我有关于 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/