Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

Это хороший вопрос.Я восстанавливаю его, чтобы рассказать немного подробнее о том, как это делается.Сеть ведет себя с различными 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 < сейчас" должно было быть правдой (я даже добавил час, чтобы быть уверенным), но все равно было ложью.

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

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

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

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

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

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

Дата-время.Сейчас возвращает Дата - время значение, представляющее текущее системное время (в любом часовом поясе, в котором работает система).Тот Самый Дата-время.Вид имущество будет Ссылка на дату и время.Местные новости

Дата и время.UtcNow возвращает Дата - время значение, представляющее текущее Универсальное координатное время (оно же UTC), которое будет одинаковым независимо от часового пояса системы.Тот Самый Дата-время.Вид имущество будет Дата и время:Utc

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top