2015-04-30 4 views
0
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 />"); 

отображает.ToUniversalTime() Неверно?

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 по времени в формате UTC и www.timeanddate.com, а время UTC должно быть 8 часов. Я делаю что-то неправильно?

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

+0

@PeterDuniho: Что вы имеете в виду * Не прямо сейчас это не так? * Почему переход от момента времени к UTC изменится в зависимости от того, что такое * текущий * часовой пояс? –

+0

@AndrewWhitaker В текущем часовом поясе создается «момент времени», который преобразуется в UTC. –

+0

@AndrewWhitaker: спасибо ... Я упустил из виду, что OP использовал дату в 1972 году. Я видел месяц и день, очень близко к текущему месяцу и дню, и просматривал прошлогодний. –

ответ

3

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

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's history of daylight saving time, вы увидите следующий пункт:

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

А потом чуть позже:

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

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

Timeanddate.com's history of DST seems to agree и перечислены 30 апреля 1972 года (последнее воскресенье апреля), так как часы даты были повернуты на один час (до UTC-7).

Правила регулировки DST Microsoft для времен до 1987 года выглядят неправильно (and I'm not the only one who thinks so).

Вот что TimeZoneInfo списки как правила для PST:

enter image description here

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

По существу, ваша дата (в 1972 году) неправильно обрабатывается правилами настройки Microsoft 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 
+0

Отличный ответ. Я удивлен, что Microsoft отправила фреймворк с такой вопиющей ошибкой. Спасибо, что подтвердил и указал на Ноду. – MarkF

+0

Это не обязательно «ошибка» - это просто, что временные зоны Windows не имеют такого уровня исторической точности. Так как .NET получает данные о часовых поясах из Windows, он ограничен диапазоном данных, предоставляемых Windows. Временные зоны IANA (используемые Noda Time) имеют гораздо более богатую историю и, следовательно, лучше подходят для такого рода задач. –

+0

@MattJohnson: Правильно, я понимаю, что поведение вызвано информацией о часовом поясе Windows, но я все равно считаю это ошибкой. Независимо от основной причины, пользователь пытается конвертировать между часовыми поясами и получает неверный результат. Тот факт, что информация о часовом поясе извлекается из Windows, не должна иметь значения для конечного пользователя. –

Смежные вопросы