Преобразование даты и времени UTC в другой часовой пояс
Вопрос
У меня есть значение даты и времени UTC, полученное из записи базы данных.У меня также есть указанный пользователем часовой пояс (экземпляр TimeZoneInfo).Как мне преобразовать эту дату и время UTC в местный часовой пояс пользователя?Кроме того, как мне определить, соблюдается ли в данный момент в указанном пользователем часовом поясе летнее время?Я использую .NET 3.5.
Спасибо, Марк
Решение
Взгляните на DateTimeOffset Дата - время смещения структура:
// user-specified time zone
TimeZoneInfo southPole =
TimeZoneInfo.FindSystemTimeZoneById("Antarctica/South Pole Standard Time");
// an UTC DateTime
DateTime utcTime = new DateTime(2007, 07, 12, 06, 32, 00, DateTimeKind.Utc);
// DateTime with offset
DateTimeOffset dateAndOffset =
new DateTimeOffset(utcTime, southPole.GetUtcOffset(utcTime));
Console.WriteLine(dateAndOffset);
Для перехода на летнее время смотрите Информация о часовом поясе.Это дневное время экономии способ.
bool isDst = southpole.IsDaylightSavingTime(DateTime.UtcNow);
Другие советы
Лучший способ сделать это - просто использовать TimeZoneInfo.ConvertTimeFromUtc
.
// you said you had these already
DateTime utc = new DateTime(2014, 6, 4, 12, 34, 0);
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
// it's a simple one-liner
DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, tzi);
Единственная загвоздка в том, что входящий DateTime
значение может не иметь DateTimeKind.Local
добрый.Это должно быть либо Utc
, или Unspecified
.
Вы можете использовать специальную функцию в TimeZoneInfo, если хотите преобразовать DateTimeOffset в другой DateTimeOffset:
DateTimeOffset newTime = TimeZoneInfo.ConvertTime(
DateTimeOffset.UtcNow,
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
);
Ответ Antartica работает только для часовых поясов, соответствующих UTC.Я очень травмирован этим DateTimeOffset
функция и после нескольких часов проб и ошибок мне удалось создать практичную функцию расширения преобразования, которая работает со всеми часовыми поясами.
static public class DateTimeFunctions
{
static public DateTimeOffset ConvertUtcTimeToTimeZone(this DateTime dateTime, string toTimeZoneDesc)
{
if (dateTime.Kind != DateTimeKind.Utc) throw new Exception("dateTime needs to have Kind property set to Utc");
var toUtcOffset = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc).GetUtcOffset(dateTime);
var convertedTime = DateTime.SpecifyKind(dateTime.Add(toUtcOffset), DateTimeKind.Unspecified);
return new DateTimeOffset(convertedTime, toUtcOffset);
}
}
Пример:
var currentTimeInPacificTime = DateTime.UtcNow.ConvertUtcTimeToTimeZone("Pacific Standard Time");
// TO get Currrent Time in current Time Zone of your System
var dt = DateTime.Now;
Console.WriteLine(dt);
// Display Time Zone of your System
Console.WriteLine(TimeZoneInfo.Local);
// Convert Current Date Time to UTC Date Time
var utc = TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.Local);
Console.WriteLine(utc);
// Convert UTC Time to Current Time Zone
DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZoneInfo.Local);
Console.WriteLine(pacific);
Console.ReadLine();