2013-05-20 5 views
5

я против вопроса, хранящего DateTimes как UTC и спутать, почему это не дает тот же результат при смене часовых поясов:Преобразование местного времени UTC

var dt = DateTime.Parse("1/1/2013"); 
MessageBox.Show(TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.Local).ToString()); 

Я вручную коммутационным мой местный часовой пояс на между восточным и центральным.

Центральная доходность 1/1/2013 6:00:00 AM и восточная доходность 1/1/2013 5:00:00 AM. Что мне здесь не хватает? Они должны быть одинаковыми независимо от часового пояса, правильно?

Большое спасибо!

+4

Таким образом, вы принимаете то же стартовое время, связывая его с часовым поясом, конвертерной его UTC, и получать разные времена UTC? Похоже, он работает. – cadrell0

+0

Я думаю, вам нужно прочитать это сообщение в блоге Jon Skeet, чтобы полностью понять проблемы с UTC/local datetimes: http://noda-time.blogspot.co.uk/2011/08/what-wrong-with-datetime-anyway .html –

+0

Я не понимаю, почему вы хотите конвертировать в UTC. Как насчет просто начала в UTC? Существует перегрузка 'DateTime.Parse', которая позволяет вам указать« Kind ». – CodesInChaos

ответ

8

Я думаю, что вам не хватает в том, что DateTime возвращенный DateTime.Parse() заявление не приходит с часовым поясом. Это всего лишь дата и время, которое может быть в любом часовом поясе. Когда вы вызываете TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.Local), вы сообщаете ему, в каком часовом поясе он начинается. Поэтому, если вы начнете в Центральной, вы получите один ответ, тогда как если вы начнете в восточном направлении, вы получите ответ, который на час раньше, UTC. В самом деле, это то, что показывает ваш код.

+0

Итак, если я запускаю DateTime.Now.ToUniversalTime() в Central, то это же, как если бы я работал на Востоке. Как создать объект datetime, который при преобразовании в универсальный, тот же, независимо от часового пояса ??? –

+0

@ user1174729 - когда вы говорите «сейчас», вы говорите об одном мгновении во времени. Если бы вы сказали «сейчас» в полночь в вашем собственном часовом поясе, то не будет полночь другой. Если вы хотите построить дату и время, то же самое, независимо от часового пояса, вам нужно будет создать это в UTC. Существует конструктор, который вы можете передать 'DateTimeKind.Utc'. –

+0

Да, что сказал Мэтт. Хитрость заключается в том, чтобы всегда работать с DateTimes, которые находятся в UTC, и затем преобразовывать их в часовой пояс пользователя при их отображении. –

3

Существует .ToUtc() метод DateTime класса

+0

Тот же результат для: MessageBox.Show (dt.ToUniversalTime(). ToString()); –

+0

Это правильно. Кстати, в то же время для КНТ и EST действительно будет отличаться на час в UTC –

1

Это полночь

var dt = DateTime.Parse("1/1/2013"); 

Полночь в восточной и центральной не то же самое абсолютное время.
В этом и состоит цель часовых поясов.

+0

Да, это правильный ответ. Полночь в одном часовом поясе составляет 5UTC, а полночь в другом месте - 6UTC. –

0

Вы можете использовать NodaTime:

static string LocalTimeToUTC(string timeZone, string localDateTime) 
{ 
    var pattern = LocalDateTimePattern.CreateWithInvariantCulture("dd/MM/yyyy HH:mm:ss"); 
    LocalDateTime ldt = pattern.Parse(localDateTime).Value; 
    ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZone]); 
    Instant instant = zdt.ToInstant(); 
    ZonedDateTime utc = instant.InUtc(); 
    string output = utc.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture); 

    return output; 
}