代码之家  ›  专栏  ›  技术社区  ›  onefootswill

非UTC或本地时区中的DateTime

  •  0
  • onefootswill  · 技术社区  · 3 年前

    我有关于的问题 DateTimeKind C#中的结构。

    如果我转换了 DateTime 到一个新的DateTime(不在我的本地时区中),使用如下内容:

    TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Tokyo Standard Time");
    

    我该用什么 Kind 新DateTime的属性? Unspecified 感觉有点奇怪,对转换没有多大帮助。

    我有一种感觉,只要你使用 Timezone 这不是您的本地,也不是UTC,那么您绝对必须开始使用 DateTimeOffset 结构。

    0 回复  |  直到 3 年前
        1
  •  2
  •   onefootswill    3 年前

    这更多的是关于如何处理非本地时区的问题。
    当您超出本地时区时,您确实需要使用 DateTimeOffset

    在编写时间服务时,您可能需要添加一个方法,用于将一个非本地时区中的DateTime转换为另一个非当地时区。当使用时,这是非常直接的 日期时间偏移

    public DateTimeOffset ConvertToZonedOffset(DateTimeOffset toConvert, string timeZoneId)
    {
        var universalTime = toConvert.ToUniversalTime(); // first bring it back to the common baseline (or standard)
    
        var dateTimeOffset = TimeZoneInfo.ConvertTime(universalTime, TimeZoneInfo.FindSystemTimeZoneById(timeZoneId));
        
        return dateTimeOffset;
    }
    

    传入的 日期时间偏移 具有源偏移量,并且 timeZoneId 被传入提供了足够的信息来实现目标时区(和偏移)。

    然后返回 日期时间偏移 具有目标偏移量。

    当你用的时候,它会变得有点笨重 DateTime 结构,如果您想提供一个等效的方法:

    public DateTime ConvertToZonedOffset(DateTime toConvert, string sourceTimeZoneId, string targetTimeZoneId)
    {
        return TimeZoneInfo.ConvertTimeBySystemTimeZoneId(toConvert, sourceTimeZoneId, targetTimeZoneId);
    }
    

    这就是 DateTimeKind 进来。如果您:

    • 传入DateTime,并将Kind设置为UTC或Local; 以及
    • sourceTimeZone两者都不是,

    然后 ConvertTimeBySystemTimeZoneId 将引发异常。所以,当你在处理“第三时区”时,Kind必须是 Unspecified 。这告诉该方法忽略系统时钟,不要假设它是UTC,并通过作为源时区传入的任何内容。

    它不如 日期时间偏移 版本的另一种方式。返回的 日期时间 没有关于时区的信息,并且 Kind 设置为 未指定 。这基本上意味着调用代码有责任知道和跟踪日期和时间在哪个时区有效。这并不理想。以至于我决定“固执己见”,放弃这种方法。我将强制调用代码转换 日期时间 他们可能正在与合作 日期时间偏移 并在返回时消耗一个。

    注1:如果 友善的 设置为 Local 并且sourceTimeZone与您的本地时区匹配,它将正常工作。
    注2:如果 友善的 设置为 Utc 并且sourceTimeZone设置为“协调世界时”,您可能会得到以下信息 TimeZoneNotFoundException :

    在本地计算机上找不到时区ID“协调世界时”

    我认为这是因为UTC是一个标准而不是时区,尽管由返回 TimeZoneInfo.GetSystemTimeZones 作为一个 Timezone .

        2
  •  1
  •   Heinzi    3 年前

    我应该为新DateTime的Kind属性使用什么? Unspecified 感觉有点奇怪。。。

    …但在这种情况下,这是正确的值。 The documentation 的DateTimeKind枚举在这个主题上非常清楚:

    地方的 (2) :表示的时间为当地时间。

    未指定 (0):表示的时间未指定为本地时间或协调世界时(UTC)。

    Utc (1) :表示的时间为UTC。

    您的时间既不是本地时间也不是UTC,因此唯一正确的值为 未指定 .

    我的感觉是,一旦您使用的时区不是您的本地时区,也不是UTC时区,那么您就必须开始使用 DateTimeOffset 结构。

    你不必这么做,但它肯定会让你的生活更轻松。正如您所注意到的, DateTime 不提供将时区信息与日期一起存储的选项。这正是 日期时间偏移 是的。