2012-05-10 2 views
2

Я прочитал несколько сообщений здесь, пока моя голова не была готова взорваться с небольшими линиями на атласе, разбросанном по всему.Почему так сложно конвертировать из одного часового пояса в другой?

Вот что я хотел бы сделать:

  1. У меня есть календарь, полный назначений для отображения для бизнеса.
  2. Бизнес находится в Нью-Йорке (EDT)
  3. Моя DEV машина находится в PST
  4. Производственные серверы находятся в Калифорнии (PST) данные
  5. Календарь хранится в БД в формате UTC

Все, что я хочу сделать, это выбрать временной диапазон, указанный в EDT (например, 15 мая, с 9:00 до 17:00) и показать все встречи в календаре.

Итак, мой календарь контролирует меня: «Я хочу назначений от 15.05.12 9 утра EDT - 5/15/12 5 вечера EDT» Я говорю «отлично», я буду называть db proc и передавать значения даты в UTC, т. Е. (5/15/12 13:00 UTC - 15.05.12 21:00 UTC). Затем, когда я получу их, я верну их обратно в EDT, прежде чем передать их вам.

Тем не менее, мало ли я знаю, что .NET найдет эту простую задачу, чтобы меня опрокинуть.

Я получил TimeZoneInfo просто отлично с помощью:

TimeZoneInfo zoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") 

Но это, насколько все работало.

Вот что я попытался следующий:

DateTime rangeStartUTC = TimeZoneInfo.ConvertTimeToUtc(rangeStart, zoneInfo); 

EXCEPTION: Kind is not properly specified. 

(WTF это Kind?) Я сказал вам время, я хочу, чтобы преобразовать, я сказал вам, что в EDT, я сказал вам, что я хочу, чтобы преобразовать его в УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ. Что вы еще хотите? Я мог бы это сделать вручную. F ** сделать это уже.

Итак, я попытался установить вид, но он имеет только два значения! Local или Utc. Но мое время не является ни местным, ни Utc. Почему, черт возьми, ты спрашиваешь меня о информации о часовом поясе? Не могли бы вы сказать, что такое местный часовой пояс, задавая системные часы? Как и ожидалось, ни одна из них не работала. (да, согласно документам есть UnSpecified, но, опять же, согласно документам, это ничего не делает и да, я тоже пробовал это).

Затем я попробовал:

TimeZoneInfo.ConvertTime(rangeStart, zoneInfo, TimeZoneInfo.Utc) 

ЖЕ отговорка!

Время, чтобы прочитать еще несколько отрывков Св. Джона Скита.

Что вам известно, есть новый класс DateTimeOffset. Это решит все ваши проблемы. благословенны все красиво и милосердных .NET 4.0 щедрот ...

DateTimeOffset offStartTime = new DateTimeOffset(rangeStart, zone.GetUtcOffset(rangeStart)); 
rangeStartUTC = offStartTime.UtcDateTime; 

EXCEPTION: "Offset should be 0 for Utc dates" 

Gaaaaah! Как вы пришли к выводу, что RangeStart является Utc? Я когда-нибудь говорил вам об этом?

Куча людей цитирует TimeZoneInfo.ConvertTime (rangeStart, zone) в качестве решения, как это «Kind» достаточно, чтобы работать на них? Если их исходный часовой пояс удобно не совпадает с местным часовым поясом.

Итак, что делать бедному разработчику .NET C#?

+2

Используйте время Noda. – SLaks

+0

Вы еще [читаете это дерево] (http://msdn.microsoft.com/en-us/library/bb384268) из MSDN? он подробно рассказывает о том, как работать с часовыми поясами и 'DateTime' –

+0

@Slaks - определенно в виду для следующего проекта. Для этого потребуется слишком много изменений/цикла тестирования. – Hooligan

ответ

2

Попробуйте DateTime.SpecifyKind(rangeStart, DateTimeKind.Unspecified) до DateTimeOffset или TimeZoneInfo. Он не должен делать никакого преобразования самого времени, просто измените Kind.

Как я понимаю, Kind на DateTime должны быть Unspecified или соответствовать результату частного TimeZoneInfo.GetCorrespondingKind() метода, который возвращает Local для TimeZoneInfo.Local и Utc для TimeZoneInfo.Utc.

ОБНОВЛЕНИЕ: Извините, неправильно ответьте на оригинал, должно быть все хорошо.

+0

Андрей - Спасибо, что нашли время, чтобы предложить решение. Я попробовал SpecifyKind() - со всеми тремя возможными значениями, все из которых закончились исключением, когда я вызывал ConvertTime(). Вы предлагаете, это поможет с построением TimeZoneOffset? Я еще не пробовал. Скоро вы узнаете, как это происходит. – Hooligan

+0

Используете ли вы результат возврата 'SpecifyKind'? Поскольку он не меняет сам 'DateTime', он создает вместо него новый. –

+0

Чтобы добавить мои два цента к этому - имена значений DateTime.Kind немного вводят в заблуждение. «Местное» означает местное время, как в текущее местное время, а не по местному времени, как я думал. Имя «Unspecified» отбросило меня, его действительно следовало назвать «другим». Понимание правильных значений для них помогает исключениям TimeZoneInfo имеют больший смысл. – Rich