将UTC时间转换为东部时区

9

我有一个UTC时间戳,它以字符串类型的形式给出,我希望将此时间戳转换为东部时间。问题是,当我在UTC时间戳上调用DateTime.Parse或Convert.ToDateTime时,它会将其转换为我的本地时间,即中央时间。

我应该如何将一个字符串时间戳转换为东部时间,而不考虑运行服务器的本地时间?


我不确定,但你可以尝试使用 Cultures。看看这个链接:http://msdn.microsoft.com/en-us/library/5hh873ya%28v=vs.90%29.aspx - George
@George - 文化与时区无关,它们对时区没有任何影响。 - Matt Johnson-Pint
3个回答

17

我会尝试分析你的问题,但下次请附上代码,这样每个人都可以更清楚地看到你的意思。

我有一个以UTC格式传入的UTC时间戳(字符串类型)。

好的,我理解你的意思是这样:

string utcString = "2014-02-25T12:34:56.000Z";

这是一个ISO-8601的UTC时间戳。如果它是以其他格式表示的,请在评论中告诉我,我会相应地更新答案。

......问题是,当我对UTC时间戳调用DateTime.ParseConvert.ToDateTime时,它会将其转换为我的本地时间,即中部时间。

DateTime utcDateTime = DateTime.Parse(utcString,
                                      CultureInfo.InvariantCulture,
                                      DateTimeStyles.RoundtripKind);
RoundtripKind 样式告诉解析器在输入字符串中查找“kind”信息,例如指示 UTC 的 Z。生成的 DateTime 将具有原始值,并将其 .Kind 属性设置为 DateTimeKind.Utc

...我希望将此时间戳转换为东部时间。

现在您拥有一个 UTC DateTime,可以使用 TimeZoneInfo 类轻松转换它。
TimeZoneInfo easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById(
                                                         "Eastern Standard Time");

DateTime easternDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime,
                                                           easternTimeZone);

就是这样。结果是一个包含美国东部时区本地时间的DateTime对象。它的类型将为Unspecified,因为时区信息不会随着DateTime对象一起传递。

同时请注意,“Eastern Standard Time”指的是整个美国东部时区,包括EST和EDT。


1
您精辟地剖析了我那个写得不好的问题。非常感谢您。 - user1373121
夏令时怎么办?如果这是个业余问题,我很抱歉。 - donstack
@donstack - 没问题。上述示例已经考虑了夏令时。Windows的时区ID“Eastern Standard Time”命名不当,应该改为“Eastern Time”。它包括EST和EDT两个时区。请参阅时区标签wiki获取更多示例。 - Matt Johnson-Pint
微软甚至不能准确地命名它们的时区,这让正确处理夏令时成为一场噩梦,这真是不可思议。它不只是命名不当,而是错误地命名! - Luke
关于从模型到视图获取先前存储的值并将其转换为正确的UTC "kind"的快速说明:您可以使用.ToUniversalTime()(DateTime.Now.ToUniversalTime())而无需首先解析字符串。 - undefined
@CodeBreaker - 是的,但有一个注意事项,如果您模型中现有的值的类型为DateTimeKind.Unspecified,那么ToUniversalTime函数将假定该值是基于本地系统时间的。如果您在太平洋时间开发,并且您的服务器设置为UTC,这可能会导致问题。更好的方法是使用TimeZoneInfo类上的转换方法,指定特定的源时区。当然,根据应用程序的性质,可能会有所不同。 - undefined

2

请在此处查看文档。

基本上,您需要使用 TimeZoneInfo.FindSystemTimeZoneById("<时区>");,然后将其用作 ConvertTime 函数的第三个参数。其中第二个参数是您当前所在的时区。

DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
   TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
   Console.WriteLine("{0} {1} is {2} local time.", 
           hwTime, 
           hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName, 
       TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}                           
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Hawaiian STandard Time zone has been corrupted.");
}

1
我发现了一个方便的解决方案:

var e_europe = TimeZoneInfo.FindSystemTimeZoneById("E. Europe Standard Time");
var utcnow = DateTime.UtcNow;
Console.WriteLine(utcnow.ToString());
Console.WriteLine(TimeZoneInfo.ConvertTimeFromUtc(utcnow, e_europe).ToString());

它打印
2/26/2014 1:03:43 AM
2/26/2014 3:03:43 AM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接