【问题标题】:DateTimeKind is Unspecified Even Though I Set itDateTimeKind 未指定,即使我设置了它
【发布时间】:2021-12-16 19:45:07
【问题描述】:

当我检查optionDateDateTime 属性的DateTimeKind 值时,我看到未指定,即使我在下面的代码中将dt 的DateTimeKind 设置为UTC。我希望optionDate 有一个DateTime,它的DateTimeKind 属性设置为UTC。我哪里错了?

       var dt = new DateTime(Convert.ToInt32(optionDateInfo.dateTime.year),
            Convert.ToInt32(optionDateInfo.dateTime.month), Convert.ToInt32(optionDateInfo.dateTime.day),
            Convert.ToInt32(optionDateInfo.dateTime.hour), Convert.ToInt32(optionDateInfo.dateTime.minutes),
            0, DateTimeKind.Utc);

        var optionDate = new DateTimeOffset(dt);

【问题讨论】:

    标签: c# datetime datetimeoffset


    【解决方案1】:

    这是记录在案的:

    DateTimeOffset.DateTime

    返回的 DateTime 对象的 DateTime.Kind 属性的值为 DateTimeKind.Unspecified。

    请注意,DateTimeOffset 没有“种类”。它有日期、时间和偏移量。当您将 DateTime 与类型 Utc 传递给它时,它会将其偏移量设置为 0,并将其日期和时间设置为给定的 DateTime。此时,您的DateTimeKind 已“丢失”。

    偏移量 0 并不一定意味着它的种类是 DateTimeKind.Utc。它可能是伦敦的当地时间,也可能是非洲某个地方的时间。所以它不能给你一个DateTime 和一种Utc 只是因为它的偏移量也是0。

    另外,DateTime 能够表示 3 种东西已经是一个有问题的设计,如果 DateTime 属性现在可以根据偏移量是否与本地时间匹配返回 3 种不同的 DateTime,是UTC 或其他的,那就更糟了。

    相反,它被设计为具有 3 个属性,为您提供不同类型的 DateTimes。

    • DateTime 为您提供DateTimeOffset 的日期和时间部分,以及Unspecified
    • LocalDateTimeDateTimeOffset 的日期和时间部分转换为当前时区,并为您提供DateTime 类型为Local
    • UtcDateTimeDateTimeOffset 的日期和时间部分转换为UTC,并为您提供DateTime 类型为Utc

    如果你想要DateTimeUtc,你应该使用最后一个。

    【讨论】:

      【解决方案2】:

      使用指定种类

      var myUtcZeroOffset = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)
      
      //If constructing a datetime offset to be not utc you can supply the offset instead
      var myOffSetExplicitLocal = new DateTimeOffset(DateTime.Now, new TimeSpan(1, 0, 0));
      var localDateTime = myOffSetExplicitLocal.DateTime;
      var utcZeroOffSetDateTime = myOffSetExplicitLocal.UtcDateTime;
      

      更糟糕的是,它是 Microsoft 的一个可批评的实现,因为根据 ISO 8601,通用协调时间不是时区而是一个符号,所以实际上 toUTC 作为一个概念是有缺陷的,因为 '2021-11-02T10 :16:25.12345+01:00' 在 UTC 格式和 UTC 零偏移量中完全有效,通常称为 Zulu 是 '2021-11-02T09:16:25.12345Z' 等价物,然后得到 datetimekind UTC 实际上只是在协调时间格林威治标准时间纬度周围的零线,但使它协调的是+部分,+00:00可以缩写为Z,所以做了很多事情来减轻固有的冲突,并且与构建服务器和云提供商的.Local是特别可疑,所以我建议始终坚持使用 ISO 8601 字符串,除非您实际上需要在您的数据库中将它们与日期操作一起使用,在这种情况下,要命名适当的字段,例如 DateTimeCreatedUtcZero 列,例如 只是我对这个话题的五美分理由,希望它有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-01
        相关资源
        最近更新 更多