【问题标题】:Create DateTime from string without applying timezone or daylight savings从字符串创建 DateTime 而不应用时区或夏令时
【发布时间】:2011-08-29 18:00:24
【问题描述】:

如何从已针对 UTC 调整的字符串创建 DateTime 变量?我在设置为 BST (GMT+1) 的机器上运行它。如果我运行以下代码行:

DateTime clientsideProfileSyncStamp = Convert.ToDateTime("20-May-2011 15:20:00");

然后在针对数据库保存 (UTC) 值的测试中使用该值,然后看起来 Convert.ToDateTime() 实际上给了我 14:20 的 UTC 值。我不希望它进行转换 - 我只是希望它接受我的 DateTime 字符串已经是 UTC。

谢谢。

【问题讨论】:

  • 当我刚刚尝试Convert.ToDateTime() 时,它返回了字符串所代表的确切值。你打电话给.ToUniversalTime()?进行转换后,您对价值做了什么?

标签: c# .net datetime timezone datetime-parsing


【解决方案1】:

解析字符串,并指定当字符串中没有指定时区时它应该采用UTC时间:

DateTime clientsideProfileSyncStamp =
  DateTime.Parse(
    "20-May-2011 15:20:00",
    CultureInfo.CurrentCulture,
    DateTimeStyles.AssumeUniversal
  );

【讨论】:

    【解决方案2】:

    使用

    DateTimeOffset.Parse
    

    未充分宣传的DateTimeOffset 类型表示一个时间点,与时区差异无关,因此应优先使用需要“时间戳”的 DateTime。

    【讨论】:

    • 看起来不错。然后我需要将它传递给期望 std DateTime 的第 3 方 API - 将其转换为 DateTime 的最安全方法是什么?
    • @Journeyman,只需访问DateTimeOffset 变量的DateTime 属性:dtVar = dtoffsetVar.DateTime
    【解决方案3】:

    @Guffa 的回答非常好,但我想补充一个额外的答案。 如果您的日期时间字符串看起来像这样“2017-11-27T05:30:00.000Z”,那么 AssumeUniversal 不起作用。 试试这个:

        DateTime.Parse("2017-11-27T05:30:00.000Z", null, System.Globalization.DateTimeStyles.AdjustToUniversal);
    

    AssumeUniversal 和 AdjustToUniversal 之间存在细微差别。在这里阅读:Difference between AssumeUniversal and AdjustToUniversal

    【讨论】:

      【解决方案4】:

      在 DateTime 字符串中添加 Z

      DateTime clientsideProfileSyncStamp = Convert.ToDateTime("20-May-2011 15:20:00Z");
      Console.Write(clientsideProfileSyncStamp.ToUniversalTime()); // 20-May-2011 15:20:00
      

      【讨论】:

        【解决方案5】:

        不要忘记TryParse 变体,它允许您处理解析错误而不会出现异常

        DateTime clientsideProfileSyncStamp;
        DateTime.TryParse(
            "20-May-2011 15:20:00",
            System.Globalization.CultureInfo.CurrentCulture,
            System.Globalization.DateTimeStyles.AssumeUniversal,
            out clientsideProfileSyncStamp
        );
        

        此外,如果您不使用 ParseExactTryParseExact,它将假定输出 KindLocal,因此您可能还想使用 ToUniversalTime()

        clientsideProfileSyncStamp.ToUniversalTime();
        

        【讨论】:

          【解决方案6】:

          DateTime.Parse()DateTime.TryParse()

          var clientsideProfileSyncStamp = DateTime.Parse("20-May-2011 15:20:00");
          

          【讨论】:

            猜你喜欢
            • 2019-01-05
            • 1970-01-01
            • 2018-03-14
            • 1970-01-01
            • 1970-01-01
            • 2021-09-06
            • 2019-08-17
            • 2010-10-23
            • 2015-04-09
            相关资源
            最近更新 更多