Мне было интересно, каковы принципы работы этих двух свойств. Я знаю, что второй универсальный и в основном не имеет дело с часовыми поясами, но может ли кто-нибудь подробно объяснить, как они работают и какой из них следует использовать в каком сценарии?
.net
language-features
date
Славо
источник
источник
Ответы:
DateTime.UtcNow сообщает вам дату и время так, как это было бы в всемирном координированном времени, которое также называется часовым поясом среднего времени по Гринвичу - в основном, как если бы вы были в Лондоне, Англия, но не летом. DateTime.Now дает дату и время, которые будут отображаться для кого-либо в вашей текущей локали.
Я бы порекомендовал использовать
DateTime.Now
каждый раз, когда вы отображаете дату человеку - так, чтобы он чувствовал себя комфортно с ценностью, которую он видит, - это то, что они могут легко сравнить с тем, что они видят на своих часах или часах. Используйте,DateTime.UtcNow
когда вы хотите сохранить даты или использовать их для более поздних вычислений таким образом (в модели клиент-сервер) ваши вычисления не будут смущены клиентами в разных часовых поясах от вашего сервера или друг от друга.источник
Это действительно довольно просто, так что я думаю, что это зависит от вашей аудитории и места, где они живут.
Если вы не используете Utc, вы должны знать часовой пояс человека, которому вы показываете даты и время - в противном случае вы скажете им, что что-то произошло в 15:00 по системному или серверному времени, когда это действительно произошло в 17:00, где они случаются, чтобы жить.
Мы используем это,
DateTime.UtcNow
потому что у нас есть глобальная веб-аудитория, и потому что я предпочел бы не раздражать каждого пользователя, чтобы заполнить форму, указывающую, в каком часовом поясе они живут.Мы также отображаем относительное время (2 часа назад, 1 день назад и т. Д.) До тех пор, пока сообщение не станет достаточно старым, чтобы время было «одинаковым» независимо от того, где на Земле вы живете.
источник
Также обратите внимание на разницу в производительности;
DateTime.UtcNow
это где-то примерно в 30 раз быстрееDateTime.Now
, потому что внутреннеDateTime.Now
выполняется много настроек часового пояса (вы можете легко проверить это с помощью Reflector).Поэтому НЕ используйте
DateTime.Now
для измерения относительного времени.источник
Одна из основных для понимания концепция в .NET является то , что в настоящее время не является в настоящее время по всей земле независимо от того , в каком часовом поясе вы находитесь в так что если вы загрузите переменную с.
DateTime.Now
ИлиDateTime.UtcNow
-. Назначение идентично * ВашDateTime
объект знает , что часовой пояс , вы находитесь в и принимает это во внимание независимо от назначения.Полезность
DateTime.UtcNow
полезна при расчете дат за пределами летнего времени. То есть в местах, которые участвуют в переходе на летнее время, иногда с полудня до полудня следующего дня бывает 25 часов, а иногда между полуднем и полднем следующего дня 23 часа. Если вы хотите правильно определить количество часов от времени A и времени B, вам необходимо сначала перевести каждый из них в их UTC-эквиваленты, прежде чем вычислятьTimeSpan
.Это покрыто постом в блоге, который я написал, который объясняет далее
TimeSpan
, и включает ссылку на еще более обширную статью MS на эту тему.* Уточнение: любое назначение будет хранить текущее время. Если вы должны были загрузить две переменных один через ,
DateTime.Now()
а другие с помощьюDateTime.UtcNow()
кTimeSpan
разнице между ними будут миллисекунды, а не часы , предполагающие вы находитесь в часовом поясе часов езды от GMT. Как отмечено ниже, распечатка ихString
значений будет отображать разные строки.источник
Это хороший вопрос. Я возрождаю его, чтобы немного подробнее рассказать о том, как .Net ведет себя с разными
Kind
значениями. Как указывает @Jan Zich, это на самом деле критически важное свойство, и оно устанавливается по-разному в зависимости от того, используете ли выNow
илиUtcNow
.Внутри сохраняется дата,
Ticks
которая (в отличие от ответа @Carl Camera) отличается в зависимости от того, используете ли выNow
илиUtcNow
.DateTime.UtcNow
ведет себя как другие языки. Он устанавливаетTicks
значение на основе GMT. Это также устанавливаетKind
кUtc
.DateTime.Now
изменяетTicks
значение на то, что было бы, если бы это было ваше время суток в часовом поясе GMT . Это также устанавливаетKind
кLocal
.Если вы отстаете на 6 часов (GMT-6), вы получите время по Гринвичу 6 часов назад. .Net фактически игнорирует
Kind
и обрабатывает это время так, как будто это было 6 часов назад, хотя это должно быть "сейчас". Это ломает еще больше, если вы создаетеDateTime
экземпляр, затем меняете часовой пояс и пытаетесь его использовать.Экземпляры DateTime с разными значениями «Kind» НЕ совместимы.
Давайте посмотрим на некоторый код ...
Как вы можете видеть здесь, сравнения и математические функции не конвертируются автоматически в совместимое время. Значение
Timespan
должно было составлять почти один час, но вместо этого было почти 6. «utc <now» должно было быть верным (я даже добавил час, чтобы быть уверенным), но все равно было ложным.Вы также можете увидеть «обходной путь», который заключается в простом преобразовании в универсальное время в любом месте,
Kind
которое не совпадает.Мой прямой ответ на вопрос согласуется с рекомендацией принятого ответа о том, когда использовать каждый из них. Вы должны всегда пытаться работать с
DateTime
объектами, которые имеютKind=Utc
, кроме как во время ввода-вывода (отображение и анализ). Это означает, что вы должны почти всегда использоватьDateTime.UtcNow
, за исключением случаев, когда вы создаете объект, просто чтобы отобразить его и сразу же отказаться от него.источник
DateTime не знает, что такое часовые пояса. Это всегда предполагает, что вы в вашем местном времени. UtcNow означает только «Вычесть мой часовой пояс из времени».
Если вы хотите использовать даты с учетом часового пояса, используйте DateTimeOffset , который представляет дату / время с часовым поясом. Мне пришлось научиться этому нелегкому пути.
источник
«Простой» ответ на вопрос:
DateTime.Now возвращает значение DateTime, представляющее текущее системное время (в любом часовом поясе, в котором работает система). Свойство DateTime.Kind будет DateTimeKind.Local
DateTime.UtcNow возвращает значение DateTime, представляющее текущее универсальное координированное время (или UTC), которое будет одинаковым независимо от часового пояса системы. Свойство DateTime.Kind будет DateTimeKind.Utc
источник
Просто небольшое дополнение к пунктам, сделанным выше: структура DateTime также содержит малоизвестное поле, называемое Kind (по крайней мере, я давно об этом не знал). Это в основном просто флаг, указывающий, является ли время местным или UTC; он не указывает реальное смещение от UTC для местного времени. Помимо того факта, что он указывает, с какими намерениями была создана структура, он также влияет на то, как работают методы ToUniversalTime () и ToLocalTime () .
источник
Немного опоздал на вечеринку, но я нашел эти две ссылки (4guysfromrolla) очень полезными:
Использование всемирного координированного времени (UTC) для хранения значений даты и времени
Рекомендации по хранению и отображению дат и времени в разных часовых поясах
источник
DateTime.UtcNow - это непрерывный однозначный временной масштаб, тогда как DateTime.Now не является непрерывным или однозначным. Основной причиной является летнее время, которое не относится к UTC. Таким образом, UTC никогда не переходит вперед или назад на час, тогда как местное время (DateTime.Now) делает. И когда он прыгает назад, то же самое время встречается дважды.
источник
DateTime.UtcNow - это универсальная шкала времени, в которой отсутствует летнее время. Таким образом, UTC никогда не меняется из-за летнего времени.
Но DateTime.Now не является непрерывным или однозначным, поскольку изменяется в соответствии с DST. Что означает DateTime.Now, одно и то же время может происходить дважды, оставляя клиентов в замешательстве.
источник
Когда вам нужно местное время для компьютера, на котором работает ваше приложение (например, CEST для Европы), используйте Сейчас. Если вы хотите универсальное время - UtcNow. Это просто вопрос ваших предпочтений - возможно, создание локального веб-сайта / отдельного приложения, которое вы хотели бы использовать в то время, которое пользователь выбрал - так зависит от его / ее настройки часового пояса - DateTime.Now.
Помните, для веб-сайта это настройка часового пояса сервера. Поэтому, если вы отображаете время для пользователя, либо получите его предпочтительный часовой пояс и сместите время (просто сохраните время Utc в базе данных и измените его), либо укажите его UTC. Если вы забудете это сделать, пользователь увидит что-то вроде: опубликовал 3 минуса назад, а затем время в будущем рядом с ним :)
источник
Большая разница :) в том, что DateTime.Now не поддерживается в рабочем процессе SharePoint, вы должны использовать DateTime.UtcNow
источник