Изменение TimeZone на Azure Web Apps Не работает для DateTimeOffset.Now?

В соответствии с multiple публикации, Microsoft разрешила использовать параметр приложения - WEBSITE_TIME_ZONE - для управления часовым поясом веб-сервера.

Чтобы попробовать это, я установил это значение в "Восточное стандартное время", которое является моим местным часовым поясом.

На странице ASP.NET MVC Razor я добавил следующий код:

DateTime.Now: @DateTime.Now
DateTimeOffset.Now: @DateTimeOffset.Now
DateTime.UtcNow: @DateTimeOffset.UtcNow

когда я прошёл эту ночь в 5:10:07 вечера по восточному стандартному времени, он дал следующий результат:

DateTime.Now: 6/18/2015 5:10:07 PM
DateTimeOffset.Now: 6/18/2015 5:10:07 PM +00:00
DateTime.UtcNow: 6/18/2015 9:10:07 PM

Как вы можете видеть, настройка правильно разрешала DateTime.Now возвращать правильное значение в моем часовом поясе, а не UTC, как обычно делают веб-сайты Azure/веб-приложения. DateTime.UtcNow всегда возвращал правильное значение по понятным причинам.

Однако DateTimeOffset.Now возвращает локальное время, но со смещением +00:00 - почти так, как если бы часы были изменены, а не часовой пояс. Это происходит, даже если документация говорит (внимание мое):

Возвращает объект DateTimeOffset, который установлен на текущую дату и время на текущем компьютере, с смещением, установленным на локальное смещение по времени от скоординированного универсального времени (UTC).

Итак, что происходит, когда параметр WEBSITE_TIME_ZONE влияет на DateTime.Now, но не влияет на DateTimeOffset.Now? И есть ли способ обойти это?

Как пояснение, я не хочу менять часовой пояс на сервере. Мы работаем над правильным решением, основанным на часовом поясе. Но мне все еще интересно, почему так происходит.

Ответы

Ответ 1

Хорошо, для меня это работает прямо сейчас. Если он не работает, убедитесь, что вы установили правильное значение

  • Открыть regedit
  • Поиск "часовых поясов"
  • Проверьте, как ваша зона написана. Например, моя зона - "Восточная EST (+2)", а в реестре ее название "E. Europe Standard Time"

Итак, я добавил к настройкам приложения в приложении azure "WEBSITE_TIME_ZONE: E. Europe Standard Time", и он работает.

Ответ 2

Для тех, кто спотыкается на этот вопрос. Это исправлено уже давно.

Ответ 3

Я столкнулся с той же проблемой. К сожалению, для меня я унаследовал много устаревшего кода, который был написан специально для Восточного стандартного времени, поэтому обновление его для работы с UTC по существу не является вариантом.

После копания в код CLR, похоже, это связано с тем, что локальный часовой пояс проверяется на системный реестр. Не видите, как они могут правильно поддерживать это без изменения кода CLR, поскольку Azure Web Apps работает на общих виртуальных машинах.

В настоящее время я обойдусь этим с помощью следующего рефлексивного взлома при запуске сайта, чтобы обмануть .Net, чтобы думать, что это в Восточное стандартное время. Это не отличное решение и, скорее всего, сломается, если они изменят реализацию класса TimeZoneInfo, но, надеюсь, причиной их изменения будет решение этой проблемы.

// rewrite local timezone
var tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

var fInfo = typeof(TimeZoneInfo).GetField("s_cachedData", BindingFlags.Static|BindingFlags.NonPublic);
var cachedData = fInfo.GetValue(null);

fInfo = cachedData.GetType().GetField("m_localTimeZone", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
fInfo.SetValue(cachedData, tz);