模糊DateTimeOffset的示例

时间:2016-01-13 14:27:28

标签: c# dst timezone-offset datetimeoffset

我们在数据库/模型中有DateTimeOffsets。要在Web中显示这些值,我们将DateTimeOffsets转换为当前用户的时区。

根据MSDN,DateTimeOffset在特定的TimeZone中可能不明确:

TimeZoneInfo.IsAmbiguousTime Method (DateTimeOffset)

这对我来说根本没有意义。有人可以给我一个不明确的 示例DateTimeOffset 吗? 我们在TimeZone" W。欧洲标准时间"。

3 个答案:

答案 0 :(得分:3)

文档中说的不清楚吗?

  

通常,当时钟设置为从夏令时返回标准时间时会产生模糊时间

即。如果凌晨2点你从DST上来并将时钟重置为凌晨1点,那么如果有人在凌晨1点30分开始谈论,你就不知道现在是30分钟还是过去30分钟。 / p>

有一组值(通常为一小时),它们以UTC时间映射到两组不同的时刻。

答案 1 :(得分:2)

样本是(去年十月&周日2:00-3:00

function countArrayKeysNumeric($array)
{
    $count = 0;
    $keys = array_keys($array);
    foreach ($keys as $key) $count += is_numeric($key) ? 1 :0;
    return $count;
}

$array = [
    1=>"one",
    "two"=>"two",
    3=>[
        1=>1,
        "two"=>2
    ]
];

print countArrayKeysNumeric($array);

不明确的时间相反无效时间(去年3月及周日2:00-3:00):

DateTimeOffset example = new DateTimeOffset(2015, 10, 25, 2, 30, 0, 
  new TimeSpan(0, 2, 0, 0));

TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");

if (tst.IsAmbiguousTime(example))
  Console.Write("Ambiguous time");

答案 2 :(得分:1)

我认为混淆来自于这里定义“含糊不清”的方式。

要清楚,DateTimeOffset永远不会模棱两可。 始终表示绝对瞬时的特定时刻。给定日期,时间和偏移量,我可以告诉您当地的壁垒时间和精确的UTC时间(通过应用偏移量)。

但是,值的挂壁时间部分在特定时区内可能不明确。也就是说,当您忽略偏移时,日期和时间仅为。这就是TimeZoneInfo.IsAmbiguousTime告诉你的。那个如果它不是用于偏移,那么该值将是不明确的。壁挂时间可能是那个时区的人可能会感到困惑的时间。

请注意,此方法有两个重载,一个采用DateTime,另一个采用DateTimeOffset

  • DateTime.Kind时,DateTimeKind.Unspecified一个很有意义。

    DateTime dt = new DateTime(2016, 10, 30, 2, 0, 0);
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
    bool ambiguous = tz.IsAmbiguousTime(dt);  // true
    
  • 与其他类型相比,它的含义更少,因为它首先会转换到给定的时区 - 但它仍然会做同样的事情:

    DateTime dt = new DateTime(2016, 10, 30, 1, 0, 0, DateTimeKind.Utc);
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
    bool ambiguous = tz.IsAmbiguousTime(dt);  // true
    
  • DateTimeOffset重载基本上与前一个示例做同样的事情。无论偏移是什么,它都应用于日期和时间,然后仅在结果日期和时间上检查歧义 - 就像在第一个示例中一样。

    DateTimeOffset dto = new DateTimeOffset(2016, 10, 30, 2, 0, 0, TimeSpan.FromHours(1));
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
    bool ambiguous = tz.IsAmbiguousTime(dto);  // true
    
  • 即使对该时区没有任何意义的偏移,它仍会在比较之前应用。

    DateTimeOffset dto = new DateTimeOffset(2016, 10, 29, 19, 0, 0, TimeSpan.FromHours(-5));
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
    bool ambiguous = tz.IsAmbiguousTime(dto);  // true
    

归结为重载的实现,基本上是:

// Make sure the dto is adjusted to the tz.  This could be a no-op if it already is.
DateTimeOffset adjusted = TimeZoneInfo.ConvertTime(dto, tz);

// Then just get the wall time, stripping away the offset.
// The resulting datetime has unspecified kind.
DateTime dt = adjusted.DateTime;

// Finally, call the datetime version of the function
bool ambiguous = tz.IsAmbiguousTime(dt);

您可以看到此in the .net reference source here。它们将它浓缩为两行,并在DST不适用时以快捷方式为其提供更好的性能,但这就是它的作用。