Подтвердить что ты не робот

Как работает DateTime.ToUniversalTime()?

Как работает конвертация в UTC из стандартного формата DateTime?

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

4b9b3361

Ответ 1

Не существует неявного часового пояса, привязанного к объекту DateTime. Если вы запустите ToUniversalTime() на нем, он использует часовой пояс контекста, в котором работает код.

Например, если я создаю DateTime с эпохи 1/1/1970, он дает мне тот же объект DateTime независимо от того, где я в мире.

Если я запустил ToUniversalTime() на нем, когда я запускаю код в Greenwich, то я получаю то же самое время. Если я сделаю это, пока я живу в Ванкувере, то получаю смещенный DateTime объект -8 часов.

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

Изменить: примечание из ответа Джоэля - объекты DateTime по умолчанию набираются как DateTimeKind.Local. Если вы проанализируете дату и установите ее как DateTimeKind.Utc, тогда ToUniversalTime() не выполняет преобразование.

И здесь статья о "Коды наилучшей практики с датами" и статья о Преобразование DateTimes с .Net.

Ответ 2

Во-первых, он проверяет, известен ли Kind DateTime как UTC. Если это так, оно возвращает то же значение.

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

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

Если значение экземпляра даты и времени неоднозначное время, этот метод предполагает что это стандартное время. (An неоднозначное время - это тот, который может отображать либо к стандартному времени, либо к экономит время в пути зона) Если экземпляр даты и времени значение - недопустимое время, этот метод просто вычитает местное время из локальный часовой пояс UTC смещен возврат UTC. (Недействительное время - одно что не существует из-за применение летнего времени правила регулировки.)

Возвращаемое значение будет иметь значение Kind DateTimeKind.Utc, поэтому, если вы вызываете ToUniveralTime, то это не будет применяться снова. (Это значительное улучшение по сравнению с .NET 1.1!)

Если вы хотите нелокальный часовой пояс, вы должны использовать TimeZoneInfo, который был представлен в .NET 3.5 (есть хакерские решения для более ранних версий, но они не очень приятные). Чтобы представить момент во времени, вам следует использовать DateTimeOffset, который был представлен в .NET 2.0SP1,.NET3.0SP1 и .NET 3.5, Тем не менее, у этого до сих пор нет реального часового пояса, связанного с ним, - только смещение от UTC. Это означает, что вы не знаете, какое местное время будет на один час позже, например - правила DST могут варьироваться между часовыми поясами, которые использовали одно и то же смещение для данного конкретного момента. TimeZoneInfo предназначен для учета исторических и будущих правил, в отличие от TimeZone, который несколько упрощен.

В основном поддержка .NET 3.5 намного лучше, чем была, но все же оставляет желать лучшего для правильной арифметики календаря. Любое причудливое портирование Joda Time на .NET?;)

Ответ 3

Что @womp сказал, добавив, что он проверяет свойство DateTime Kind, чтобы увидеть, может ли это быть дата UTC.

Ответ 4

DateTime.ToUniversalTime удаляет смещение часового пояса локального часового пояса, чтобы нормализовать DateTime в UTC. Если вы затем используете DateTime.ToLocalTime для нормализованного значения в другом часовом поясе, смещение временной зоны этого часового пояса будет добавлено к нормализованному значению для правильного представления в этом часовом поясе.