Оператор разницы DateTime считает летнее время? - PullRequest
9 голосов
/ 01 мая 2009

Насколько мне известно, оператор разницы типа 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

А как насчет летнего времени?

Ответы [ 5 ]

3 голосов
/ 11 января 2010

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

Короткая версия:

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

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

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

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

Из Raymond Chen запись в блоге, Почему летнее время не интуитивно понятно :

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

...

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

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

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

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

2 голосов
/ 01 мая 2009

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

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

Это немного больно, не говоря уже о странах, которые этого не делают, или некоторых странах.

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

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

2 голосов
/ 01 мая 2009

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

Вы можете легко обойти это, хотя: Просто сделайте:

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

, а при конвертации в UTC учитывается переход на летнее время

1 голос
/ 05 ноября 2009

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

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

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

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

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

0 голосов
/ 01 мая 2009

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

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

...