Ошибка високосного года, вызывающая функцию ToUniversalTime().AddYears().ToLocalTime()?

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

  •  03-07-2019
  •  | 
  •  

Вопрос

Я столкнулся с тем, что может быть високосным годом в .NET's DateTime обращение, в частности 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= 28.02.2009 11:00:00 вечера, 2= 28.02.2009 11:00:00 вечера
КОНЕЦ :1= 28.02.2012, 11:00:00, 2= 29.02.2012, 11:00:00

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

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

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

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

Решение

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

DateTime dtStartUtc = dtStartLocal.ToUniversalTime();

PST - это UTC-8.Таким образом, это преобразует время в март 1, 2009, 07:00:00.

DateTime dtEndUtc = dtStartUtc.AddYears(3);

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

DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();

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

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

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

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

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

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