.ToUniversalTime() неверно?

85
5

    DateTime dt = new DateTime(1972, 4, 24, 0, 0, 0);
Response.Write("dt: " + dt.ToString("M/d/yyyy h:mm:ss tt") + "<br />");
Response.Write("dt.Kind: " + dt.Kind.ToString() + "<br />");
Response.Write("dt.ToUniversalTime(): " + dt.ToUniversalTime().ToString("M/d/yyyy h:mm:ss tt") + "<br />");

дисплеи

dt: 4/24/1972 12:00:00 AM
dt.Kind: Unspecified
dt.ToUniversalTime(): 4/24/1972 7:00:00 AM

что неверно. 24 апреля 1972 года в 12 часов вечера Тихоокеанский регион фактически находится 24 апреля 1972 года в 8 часов UTC.

Я подтвердил правильное преобразование UTC с внутренней рассылкой даты в формате iOS и www.timeanddate.com, а время UTC должно быть 8 часов. Я делаю что-то неправильно?

Сервер работает в часовом поясе "Тихоокеанского времени", поэтому ToUniversalTime должен преобразовывать из тихоокеанского часового пояса в UTC, поскольку Unspecified обрабатывается как Local.

спросил(а) 2015-04-30T04:30:00+03:00 5 лет, 2 месяца назад
1
Решение
77

Если вы находитесь на машине, не входящей в стандартное тихоокеанское время, вы можете увидеть это поведение, используя следующий код:

DateTime dt = new DateTime(1972, 4, 24, 0, 0, 0);    
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

Console.WriteLine (TimeZoneInfo.ConvertTimeToUtc(dt, tz));
// 4/24/1972 7:00:00 AM

Если вы посмотрите историю летнего времени navy.mil, вы заметите следующий параграф:

Закон об унифицированном времени 1966 года предусматривал стандартизацию в датах начала и окончания летнего времени в США, но допускал локальные исключения из его соблюдения. Этот акт предусматривал, что дневное время начинается в последнее воскресенье апреля и заканчивается в последнее воскресенье октября, когда переход произойдет в 2 часа по местному времени.

А потом немного позже:

В 1986 году был принят закон, который сдвинул дату начала дневного света до первого воскресенья апреля, начиная с 1987 года

Таким образом, переход DST не был первым воскресеньем в апреле до 1987 года, но по какой-то причине.NET действует так, как будто это было.

История DST Timeanddate.com, похоже, согласна и перечисляет 30 апреля 1972 года (последнее воскресенье апреля), так как часы даты были отправлены на один час (на UTC-7).

Правила регулировки Microsoft DST для времен до 1987 года кажутся неправильными (и я не единственный, кто так думает).

Здесь то, что TimeZoneInfo перечисляет как правила для PST:

enter image description here

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

По существу, ваша дата (в 1972 году) неправильно обрабатывается правилами настройки времени TimeZoneInfo.

Если вы ищете библиотеку, которая намного лучше справляется с этими типами правил часового пояса, проверьте NodaTime, которая правильно обрабатывает этот конкретный случай:

var pacific = DateTimeZoneProviders.Tzdb["America/Los_Angeles"];

LocalDateTime localDateTime = new LocalDateTime(1972, 4, 24, 0, 0);
ZonedDateTime zonedDateTime = pacific.AtStrictly(localDateTime);

DateTime utcDateTime = zonedDateTime.ToDateTimeUtc();

Console.WriteLine(utcDateTime);
// 4/24/1972 8:00:00 AM

ответил(а) 2015-04-30T05:16:00+03:00 5 лет, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема