gpt4 book ai didi

c# - 为什么 DateTime.ToLocalTime() 不考虑夏令时?

转载 作者:太空狗 更新时间:2023-10-29 22:58:23 28 4
gpt4 key购买 nike

我有一个使用 DateTime.UtcNow.ToString("s") 创建的 UTC 时间字符串(我从数据库中获取,因此我无法更改格式)。我想显示一些面向用户的东西,比如“10:00 AM”。我所在的地方(在英国),时钟最近向前走,下面的方法是一个小时:

var timenowstring = DateTime.UtcNow.ToString("s");
var dateutc = DateTime.Parse(timenowstring).ToShortTimeString();
var datelocal = DateTime.Parse(timenowstring).ToLocalTime().ToShortTimeString();

Console.WriteLine("Utc time string: " + dateutc);
Console.WriteLine("Local time string: " + datelocal);

两者都打印“9:02 AM”,而实际上是 10:02 AM。

这是它在 http://csharppad.com/ 上重现的截图:

utc and local show the same time - see system clock in lower right, which is correct bigger image

CSharpPad gist

我做错了什么?获取 DateTime 对象的最简单方法是什么,该对象将在我调用 .ToShortTimeString() 时返回正确的时间?

注意 the docs on ToLocalTime()说:

The conversion also takes into account the daylight saving time rule that applies to the time represented by the current DateTime object.

最佳答案

你说:

I have a a UTC time string (that I get from a database, so I can't change the format) that is created with DateTime.UtcNow.ToString("s").

马上,你就有问题了。数据库中的日期(通常)不存储为字符串。它们存储在具有特定数据类型的字段中。在 SQL Server(例如)中,您可能正在使用 datetimedatetime2 字段。这些不是字符串。当您将它们检索到您的 .NET 代码中时,它们会直接转换为 DateTime 类型。如果您将其视为字符串,那就错了。

例如,您的数据访问代码可能会执行如下操作:

DateTime dt = Convert.ToDateTime(dataReader["myDateTimeField"].ToString());

这很常见,但完全错误。你应该这样做:

DateTime dt = (DateTime) dataReader["myDateTimeField"];

或者如果该字段可以为空:

DateTime? dt = dataReader["myDateTimeField"] as DateTime;

一旦您正确加载值而不是将其解析为字符串,其余的将正常工作。 DateTime 值的 Kind 属性将具有 DateTimeKind.Unspecified,当您对其调用 ToLocalTime 时,它将假设您想要将未指定的值视为 UTC。 ( See the chart on MSDN .)

关于您发布的代码,虽然它有点困惑(不必要地遍历字符串),但它实际上可以正常工作 - 假设您在您的 时区运行它。在 ToLocalTime 方法中,“本地”表示代码恰好运行的机器的本地时区设置。 对于 csharppad.com,时区恰好是 UTC。它无法知道您想使用英格兰的时区规则。

CSharpPad Time Zone

如果您打算在服务器上运行您的代码,那么您根本不应该使用 ToLocalTime - 因为服务器的时区可能无关紧要。相反,您可以使用 TimeZoneInfo 来转换时间:

// this uses the time zone for England
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime englandDatetime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, tz);

或者,您可以使用开源 Noda Time库,像这样:

DateTimeZone tz = DateTimeZoneProviders.Tzdb["Europe/London"];
DateTime englandDateTime = Instant.FromDateTimeUtc(utcDateTime)
.InZone(tz)
.ToDateTimeUnspecified();

关于c# - 为什么 DateTime.ToLocalTime() 不考虑夏令时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29557418/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com