Я хочу комбинировать Gusman's и Evan's и создавать аргументы против них, если они позволят мне. Давайте сделаем шаг за шагом.
Должно ли DateTime.UtcNow
компенсировать часовой пояс?
Независимо от того, что Kind
он (Local, Utc или не указано), DateTime
экземпляр не держать любой UTC значение смещения. Период.
Прежде всего, давайте посмотрим на документацию The "zzz"
format specifier;
Со значениями DateTime, то «ZZZ» пользовательский формат спецификатор представляет подписал смещение часового пояса локальной операционной системы от UTC, , измеренном в часах и минутах. Он не отражает значение объекта DateTime.Kind объекта . По этой причине формат «zzz» спецификатор не рекомендуется для использования с значениями DateTime.
на основе первых двух смелых предложений, как на результат, порожденный LINQPad является полностью ожидается. Вы можете получить те же результаты (ожидайте даты и времени, конечно,) в Visual Studio.
Просто запустите этот код, как "Start Without Debugging" (Ctrl + F5 )
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Но что если вы запустите его как "Начать отладку" с (F5)?
Есть два варианта в таком случае, которые зависят от вашего DateTimeInvalidLocalFormat
в Managed Debugging Assistants отмечены галочкой или нет. Эти разделы находятся в меню Debug
, а затем нажмите Exceptions
.
Если эта опция отмечена, вы получите исключение, и он говорит;
UTC
DateTime преобразовывается в текст в формате, который только правильно для местного времени. Это может произойти при вызове DateTime.ToString
с использованием спецификатора формата 'z'
, который будет содержать смещение локального часового поясана выходе. В этом случае используйте либо спецификатор формата , обозначающий время UTC, либо используйте строку 'o'
, что является рекомендуемым способом сохранения DateTime в тексте.
Если эта опция не отмечена галочкой, вы не получите никакого сообщения, и результат будет таким же, как LINQPad.
Учитывая, что второй результат универсального времени, я ожидал, что он вернется 2016-01-08T16:05:04-00:00
(часовой пояс смещение нуля).
Как я уже объяснял, zzz
спецификатор формата делает не ведут себя, как, что для любого DateTime
экземпляра.
Но это ведет себя по-разному для экземпляра DateTimeOffset
, который документирован как;
С DateTimeOffset
значений, этот спецификатор формата представляет значение DateTimeOffset-х Offset
от UTC в часах.
И DateTimeOffset.Now
и DateTimeOffset.UtcNow
совершенно не соответствует вашим ожиданиям независимо от того, вы работаете в LINQPad или Visual Studio, так как они зарегистрированы как;
Теперь
DateTimeOffset объект, дата и время текущее местное время и чье смещение локального часового пояса это смещение от координированного времени (UTC).
UtcNow
Объект, дата и время всемирное координированное времени (UTC) и которого смещениеTimeSpan.Zero
.
Console.WriteLine(DateTimeOffset.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
будет генерировать
2016-01-08T09:05:04-07:00
2016-01-08T16:05:04-00:00
Tl, д-р я думаю, что это не ошибка. LINQPad генерирует правильные результаты точно что это должно быть. В Visual Studio вы может получить исключение, если , что опция имеет галочку или нет в режиме отладки.
Если вы попробуете это в консольном приложении, оно выдает исключение, так как UtcNow не может использовать указанный формат, поскольку он не имеет зоны ... поэтому формат недействителен для UtcNow, и в LINQPad есть некоторая ошибка, которая игнорируя это. – Gusman
Если вы используете 'DateTimeOffset' вместо' DateTime', это будет правильно. –
Спасибо! Между этими двумя комментариями у меня есть объяснение и обходное решение, и я рад принять либо ответ, если вы хотите его перевести в один. – Anders