значение datetime.Теперь против даты и времени.UtcNow


Мне было интересно, каковы именно принципы работы этих двух свойств. Я знаю, что второй является универсальным и в основном не имеет отношения к часовым поясам, но может ли кто-нибудь подробно объяснить, как они работают и какой из них следует использовать в каком сценарии?

12   176  

12 ответов:

дата и время.UtcNow сообщает вам дату и время, как это было бы в координированном универсальном времени, которое также называется Гринвичским средним часовым поясом - в основном, как это было бы, если бы Вы были в Лондоне Англии, но не летом. дата и время.Сейчас дает дату и время, как это могло бы показаться кому-то в вашей текущей локали.

Я бы посоветовал использовать DateTime.Now всякий раз, когда вы показываете дату человеку - таким образом, им комфортно ценность, которую они видят-это то, что они могут легко сравнить с тем, что они видят на своих часах или часах. Используйте DateTime.UtcNow Если вы хотите сохранить даты или использовать их для последующих вычислений таким образом (в модели клиент-сервер), ваши вычисления не будут путаться клиентами в разных часовых поясах от вашего сервера или друг от друга.

это действительно довольно просто, поэтому я думаю, что это зависит от того, что ваша аудитория и где они живут.

Если вы не используете Utc, вы должны знайте часовой пояс человека, которому вы показываете даты и время, иначе вы скажете им, что что-то произошло в 3 часа дня в системном или серверном времени, когда это действительно произошло в 5 часов вечера, где они живут.

мы используем:DateTime.UtcNow потому что у нас есть глобальная веб-аудитория, и потому что я бы предпочел не пилить каждого пользователя заполните форму с указанием часового пояса, в котором они живут.

мы также показываем относительное время (2 часа назад, 1 день назад и т. д.), Пока сообщение не станет достаточно возрастным, чтобы время было "одинаковым" независимо от того, где вы живете.

одна из основных концепций для понимания в .NET является то, что теперь и теперь по всей Земле не важно, в каком часовом поясе вы находитесь. Поэтому, если вы загружаете переменную с DateTime.Сейчас или Дата-Время.UtcNow -- назначение идентично.* Ваш объект DateTime знает, в каком часовом поясе вы находитесь, и учитывает это независимо от назначения.

полезность DateTime.UtcNow пригодится при расчете дат через границы летнего времени. Что есть, в местах, которые участвуют в летнее время, иногда есть 25 часов с полудня до полудня следующего дня, а иногда есть 23 часа между полуднем и полуднем следующего дня. Если вы хотите правильно определить количество часов от времени A и времени B, вам нужно сначала перевести их в эквиваленты UTC перед вычислением временного интервала.

Это покрывается сообщение в блоге я написал, которая поясняет значение TimeSpan, и включает в себя ссылку на еще более обширная статья MS по этой теме.

*уточнение: либо назначение будет хранить текущее время. Если вы должны были загрузить две переменные один через DateTime.Теперь () и другой через DateTime.UtcNow () разница во времени между ними будет составлять миллисекунды, а не часы, предполагая, что вы находитесь в часовом поясе в часах от GMT. Как отмечено ниже, при печати их строковых значений будут отображаться разные строки.

также обратите внимание на разницу в производительности; DateTime.UtcNow примерно в 30 раз быстрее, чем DateTime.Теперь, потому что внутренне даты.Теперь делает много регулировок часового пояса (вы можете легко проверить это с рефлектором).

Так что не используйте DateTime.Теперь для относительных измерений времени.

Это хороший вопрос. Я возрождаю его, чтобы дать немного больше подробностей о том, как .Net ведет себя с различными значениями "рода". Как указывает @Jan Zich, на самом деле это критически важное свойство и устанавливается по-разному в зависимости от того, используете ли вы сейчас или UtcNow.

внутренне дата хранится в виде "тиков", которые (вопреки ответу @Carl Camera) отличаются в зависимости от того, используете ли вы сейчас или UtcNow.

дата и время.UtcNow ведет себя как и другие языки. Он устанавливает Клещей в МСК значение, основанное. Он также устанавливает " вид " в "Utc".

дата и время.Теперь изменяет значение тиков на что было бы, если бы это было ваше время в часовом поясе GMT. Он также устанавливает " вид " на "локальный".

Если вы на 6 часов отстаете (GMT-6), вы получите время GMT от 6 часов назад. .Net фактически игнорирует " вид "и относится к этому времени, как если бы это было 6 часов назад, хотя это должно быть"сейчас". Это еще больше нарушается, если вы создаете экземпляр DateTime затем измените свой часовой пояс и попробуйте его использовать.

экземпляры DateTime с разными значениями "вида" несовместимы.

давайте посмотрим на некоторые код...

    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

Как вы можете видеть здесь, сравнения и математические функции не преобразуются автоматически в совместимые времена. Промежуток времени должен был быть почти один час, но вместо этого был почти 6. "utc

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

мой прямой ответ на вопрос согласуется с рекомендацией принятого ответа о том, когда использовать каждый из них. Вы должны всегда попробовать для работы с объектами DateTime, имеющими Kind=Utc, за исключением операций ввода-вывода (отображение и синтаксический анализ). Это означает, что вы почти всегда должны использовать DateTime.UtcNow, за исключением случаев, когда вы создание объекта только для его отображения, и сразу же отбросить его.

DateTime понятия не имеет, что такое часовые пояса. Это всегда предполагает, что вы находитесь в вашем местном времени. UtcNow означает только "вычесть мой часовой пояс из времени".

Если вы хотите использовать даты с учетом часового пояса, используйте DateTimeOffset, который представляет собой дату / время с часовым поясом. Мне пришлось учиться этому на собственном горьком опыте.

просто небольшое дополнение к пунктам, сделанным выше: структура DateTime также содержит малоизвестное поле под названием вид (по крайней мере, я не знаю об этом давно). Это в основном просто флаг, указывающий, является ли время локальным или UTC; он не указывает реальное смещение от UTC для местного времени. Помимо того, что он указывает, с какими намерениями была построена штукатурка, он также влияет на то, как методы ToUniversalTime() и ToLocalTime() работа.

"простой" ответ на вопрос:

дата и время.Сейчас возвращает a DateTime значение, представляющее текущее системное время (в любом часовом поясе, в котором работает система). Элемент дата и время.Добрый собственность будет DateTimeKind.Местные

дата и время.UtcNow возвращает a DateTime значение, представляющее текущее универсальное координированное время (aka UTC), которое будет одинаковым независимо часового пояса системы. Элемент дата и время.Добрый собственность будет DateTimeKind.Мирового

дата и время.UtcNow-это непрерывная однозначная временная шкала, тогда как DateTime.Теперь не является непрерывным или однозначным. Основная причина-летнее время, которое не относится к UTC. Таким образом, UTC никогда не прыгает вперед или назад на час, тогда как местное время(DateTime.Сейчас делать. И когда он прыгает назад, одно и то же значение времени происходит дважды.

дата и время.UtcNow-это универсальная шкала времени, исключающая летнее время. Так что Мирового не меняется из-за перехода на летнее время.

Но, Дата И Время.Теперь не является непрерывным или однозначным, потому что он изменяется в соответствии с DST. Что означает дату и время.Теперь одно и то же значение времени может произойти дважды, оставляя клиентов в запутанном состоянии.

Если вам нужно местное время для машины, на которой работает ваше приложение (например, CEST для Европы), используйте сейчас. Если вы хотите универсальное время - UtcNow. Это просто вопрос ваших предпочтений-вероятно, создание локального веб - сайта / автономного приложения, которое вы хотите использовать, когда пользователь имеет - так влияет на его/ее настройку часового пояса-DateTime.Сейчас.

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