Есть ли способ определить часовой пояс для приложения в ASP.NET? - PullRequest
4 голосов
/ 19 ноября 2008

Есть ли способ определить часовой пояс для приложения в ASP.NET таким образом, чтобы все времена, считанные с текущего серверного времени или сравниваемые с ним, были неявно преобразованы, или мне нужно указывать в выражениях преобразования все и каждый DateTime.Now? звоните

Ответы [ 3 ]

3 голосов
/ 19 ноября 2008

Я не уверен насчет последних изменений в ASP, но эта статья за 2006 год дает интересный ответ:

Проблема в том, что информация о часовом поясе не доступна напрямую через веб-браузер. Вы можете использовать эвристику для определения правильного часового пояса или вам придется сохранять настройки часового пояса для пользователя на основе их выбора.

Дальнейшее может не понадобиться для .Net 3.5 и его TimeZoneInfo..ConvertTime метода, но все же для полноты:

Если у вас есть настройки часового пояса, вам нужно перевести время. Вы всегда должны хранить значения даты / времени в БД в формате UTC . Это устраняет многие проблемы конверсии. Если вы храните информацию в UTC, то вам нужно только переводить из UTC в местный часовой пояс пользователя, когда вы отображаете данные для него, и вам нужно конвертировать из их часового пояса в UTC, когда вы получаете от них значения даты / времени.

Что делает это более трудным, так это тот факт, что класс TimeZone не так уж и полезен. К счастью, в версии 2.0 DateTime был обновлен для поддержки индикатора времени в UTC или нет. Вы можете преобразовать DateTime в UTC, используя метод DateTime.ToUniversalTime. К сожалению, однако, вы не можете преобразовать его обратно .

Метод ToLocalTime использует локальный часовой пояс, который при запуске на сервере использует часовой пояс сервера, а не тот, который вы хотели. Еще хуже то, что вы не можете просто создать объект TimeZone и использовать его, так как такой поддержки не существует.

Майкл Брамм создал замечательный маленький класс для возможности легко создавать и использовать часовые пояса. Я лично использую сильно измененную версию этого кода в своих собственных приложениях, и она прекрасно работает. Ниже приведены инструкции по преобразованию значения UTC из БД в часовой пояс локального пользователя.

1) Получить сохраненное значение часового пояса для пользователя
2) Создайте класс SimpleTimeZone, чтобы обернуть его (используя некоторую схему сопоставления, которая сопоставляет значение БД с базовой версией реестра Windows)
3) Используйте метод SimpleTimeZone.ToLocalTime для преобразования значения DateTime в местное время.

По соображениям производительности вам, вероятно, следует получить и инициализировать экземпляр SimpleTimeZone и кэшировать его в свойстве Items для длины запроса, чтобы вам не приходилось его создавать.

Для преобразования из местного часового пояса пользователя в UTC выполните обратное:

1) Получить сохраненное значение часового пояса от пользователя
2) Создайте класс SimpleTimeZone, чтобы обернуть его
3) Используйте метод SimpleTimeZone.ToUniversalTime для преобразования DateTime в UTC.

1 голос
/ 10 июля 2014

Позвольте мне ответить на этот вопрос напрямую .

Есть ли способ определить часовой пояс для приложения в ASP.NET таким образом, чтобы все времена, считанные с текущего сервера по сравнению с текущим временем сервера, были неявно преобразованы ...

Нет, это невозможно. В .NET нет механизма изменения локального часового пояса для каждого потока или приложения. Это может быть изменено только для всей системы настройками часового пояса машины, на которой выполняется код. См. Также этот ответ .

... или мне нужно указывать в выражениях преобразования каждый вызов DateTime.Now?

Вы не должны использовать DateTime.Now в веб-приложении. Поскольку настройки часового пояса вашего сервера могут быть легко изменены, вы должны разработать приложение так, чтобы оно игнорировалось. Это означает использование DateTime.UtcNow при чтении текущего системного времени. Кроме того, вы можете использовать DateTimeOffset с его свойствами DateTimeOffset.Now или DateTimeOffset.UtcNow.

См. Также: Дело против DateTime.Now

Когда вам нужно работать с местным временем определенного пользователя, тогда да - вы должны вводить преобразования для каждого использования. Для этого вы можете использовать класс TimeZoneInfo.

Вы также можете рассмотреть возможность использования Noda Time , который предлагает реализацию базы данных часовых поясов IANA , и в целом является гораздо лучшим API.

1 голос
/ 19 ноября 2008

Внутреннее использование DateTime.UtcNow . Для .NET 3.5 проверьте TimeZoneInfo.ConvertTime .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...