DateTime.Now против DateTime.UtcNow

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

может быть уже слишком поздно, но я хочу указать на этот блог: blog.angeloflogic.com/2013/10/…

treehouse 30.04.2015 16:36

небольшой репер rextester.com/QRDR82396

Daniel B 10.01.2018 18:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
245
2
181 960
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Ответ принят как подходящий

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

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

отличный момент - когда даты хранение в базе данных или файле, обязательно сохраните их в UTC!

Jeff Atwood 15.09.2008 15:04

Вы должны отметить, что когда вы хотите хранить даты в формате UTC в базе данных, вы должны убедиться, что база данных не добавляет собственный часовой пояс к датам, которые не указывают явные часовые пояса. Обратите внимание, что DateTime всегда будет использовать текущий часовой пояс по запросу.

Omer van Kloeten 15.09.2008 15:25

@OmervanKloeten дает очень хороший отзыв. Мне интересно, есть ли для этого элегантное «универсальное» решение для правильного хранения и получения дат каждый раз, даже если ваши IIS и SQL-сервер находятся в разных часовых поясах.

TheGeekZn 23.05.2014 15:34

Можно ли добавить к DateTime.UtcNow 1 год? Например, и срок действия учетной записи пользователя.

JoshYates1980 22.05.2015 19:24

@ JoshYates1980 Да, вы просто делаете DateTime.UtcNow.AddYears (1)

CathalMF 30.11.2015 17:21

Используйте NodaTime - это заставит вас думать о времени более полезным образом и избежать таких проблем

aateeque 14.04.2016 01:43

Я уверен, что когда вы говорите: «Я бы порекомендовал использовать DateTime.Now», это был 2008 год, и облака не существовало. Вам не кажется, что UTC.Now - это правильный вариант в наши дни, когда все развертывается в геораспределенном облаке с международной аудиторией?

Sagar Khatri 18.10.2019 13:39

wont DateTime.Now дать вам дату и время сервера, а не дату и время клиента? глядя на захват даты и времени клиента. Как мне это сделать без осложнений?

Oracular Man 17.04.2020 04:47

Я получаю ошибку NoMethodError (undefined method `UtcNow' for DateTime:Class)

Chetan Kumar 21.12.2020 18:11

Например, я живу в Турции, и мои часы показывают 21:39 ночи здесь. Итак, DateTime.Now дает мне 21:39:18. DateTime.UtcNow показывает 18:39:18, так как в Лондоне сейчас вечер.

Onat Korucu 02.01.2021 21:42

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

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

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

Мы также отображаем относительное время (2 часа назад, 1 день назад и т. д.) До тех пор, пока пост не устареет настолько, чтобы время было «одинаковым» независимо от того, где на Земле вы живете.

Я также хочу, чтобы сохранение DateTime.UtcNow также необходимо только тогда, когда выполняется расчет с двумя датами, чтобы получить правильные часы. Когда мне просто нужно отобразить RegisterAt Date, достаточно Datetime.Now.

Elisabeth 14.07.2016 23:50

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

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

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

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

Чтобы быть полностью точным (и чтобы люди не использовали Now over UtcNow по соображениям производительности), это наоборот: теперь добавляет часовой пояс в UtcNow, и на самом деле это намного медленнее.

mafu 09.02.2012 19:30

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

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

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

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

Относительно «загрузить переменную с помощью DateTime.Now или DateTime.UtcNow - присвоение идентично»: Возможно, это необходимо уточнить? Пока я сижу здесь, в часовом поясе EDT (UTC -4), я назначил две переменные DateTime.UtcNow и DateTime.Now соответственно, а затем распечатал их значения с помощью ToString (). Разница между отображаемыми значениями составила 4 часа - не «идентичны».

Jon Schneider 19.05.2015 17:40

@JonSchneider, я считаю, что вы правы. Утверждение: «присвоение идентично» не соответствует действительности. ToString (), вероятно, не лучший способ проверить это, потому что мог отображает одинаковые даты по-разному (как это делает Java). Функции сравнения - лучший тест, и они показывают, что они действительно не равны.

Ted Bigham 20.05.2015 20:55

Пояснение к моей «идентичной» инструкции: загрузите одну переменную через DateTime.Now, а другую - через DateTime.UtcNow, а затем распечатайте разницу TimeSpan. Разница будет в миллисекундах, а не в часах, если вы находитесь в нескольких часах от GMT.

Carl Camera 15.12.2016 23:11

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

Поэтому НЕ используйте DateTime.Now для измерения относительного времени.

Мне потребовалось болезненное путешествие, просто знаю, что UtcNow имеет лучшую производительность и что простое сохранение ваших дат в mysql и предположение, что это utc, и сравнение зависимых от даты дисплеев с UtcNow упрощает эти глобальные проблемы с часовым поясом

Diin 14.05.2019 19:48

На моем компьютере только 3 раз быстрее. Я создал цикл с одним миллионом итераций. Использование datetime.now заняло 200 мс. Использование datetime.utcnow заняло 60 мс.

Tono Nam 10.11.2020 18:39

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

«Простой» ответ на вопрос:

DateTime.Now возвращает значение DateTime, представляющее текущее системное время (в любом часовом поясе, в котором работает система). Свойство DateTime.Kind будет DateTimeKind.Local.

DateTime.UtcNow возвращает значение DateTime, представляющее текущее универсальное координированное время (также известное как UTC), которое будет одинаковым независимо от часового пояса системы. Свойство DateTime.Kind будет DateTimeKind.Utc.

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

Это хороший вопрос. Я восстанавливаю его, чтобы подробнее рассказать о том, как .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 НЕ совместимы.

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

    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

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

Вы также можете увидеть «обходной путь», который заключается в простом преобразовании во всемирное время везде, где Kind не совпадает.

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

DateTime.UtcNow - это универсальная шкала времени без учета летнего времени. Таким образом, UTC никогда не меняется из-за летнего времени.

Но DateTime.Now не является непрерывным или однозначным, потому что он изменяется в соответствии с DST. Это означает, что DateTime.Now одно и то же значение времени может встречаться дважды, оставляя клиентов в замешательстве.

Большая разница :) в том, что DateTime.Now не поддерживается в рабочем процессе SharePoint, вы должны использовать DateTime.UtcNow

Другие вопросы по теме