【问题标题】:DateTime conversion adds one extra hourDateTime 转换增加一小时
【发布时间】:2018-08-27 19:32:38
【问题描述】:

我有一个 UTC 输入时间,并希望将其转换为设备的本地时间。我想使用 TryParse 方法来避免异常。

输入时间是晚上 7 点。预计 out DateTime date 参数为 20:00。相反,它变成了 21:00。

我的时区是 GMT+1 中欧时间。目前不是 DST,但 DST 将于今年 3 月下旬开始。

var value = "4/2/2018 7:00:00 PM"; // UTC time

if (DateTime.TryParse(value.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime date))
{
    var isDST = date.IsDaylightSavingTime(); // true
    var kind = date.Kind; // DateTimeKind.Local
    var time = date.ToShortTimeString(); // 21:00
}

【问题讨论】:

  • DateTimeStyles.AssumeLocal
  • 您需要提供有关您的时区的更多信息(不仅仅是偏移量)
  • @javm 设备设置为哪个时区?我问的不是 +/- 小时,而是国家/州名称。您是说本月晚些时候开始,4 月 2 日将在 DST 内,如果您的时区在 DST 期间从 +1 更改为 +2,则代码正在运行正确。
  • @javm 见,it is correct。 2018-04-02T19:00:00UTC 将是 21:00,因为那天您的本地时区将是 +2 而不是 +1。
  • "4/2/2018" 是 4 月 2 日,所以它属于从 3 月底开始的 DST。所以输出是正确的,因为 UTC 7 PM 是您的时区 9 PM(1 小时常规偏移 + 1 小时 DST 偏移)。

标签: c# date datetime timezone


【解决方案1】:

框架将遵守夏令时规则。在您的示例中:

  • 输入是April 2, 2018 7:00 PM UTC
  • 输出的时区是Central European Time (CET)

显然您的国家/地区1 计划在 3 月的最后一个星期日使用 Central European Summer Time (CEST),并且时区偏移量将 +01:00 更改为 +02:00。结果April 2, 2018 9:00 PMis therefore correct2.


1 一个国家或地区定义其时区,其中包括一个或多个偏移量以及这些偏移量生效的日期。
2相同的代码将产生如果输入日期在 DST 之外,则相差一小时。

【讨论】:

    【解决方案2】:

    避免使用Local 日期时间类型,因为这意味着您的代码将根据运行机器的时区不同运行。

    您需要确保您有一个有效的 UTC 日期时间表示,然后显式转换为您需要的时区:

    var utcDateTime = DateTime.SpecifyKind(DateTime.Parse(val), DateTimeKind.Utc); // guarantee your DateTime is in Utc.
    
    TimeZoneInfo localZone = TimeZoneInfo.FindSystemTimeZoneById("E. Europe Standard Time");
    Console.WriteLine(TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, localZone));
    

    【讨论】:

    • "避免使用本地日期时间类型,因为这意味着您的代码会根据运行机器的时区不同运行。"在这种情况下,这就是整个想法:OP 想要将 UTC 值转换为本地表示。向用户显示值是完全合理的。 OP 在解析操作中指定预期的类型也是完全合理的......我相信这远远超过调用 DateTime.Parse 并将其隐含然后使用 DateTime.SpecifyKind
    【解决方案3】:

    您可能没有考虑夏令时。

    bool isDST = time.IsDaylightSavingTime;
    

    检查 DST 是否在特定日期生效。

    【讨论】:

    • IsDaylightSavingTime() 的值为true。如何确保转换采用此值的高度?
    • OP 不需要这样做。 .NET 将其从 UTC 转换为本地,包括 DST,或者不是 - OP 不需要明确地做任何事情。
    • @javm:您不需要对代码进行更改,但这确实表明您对您的时区的想法和系统对您的时区的想法是不一样的。请在问题中提供有关您的系统时区的更多信息。
    • @JonSkeet 我不同意。 OP 显然想要没有 DST 的本地日期时间,原因超出了我们的业务范围。虽然我理解为什么我被否决了,但同时我不清楚他如何在没有手动修改的情况下获得预期的日期时间。
    • 实际上,OP 的编辑建议“输出是正确的”。 (如果 OP 总是想应用时区的标准偏移量,那么最简单的方法就是不使用您显示的代码,而是使用 TimeZoneInfo.BaseUtcOffset。)
    猜你喜欢
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2017-03-25
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    相关资源
    最近更新 更多