Оператор разницы в дате и времени учитывает переход на летнее время?

StackOverflow https://stackoverflow.com/questions/810600

Вопрос

Насколько я знаю, разностный оператор DateTime тип учитывает високосные годы:итак

new DateTime(2008, 3, 1) - new DateTime(2008, 2, 1) // should return 29 days
new DateTime(2009, 3, 1) - new DateTime(2009, 2, 1) // should return 28 days

Но как насчет перехода на летнее время?

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

Решение

Я не думаю, что это сработает. Документация просто говорит, что дата-время хранится как количество тиков с 12: 00: 00 полуночи 1 января 0001 года, но в нем не указано, в каком часовом поясе на самом деле полночь - я должен был бы предположить, что если бы оно всегда хранилось внутри UTC, они бы так и сказали.

Однако вы можете легко обойти это:Просто делай:

var difference = Dt1.ToUniversalTime() - Dt2. ToUniversalTime()

а при переводе в UTC будет учитываться переход на летнее время

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

.NET неправильно обрабатывает переход на летнее время, даже если он дает ответы, которые вы хотите.Ты хотеть неправильные ответы.

Сокращенная версия:

  • Откуда .NET может знать, что в 1977 году переход на летнее время действовал весь год из-за энергетического кризиса?

  • Откуда .NET может знать, какими будут правила перехода на летнее время в Израиле, когда правила ежегодно определяются кнессетом?

  • Откуда .NET знать, что во время Второй мировой войны США переходили на летнее время круглый год, а с 1945 по 1966 год правила летнего времени менялись от региона к региону, и правила до сих пор меняются от региона к региону.

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

От Рэймонд Чензапись в блоге, Почему переход на летнее время неинтуитивен:

Почему функции преобразования часовых поясов (win32) не используют часовой пояс, соответствующий времени года?

...

Win32 не пытается угадать, какие правила часового пояса действовали в то другое время.Итак, Win32 говорит: "Четверг, 17 октября 2002 г. 8:45:38 утра по тихоокеанскому времени".

Примечание: Тихий Океан Стандартный Время.Еще хотя 17 октября во время тихого Дневной свет Time, Win32 отображает время как стандартное, потому что это именно то время, которым оно является сейчас.

.NET говорит: "Что ж, если бы правила, действующие сейчас, действовали также 17 октября 2003 года, тогда это было бы светлое время суток" итак, он отображает "Четверг, 17 октября 2003 года, 9:45 утра PDT" - дневное время.

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

Переход на летнее время более специфичен, чем общие 12 часовых поясов и то, какие страны их использовали.

Разные страны или группы стран используют разные даты наступления летнего времени.

на самом деле немного неприятно не упоминать страны, которые этого не делают, или части стран.

Например, в Квинсленде, в AU нет летнего времени, в отличие от остальной части страны.

Я не удивлюсь, если это не так, в том случае, если это произойдет, он не сможет сделать это, по крайней мере, без cultureinfo 9).

Этого не будет и на самом деле НЕ МОЖЕТ БЫТЬ, основываясь на том факте, что это ни вынуждает вас использовать UTC для построения DateTime, ни позволяет вам указать, действовало ли летнее время при создании DateTime со значением местного времени.Кроме того, это позволяет режиму (LT или UTC) быть "неуказанным", что является просто идиотским.

Позволяя создавать значения DateTime из значений местного времени, можно создать значение DateTime (указанное как местное время), которое является неоднозначным (например, в любое время между 1 и 2 часами ночи 2 ноября в США, когда местное время повторяется) и не может быть детерминированно преобразовано обратно в UTC, ЕСЛИ только конструктор не предоставил параметр для указания того, влияет ли летнее время на данное местное время.

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

Я думаю, именно поэтому они создали класс DateTimeOffset, который...если вы были сбиты с толку, почему существует такой, казалось бы, избыточный класс...вот почему.

В результате вы никогда не должны выполнять какие-либо вычисления с любым экземпляром DateTime, для которого не установлено значение DateTimeMode.Utc.Используйте только UTC.На самом деле вы не можете конвертировать ни в LT, ни из него, потому что он поврежден двумя разными ошибками, в обоих направлениях.1.Переход с LT на UTC прерывается, потому что, как уже упоминалось, он не позволяет вам указать, действовало ли летнее время в течение этого одного неоднозначного часа в LT.О, это также позволяет вам указать местный час, что в принципе невозможно, например, час, который мы пропускаем, когда часы переводятся вперед.2.При преобразовании значения UTC в прошлом в местное время Windows исправляет это, компенсируя летнее время в зависимости от того, действует ли оно СЕЙЧАС, а не от заданного времени, что является серьезной ошибкой.Конечно, вы, возможно, заметили эту проблему, когда время изменения, которое вы записали, сохранили или использовали в имени файла, однажды отображается на ЧАС ПОЗЖЕ в проводнике Windows.Нет, вы не сумасшедший, просто в Windows есть серьезная ошибка, которую они так и не нашли времени исправить где-то между выпуском DOS и последней версии .NET Framework (~ 2 десятилетия)!Конечно, эта ошибка влияет на системы CVS и все, что отслеживает время внесения изменений.Файловая система FAT хранит время как местное, что означает, что она просто полностью испорчена.

Протестируйте это и посмотрите!

Написать тест, который вы сделали для случая летнего времени, так же просто, как и для случая високосного года.

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