c# - 非 UTC 或本地时区中的日期时间

标签 c# datetime

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

如果我使用以下方法将 DateTime 转换为新的 DateTime(不在我的本地时区中):

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

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

我的感觉是,一旦您使用的Timezone不是您本地的且不是UTC,那么您绝对必须开始使用DateTimeOffset结构。

最佳答案

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

编写时间服务时,您可能需要添加一种方法,用于将一个非本地时区的 DateTime 转换为另一个非本地时区。使用 DateTimeOffset 类时,这非常简单:

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;
}

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

返回的DateTimeOffset具有目标偏移量。

如果您想提供等效的方法,那么当您使用 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,并遵循作为 sourceTimeZone 传入的任何内容。

它在另一个方面不如 DateTimeOffset 版本。返回的 DateTime 没有有关时区的信息,并且 Kind 设置为 Unspecified。这基本上意味着调用代码有责任了解并跟踪该日期和时间在哪个时区有效。这并不理想。以至于我决定“固执己见”并摆脱这种方法。我将强制调用代码将它们可能正在使用的 DateTime 转换为 DateTimeOffset 并在返回时使用它。

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

The time zone ID 'Coordinated Universal Time' was not found on the local computer

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

关于c# - 非 UTC 或本地时区中的日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70484624/

相关文章:

python - 带有日期时间和相对增量的奇怪算术

c# - 在 ASP.Net MVC3 中使用 HtmlHelper 和分页呈现 View

c# - Crystal 报表导出为 PDF 文件大小太大

c# - 仅具有过去 10 天脱机同步 PullAsync 行的 MobileServiceClient

python - 每组最近 n 天的计数

php - 帮我理解mysql当前时间和时区的now()

c# - C# 中的字符串流

c# - 如何使用 Fluent-NHibernate 和 MySQL 指定自动递增 (int) 标识列

javascript - Sequelize 如何比较查询中日期的年份

python - 日期时间和 utctimetuple()