如何在dot net core中获取另一个时区的本地时间

4

我正在解决一个问题,需要获取另一个时区的当前日期和时间。我不知道我的代码将在哪个时区运行,并且它需要在Windows和Linux机器上正常工作。

我还没有找到任何方法来实现这一点。有什么想法吗?

(附注: 我需要找出在瑞典是什么时间,包括夏令时,从代码可能运行的任意时区).


我通常使用UTC作为所有DateTime时间戳的标准。如果您想查找特定时区的时间,可以考虑使用内置的时区转换方法。您可以记录UTC时间,然后根据需要进行转换。这是文档部分的链接。您需要仔细阅读并可能需要创建自己的TimeZoneInfo类。https://learn.microsoft.com/en-us/dotnet/api/system.timezoneinfo.converttime?view=netcore-3.1 - jdewerth
我有所有时间戳的UTC时间,我需要将其用于消息模板,该模板包括发送给客户的当前时间。时间应该是他们本地时区的时间,而不是UTC时间。到目前为止,我还没有找到在dot net core中将UTC时间转换为其他时间的方法。当你寻找它时,你会发现一堆关于它在Windows和Linux上工作方式不同的帖子。 - JensB
1个回答

7

瑞典的IANA时区ID是"Europe/Stockholm"(用于Linux、OSX和其他非Windows平台)。瑞典的Windows时区ID是"W. Europe Standard Time"

因此,您可以执行以下操作:

// Determine the time zone ID for Sweden
string timeZoneId = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
    ? "W. Europe Standard Time"
    : "Europe/Stockholm";

// Get a TimeZoneInfo object for that time zone
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);

// Convert the current UTC time to the time in Sweden
DateTimeOffset currentTimeInSweden = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi);

如果需要,你可以使用我的TimeZoneConverter库,这样可以在任何平台上使用任何id,从而简化操作。
TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Europe/Stockholm");
DateTimeOffset currentTimeInSweden = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi);

如果运行在.NET 6或更高版本,并且启用了ICU全球化支持,则您无需再使用我的库。如果需要,.NET会自动转换格式。因此,您只需要执行以下操作:
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Europe/Stockholm");
DateTimeOffset currentTimeInSweden = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi);

注意,代码运行所在的时区并不重要,也不应该重要。仅瑞典的夏令时规则是相关的,而不是代码可能运行的时区的夏令时规则。

最后,请注意如果您希望得到有效的结果,则必须正确设置计算机的时钟。始终使用NTP或操作系统的“自动设置日期和时间”功能将计算机时钟与互联网同步。


1
另外请注意,如果您正在使用基于Alpine Linux的.NET Core Docker镜像,则需要单独安装tzdata。请参阅https://github.com/dotnet/dotnet-docker/issues/1366。 - Matt Johnson-Pint
很抱歉要对一个声望如此高的人的回答进行负评,但我认为这个答案不完整或者我没有正确理解。我在法国,将我的电脑时间设置为比实际时间早一小时(这是我在部署服务器时遇到的实际问题)。我得到了巴黎的时区,按照你的示例将其转换为DateTimeOffset,然后检查本地日期时间。它比实际时间早了一个小时。而且UTC时间比实际时间早了一个小时。如何获取真正的本地时间而不基于计算机时间?很抱歉,但我感到困惑。 - Jérôme MEVEL
@JérômeMEVEL - 如果时钟提前了一个小时,那就是个问题。时钟应该始终同步。如果您希望使用平台的NowUtcNow方法准确获取当前时间,则始终使用操作系统的“自动设置日期和时间”(NTP)功能。如果由于某种原因您不能依赖系统时钟,则必须从某个您信任的服务器获取当前时间。您可以在代码中实现NTP客户端,或者从Web服务器获取当前时间(如果您不需要太精确)。 - Matt Johnson-Pint
感谢您的回复,我给您点了赞。实际上,服务器的时间没有设置不正确,只是设置在Europe/London(服务器可以位于世界任何地方),而我们的业务位于法国。我觉得混淆是因为您变量名称 currentTimeInSweden 的名称。我本来期望本地时间是瑞典的,但实际上它仍然设置为当前机器的时间。无论如何,后来我发现属性DateTime提供了正确的日期和时间,所以没问题了。感谢您的答案,抱歉之前给您点了踩。 - Jérôme MEVEL
嗨@JérômeMEVEL。我认为可能还有一些混淆需要解决。 currentTimeInSweden确实是瑞典的正确时间,表示为DateTimeOffset。访问DateTime属性将仅删除偏移量并将结果的Kind属性设置为Unspecified。日期和时间将保持不变。此外,只要计算机的时钟设置正确,该代码将在世界上任何地方的计算机上提供相同的输出。 - Matt Johnson-Pint
1
我认为你可能会把服务器的时钟提前或推迟一个小时,而不是将它们与NTP源同步。如果你试图手动设置时间以调整时区或夏令时(DST),那么这是错误的方法。换句话说,如果你只是执行 Console.WriteLine(DateTime.UtcNow),那么它应该始终与此处显示的时间对齐:https://www.timeanddate.com/worldclock/timezone/utc - Matt Johnson-Pint

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