如何在时区之间转换时间(UTC 到 EDT)?

Posted

技术标签:

【中文标题】如何在时区之间转换时间(UTC 到 EDT)?【英文标题】:How to convert time between timezones (UTC to EDT)? 【发布时间】:2010-11-01 04:22:47 【问题描述】:

我需要一个通用函数来将 UTC 时间转换为 EDT。我在印度有一个服务器。其中的应用程序需要为所有时间目的使用 EDT 时间。

我正在使用 .NET 3.5。

我在其他论坛上找到了这个。

DateTime eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(
        DateTime.UtcNow, "Eastern Standard Time");

当我尝试使用“Easten Daylight Time”时出现错误。

“在本地计算机上找不到时区 ID 'Eastern Daylight Time'”。

请帮助解决此问题或任何其他解决方案。

【问题讨论】:

【参考方案1】:

东部夏令时间不是“完整”时区的名称,而是“半”时区,实际上总是比 UTC 晚 4 小时。 (这可能有适当的术语,但我不知道。)

为什么要在没有应用夏令时的时间使用 EDT?如果您想要一个与 UTC 始终具有相同偏移量的自定义时区,请使用 TimeZoneInfo.CreateCustomTimeZone

请注意,如果您使用获取东部标准时区 (TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")),那么仍然会适当地应用夏令时(即在夏季)。

例如:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

// Prints True
Console.WriteLine(tzi.IsDaylightSavingTime(new DateTime(2009, 6, 1)));
// Prints False
Console.WriteLine(tzi.IsDaylightSavingTime(new DateTime(2009, 1, 1)));

【讨论】:

嗨乔恩,感谢您的回复。你会建议什么作为这两个中的最佳解决方案?我应该创建一个自定义时区还是使用 TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");考虑到它将处理夏令时。以及如何在使用 getdate() 方法并占用 IST 时间的存储过程中解决这个问题? 老实说,我不了解存储过程 - 如果可能的话,将 UTC 传递给它们并让它们理解 UTC。至于您是否应该使用东部标准时间的自定义时区,这取决于您是想要一个总是比 UTC 晚 4 小时的时区,还是与东部标准时间匹配的时区。您最初声明您需要“出于所有时间目的”使用 EDT - 我建议您检查您是否真的需要 EDT,或者您是否需要东部标准时间。 好的,乔恩。我被要求使用 波士顿 城市时间作为所有时间的标准时间,它属于 EDT。我不太了解夏令时。我希望我的应用程序能够花时间,尽管它在 IST 服务器中运行。以前它在 EDT 时区运行的不同服务器中,我没有这样的问题。 波士顿在东部时间 - 在夏季使用 EDT。所以是的,使用 FindSystemTimeZoneById("Eastern Standard Time") 是要走的路。我同意整个事情很混乱:( 这真的很有帮助。我不明白为什么微软文档在他们的例子中使用了这个。 docs.microsoft.com/en-us/dotnet/standard/datetime/…(我可能已经跳到本章了)但是,这个解释是有道理的。【参考方案2】:

我会说你应该使用 UTC 来计算时间段,这样你就可以避免夏令时问题,然后只使用 LocalTime 来显示。

将UTC的DateTime.ToLocalTime转换为本地时区,然后将DateTime.ToUniversalTime从本地时间转换为UTC。

在评论 1 后编辑

我是否认为您显示的时区与服务器的时区不同?

如果您使用网页来访问您的服务器,请使用 HttpRequest.UserLanguages 帮助创建 CultureInfo 对象并使用它来解析您的 DateTime 对象。 看这里完整解释:Microsoft link on displaying local user time for web pages.

如果您使用的是客户端-服务器架构,那么如果 LocalTime 调用在客户端,它将显示客户端的 LocalTime。然后将其转换为 UTC 以发送回您的服务器。

无论哪种方式,您的服务器都不需要知道客户端在哪里,因此如果您在多个时区有多个客户端,那么所有计算都会匹配。它还允许您通过使用不同的文化对象来显示您希望的任何时区的时间。

Edit 2 复制了我的第二条评论

您可以从服务器获取 UTC 格式的时间数据。然后,您可以根据需要使用 DateTime.ToLocalTime 或 DateTime.ToUniversalTime 对其进行转换。如果您还包括日期并且需要处理美国 MM/dd/yyyy 和欧洲 dd/MM/yyyy 格式,则可以使用 CultureInfo 类相应地解析 DateTime 值。这听起来比您目前所做的工作更多,但这意味着如果您再次移动服务器,则无需重新编码 DateTime 处理。

新观点

另一个需要注意的地方是服务器和客户端之间使用 NTP(网络时间协议)或 SNTP(简单网络时间协议)的时钟同步,如果它足够准确的话。我不知道您使用的是什么操作系统,但 Windows Server 时间服务使用它来同步网络。

【讨论】:

嗨,克里斯,感谢您的回复。如果我没记错的话,如果服务器在 IST 时区运行,那么来自 UTC 的 Datetime.ToLoalTime 将在 IST 中给出时间。不是吗? 是的。我已经编辑了我的答案。解释 LocalTime 如何编写客户端-服务器代码,以及为 Web 用户显示本地时间的指针。 嗨,克里斯,你做对了。我正在显示与服务器不同的时区。这是一个客户端服务器架构。但我不想依赖客户端系统时间,因为所有客户端机器时间可能不完全相同。就好像它使用服务器计时一样,它对所有客户端都是统一的。 在这种情况下,从服务器获取 UTC 格式的时间数据。然后,您可以根据需要使用 DateTime.ToLocalTime 或 DateTime.ToUniversalTime 对其进行转换。如果您还包括日期并且需要处理美国 MM/dd/yyyy 和欧洲 dd/MM/yyyy 格式,则可以使用 CultureInfo 类相应地解析 DateTime 值。这听起来比您目前所做的工作更多,但这意味着如果您再次移动服务器,则无需重新编码 DateTime 处理。【参考方案3】:

牛仔方法是取 UTC 时间,从中减去四个小时的秒数(时区偏移量),使用 UTC 格式化函数对其进行格式化,然后在其上贴上“EDT”标签。

如果您有时需要使用夏令时而其他时间需要使用标准时间,请制作转换日期查找表,或使用一些日历功能。

【讨论】:

【参考方案4】:

TimeZoneInfo.ConvertTimeFromUtc 将根据您提供的 DateTime 具有正确的偏移量。例如:

世界标准时间凌晨 3 点/东部时间晚上 11 点(偏移 4 小时):

DateTime timeSummerET = TimeZoneInfo.ConvertTimeFromUtc(Convert.ToDateTime("08/01/2019 03:00:00"), zoneET);

世界标准时间凌晨 3 点/东部时间晚上 10 点(5 小时偏移):

DateTime timeWinterET = TimeZoneInfo.ConvertTimeFromUtc(Convert.ToDateTime("12/01/2019 03:00:00"), zoneET);

【讨论】:

以上是关于如何在时区之间转换时间(UTC 到 EDT)?的主要内容,如果未能解决你的问题,请参考以下文章

Redshift - 将 UTC 数据转换为其他时区

在 Rails 3 中将 UTC 转换为本地时间

JSON如何反序列化日期时间并将UTC转换为指定时区?

如何将 UTC 格式的字符串转换为特定时区的日历?

怎么把linux上的UTC时间改成CST时间

如何根据 bigquery 中的时区列将 UTC 时间转换为本地时区?