【发布时间】:2012-03-20 12:30:46
【问题描述】:
我的本地时区是 (UTC+10:00) 堪培拉、墨尔本、悉尼
2012 年 3 月 31 日星期六 15:59 UTC = 2012 年 4 月 1 日星期日 02:59 +11:00
2012 年 3 月 31 日星期六 16:00 UTC = 2012 年 4 月 1 日星期日 02:00 +10:00
夏令时在 4 月的第一个星期日凌晨 3 点结束,时钟拨回 1 小时。
给定以下代码 ....
DateTime dt1 = DateTime.Parse("31-Mar-2012 15:59", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
DateTime dt2 = DateTime.Parse("31-Mar-2012 15:59", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal).AddMinutes(1);
DateTime dt3 = DateTime.Parse("31-Mar-2012 16:00", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
Console.WriteLine("{0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt1);
Console.WriteLine("{0:yyyy-MMM-dd HH:mm:ss.ffff K} ({1}) = {2:yyyy-MMM-dd HH:mm:ss.ffff K} ({3})", dt2, dt2.Kind, dt3, dt3.Kind);
Console.WriteLine("{0} : {1} : {2}", dt1.ToUniversalTime().Hour, dt2.ToUniversalTime().Hour, dt3.ToUniversalTime().Hour);
我得到以下输出
2012 年 4 月 1 日 02:59:00.0000 +11:00
2012 年 4 月 1 日 03:00:00.0000 +10:00(本地)= 2012 年 4 月 1 日 02:00:00.0000 +10:00(本地)
15:17:16
在原始日期时间上增加 1 分钟会使当地时间为凌晨 3 点,但也会将偏移量设置为 +10 小时。 将 1 分钟添加到 UTC 日期并正确解析将本地时间设置为凌晨 2 点,并带有 +10 UTC 偏移量。
重复
DateTime dt1 = new DateTime(2012, 03, 31, 15, 59, 0, DateTimeKind.Utc);
DateTime dt2 = new DateTime(2012, 03, 31, 15, 59, 0, DateTimeKind.Utc).AddMinutes(1);
DateTime dt3 = new DateTime(2012, 03, 31, 16, 0, 0, DateTimeKind.Utc);
或
DateTime dt1 = DateTime.Parse("31-Mar-2012 15:59", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
DateTime dt2 = DateTime.Parse("31-Mar-2012 15:59", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal).AddMinutes(1);
DateTime dt3 = DateTime.Parse("31-Mar-2012 16:00", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
给予
2012-Mar-31 15:59:00.0000 Z
2012 年 3 月 31 日 16:00:00.0000 Z (UTC) = 2012 年 3 月 31 日 16:00:00.0000 Z (UTC)
15:16:16
如预期的那样
再次重复
DateTime dt1 = new DateTime(2012, 03, 31, 15, 59, 0, DateTimeKind.Utc).ToLocalTime();
DateTime dt2 = new DateTime(2012, 03, 31, 15, 59, 0, DateTimeKind.Utc).ToLocalTime().AddMinutes(1);
DateTime dt3 = new DateTime(2012, 03, 31, 16, 0, 0, DateTimeKind.Utc).ToLocalTime();
给出原件
2012 年 4 月 1 日 02:59:00.0000 +11:00
2012 年 4 月 1 日 03:00:00.0000 +10:00(本地)= 2012 年 4 月 1 日 02:00:00.0000 +10:00(本地)
15:17:16
谁能解释一下?
如果我使用 TimeZoneInfo 从 UTC 转换为澳大利亚东部标准时间,我会得到正确的时间,但我会丢失 DateTime 实例中的偏移信息,因为 DateTime.Kind == DateTimeKind.Unspecified
== 要突出显示的其他场景
这只是简单的时间跨度添加,从一个明确的 UTC 日期开始,在夏令时结束前 1 分钟。
DateTime dt1 = new DateTime(2012, 03, 31, 15, 59, 0, DateTimeKind.Utc);
DateTime dt2 = new DateTime(2012, 03, 31, 15, 59, 0, DateTimeKind.Utc).ToLocalTime();
Console.WriteLine("Original in UTC : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt1);
Console.WriteLine("Original in Local : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt1.ToLocalTime());
Console.WriteLine("+ 1 Minute in Local : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt1.AddMinutes(1).ToLocalTime());
Console.WriteLine("+ 1 Minute in UTC : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt1.AddMinutes(1));
Console.WriteLine("=====================================================");
Console.WriteLine("Original in UTC : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt2.ToUniversalTime());
Console.WriteLine("Original in Local : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt2);
Console.WriteLine("+ 1 Minute in Local : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt2.AddMinutes(1));
Console.WriteLine("+ 1 Minute in UTC : {0:yyyy-MMM-dd HH:mm:ss.ffff K}", dt2.AddMinutes(1).ToUniversalTime());
给予
UTC 原文:2012-Mar-31 15:59:00.0000 Z
本地原文:2012-Apr-01 02:59:00.0000 +11:00
+ 本地 1 分钟:2012 年 4 月 1 日 02:00:00.0000 +10:00
+ UTC 1 分钟:2012 年 3 月 31 日 16:00:00.0000 Z
================================================ ======
UTC 原文:2012-Mar-31 15:59:00.0000 Z
本地原文:2012-Apr-01 02:59:00.0000 +11:00
+ 本地 1 分钟:2012 年 4 月 1 日 03:00:00.0000 +10:00
+ UTC 1 分钟:2012 年 3 月 31 日 17:00:00.0000 Z
【问题讨论】:
-
DateTime 不会“保留”本地偏移量。我只是显示了当时有效的偏移量。由于 dt2 始终是本地时间,因此它对当前时间的看法是“真实的”。如果您想携带“应用时”偏移量msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx,则应该使用 DateTimeOffset
-
... 如果这是真的,那么我预计最后一个场景中 dt2 的第三个结果是 03:00:00 +11:00,但它知道 DST 已经结束。它正确切换到 +10:00,但没有起飞。 DateTimeOffset 显示时间为 03:00:00 +11:00,这对我的本地时区无效。
-
不,它知道您说这是 2012 年 4 月 1 日的 3:00,所以当时的偏移量是 +10:00
-
我从没说过是 03:00 +10,我在 2:59 +11 加了 1 分钟。它应该导致 02:00 +10 该日期的 DateTime.Kind 属性是 Local
-
@RobertSlaney:这就是问题所在 - 它正在进行局部算术。当你有一个本地的 DateTimeKind 时,它不会考虑任何 DST;您没有添加“经过”时间,您只是添加到本地时间。