【发布时间】:2015-09-28 10:31:58
【问题描述】:
我有两个 DateTime 对象,其中包含两个 UTC 日期/时间和一个用户 TimezoneId (tzdb) 作为 string。我正在尝试编写一个采用这三个参数并返回相对于时区的两个日期时间之间的总秒数(或Duration)的方法。
public static double GetDurationForTimezone(DateTime startUtc, DateTime endUtc, string timezoneId)
{
var timezone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(timezoneId);
// convert UTC to timezone
var startInstantUtc = Instant.FromDateTimeUtc(startUtc);
var startZonedDateTime = startInstantUtc.InZone(timezone);
var endInstantUtc = Instant.FromDateTimeUtc(endUtc);
var endZonedDateTime = endInstantUtc.InZone(timezone);
return endZonedDateTime.ToInstant().Minus(startZonedDateTime.ToInstant()).ToTimeSpan().TotalSeconds;
}
我想按照 w.r.t.时区,以确保它考虑到在此期间可能发生的任何夏令时变化。
示例测试:
// DST starts (25h day -- DST starts: 10/4 @ 2am local time)
var result = GetDurationForTimezone(
new DateTime(2015, 10, 3, 15, 0, 0, DateTimeKind.Utc),
new DateTime(2015, 10, 4, 15, 0, 0, DateTimeKind.Utc),
"Australia/Sydney");
Assert.Equal(TimeSpan.FromHours(25).TotalSeconds, result);
但在运行此测试时,似乎对 .ToInstant() 的调用并未遵循 ZonedDateTime 版本,而是原始 UTC DateTime 对象。因此,我看到结果是 24 小时。
【问题讨论】:
-
如果您的两个输入始终采用 UTC,并且您想要它们之间的经过时间,则不应涉及时区。 UTC 全球统一,没有夏令时。
-
测试也有缺陷。无论您在本地的哪个时区,这两个基于 UTC 的值之间都正好有 24 小时。