DST的灰色区域

时间:2014-02-26 20:26:09

标签: c# timezone dst

有人知道如何处理DST的灰色区域(当时间不存在时): e.g:

DateTime dt = new DateTime(2014,3,30,2,30,0);
TimeZoneInfo tziSV = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
DateTime dtSV =TimeZoneInfo.ConvertTimeToUtc(dt,tziSV);

时出现错误

DateTime dt = new DateTime(2014,3,30,2,30,0);
dt = dt.ToUniversalTime();
dt = TimeZoneInfo.ConvertTimeFromUtc(dt,tziSV);

给出1:30然后3:30。

由于

2 个答案:

答案 0 :(得分:4)

使用Noda Time:)

这并不能减轻你思考如何处理这个问题的负担 - 但它允许你指定你想要如何处理它。从根本上说,你已经获得了一个不存在的值...所以你可以选择抛出错误,或者可以选择转换的开始,转换的结束,或者某些自定义行为:

例如,“宽松”解析器将返回转换结束:

using System;
using NodaTime;

class Test
{
    static void Main()
    {
        var local = new LocalDateTime(2014, 3, 30, 2, 30, 0);
        var zone = DateTimeZoneProviders.Tzdb["Europe/Paris"];

        var zoned = local.InZoneLeniently(zone);
        Console.WriteLine(zoned);  // 2014-03-30T03:00:00 Europe/Paris (+02)
    }
}

或者您可以使用内置解析器返回“转换前”:

using System;
using NodaTime;
using NodaTime.TimeZones;

class Test
{
    static void Main()
    {
        var local = new LocalDateTime(2014, 3, 30, 2, 30, 0);
        var zone = DateTimeZoneProviders.Tzdb["Europe/Paris"];

        var resolver = Resolvers.CreateMappingResolver(
              ambiguousTimeResolver: Resolvers.ReturnEarlier,
              skippedTimeResolver: Resolvers.ReturnEndOfIntervalBefore);
        var zoned = local.InZone(zone, resolver);
        Console.WriteLine(zoned); // 2014-03-30T01:59:59 Europe/Paris (+01)
    }
}

或者你可以建立自己的解析器(他们只是代表)。

从根本上说,应由您的应用程序来确定它需要如何处理它。没有一个通用的答案,你不能轻易避免在这里丢失数据。 (好吧,不是没有专门建立自己的数据结构来记住原始的本地日期/时间。)

答案 1 :(得分:0)

我找到了一种通过.net设施处理这个灰色区域的方法

    DateTime dt = new DateTime(2014,3,30,2,30,0);
    TimeZoneInfo tziSV = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");

    if (tziSV.IsInvalidTime(dt))
    {
       dt = dt.Add(tziSV.GetUtcOffset(dt));
    }
    DateTime dtSV = TimeZoneInfo.ConvertTimeToUtc(dt,tziSV);