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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/964894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:22:42  来源:igfitidea点击:

How to convert time between timezones (UTC to EDT)?

c#timezone

提问by Shetty

I need to have a common function to convert UTC time to EDT. I have a server in India. An application in it needs to use EDT time for all time purposes.

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

I am using .NET 3.5.

我正在使用 .NET 3.5。

I found this on some other forum.

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

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

When i tried with "Easten Daylight Time" I got an error.

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

"The time zone ID 'Eastern Daylight Time' was not found on the local computer".

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

Please help with this or any other solution.

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

采纳答案by Jon Skeet

Eastern Daylight Time isn't the name of a "full" time zone - it's "half" a time zone, effectively, always 4 hours behind UTC. (There may be proper terminology for this, but I'm not aware of it.)

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

Why would you want to use EDT for times which don't have daylight savings applied? If you want a custom time zone that always has the same offset to UTC, use TimeZoneInfo.CreateCustomTimeZone.

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

Note that if you use get the Eastern Standard timezone (TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")) then that will still have daylight saving time applied appropriately (i.e. during summer).

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

For example:

例如:

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)));

回答by ChrisBD

I would have said that you should use UTC for calculations of time periods, so that you avoid issues of daylight saving time and then use LocalTime for display only.

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

DateTime.ToLocalTime for UTC to whatever the local time zone is and then DateTime.ToUniversalTime to convert from local time to UTC.

DateTime.ToLocalTime for UTC 到任何本地时区,然后 DateTime.ToUniversalTime 从本地时间转换为 UTC。

Edit after comment 1

评论后编辑 1

Do I take it then that you're after displaying a different timezone to that of the server?

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

If you're using web pages to access your server then use HttpRequest.UserLanguages to help create a CultureInfo object and use that to parse your DateTime object. Look here for a full explanation:Microsoft link on displaying local user time for web pages.

如果您使用网页访问您的服务器,则使用 HttpRequest.UserLanguages 来帮助创建 CultureInfo 对象并使用它来解析您的 DateTime 对象。在此处查看完整说明:Microsoft 链接显示网页的本地用户时间。

If you're using client-server architecture then if the LocalTime call is on the client side it will display the LocalTime for the client. You then convert it to UTC to send back to your server.

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

Either way your server doesn't need to know where the client is so if you have multiple clients in multiple timezones then all calculations will match. It will also allow you to show the times in any timezone that you wish by use of different Culture objects.

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

Edit 2 copied my second comment

编辑 2 复制了我的第二条评论

You can get time data in UTC format from the server. Then you can convert it using DateTime.ToLocalTime or DateTime.ToUniversalTime as requried. If you're including dates as well and need to cope with say US MM/dd/yyyy and european dd/MM/yyyy formats the you can use CultureInfo class to parse the DateTime value accordingly. It sounds like more work than what you have at the moment, but it would mean that if you move your server again then you don't need to recode the DateTime handling.

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

A new point

一个新点

Another point to look at is clock synchronisation between the server and the clients using NTP (Network Time Protocol) or SNTP (Simple Network Time Protocol) if it is accurate enough. I don't know what OS you are using but this is used by Windows Server time services to synchronise networks.

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

回答by Robert L

The cowboy method is to take the UTC time, subtract four hours' worth of seconds from it (the timezone offset), format it using a UTC formatting function, and slap a "EDT" label on it.

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

If you need to use Daylight Time sometimes and Standard Time other times, either make a lookup table of switchover dates, or use some calendar function.

如果您有时需要使用夏令时,有时需要使用标准时间,要么制作切换日期的查找表,要么使用一些日历功能。

回答by Andrew Gale

TimeZoneInfo.ConvertTimeFromUtc will have correct offset depending on the DateTime you give it. For example:

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

3AM UTC/11PM ET (4 hour offset):

UTC 凌晨 3 点/美国东部时间晚上 11 点(4 小时偏移):

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

3AM UTC/10PM ET (5 hour offset):

UTC 凌晨 3 点/美国东部时间晚上 10 点(偏移 5 小时):

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