Ошибка високосного года, вызывающая ToUniversalTime (). AddYears (). ToLocalTime ()? - PullRequest
2 голосов
/ 02 марта 2009

Я столкнулся с високосным годом в DateTime обработке .NET, в частности ToLocalTime(). Вот некоторый код, который воспроизводит проблему (я нахожусь в тихоокеанском часовом поясе):

DateTime dtStartLocal = DateTime.Parse("2009-02-28T23:00:00.0-08:00");
DateTime dtEndLocal = dtStartLocal.AddYears(3);
DateTime dtStartUtc = dtStartLocal.ToUniversalTime();
DateTime dtEndUtc = dtStartUtc.AddYears(3);
DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();
DateTime dtStartLocal2 = dtStartUtc.ToLocalTime();
Console.WriteLine("START: 1={0}, 2={0}", dtStartLocal, dtStartLocal2);
Console.WriteLine("END  : 1={0}, 2={1}", dtEndLocal, dtEndLocal2);
Console.ReadLine();

Вывод:

СТАРТ: 1 = 2/28/2009 23:00:00 PM, 2 = 2/28/2009 11:00:00
КОНЕЦ: 1 = 2/28/2012 23:00:00 PM, 2 = 2/29/2012 23:00:00

Обратите внимание, что переменная, которую я сделал ToUniversalTime().AddYears(3).ToLocalTime(), отличается от простой AddYears(3), она впереди на один день.

Кто-нибудь сталкивался с этим? Если это ожидается, может кто-нибудь объяснить логику этого?

ПРИМЕЧАНИЕ. Да, лучший подход - полностью работать в формате UTC, а не переключаться между ними. Это не то, что влияет на меня, а особенность, с которой я столкнулся. По сути, я неправильно понял, как работает AddYears(), и теперь я понимаю, почему он делает то, что делает (см. Мой выбранный ответ ниже).

Ответы [ 3 ]

9 голосов
/ 02 марта 2009

Я думаю, что это работает правильно.

DateTime dtStartUtc = dtStartLocal.ToUniversalTime();

PST - UTC-8. Следовательно, это время конвертируется в 1 марта 2009 г. с 07:00 до 00:00.

DateTime dtEndUtc = dtStartUtc.AddYears(3);

Это добавляет три года к предыдущему времени, т.е. 1 марта 2012 г., 07: 00: 00.

DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();

Это преобразует время окончания обратно в PST, которое будет 29 февраля 2012 года, 11: 00: 00.

Я бы сказал, что это всего лишь побочный эффект конвертации между местным и временем UTC.

0 голосов
/ 03 марта 2009

Насколько я могу судить, это поведение не является неправильным. Когда вы конвертируете местное время в UTC, оно фактически переносит его на следующий день; 1 марта. Когда вы добавляете три года, он остается 1 марта. Переведите его обратно в местное время, и он вернется к предыдущему дню, который, поскольку 2012 год является високосным, является 29 февраля.

0 голосов
/ 02 марта 2009

Печать часового пояса / поправочного коэффициента. Когда вы делаете .ToUniversialTime (), он, по сути, добавляет 8 часов от вашего исходного времени («-08: 00»), что приведет к 11:00 следующего дня, начиная с 23:00 часов 28 февраля. Таким образом, когда вы добавляете 3 года, это 11:00 утра 29-го. Если бы вы сделали 2 года, это было бы 1 марта, это не имеет никакого отношения к високосному году.

...