简体   繁体   中英

Grey zone of DST

does anybody knows how to handle grey zones of DST (when time doesn't exist): eg:

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

gives an error,when

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

gives 1:30 and then 3:30.

Thanks

Use Noda Time :)

That doesn't relieve you from the burden of thinking how you want to handle this - but it allows you to specify how you want to handle it. Fundamentally, you've been given a value that doesn't exist... so you can choose to throw an error, or maybe take the start of the transition, or the end of the transition, or some custom behaviour:

For example, the "lenient" resolver will return the end of the transition:

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)
    }
}

Or you could use a built-in resolver to return "just before" the transition:

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)
    }
}

Or you can build your own resolver (they're just delegates).

Fundamentally it's up to your application to work out how it needs to handle this. There's no one-size-fits-all answer, and you can't easily avoid losing data here. (Well, not without building your own data structure specifically to remember the original local date/time.)

I found a way of handling this grey zones by .net facilities

    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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM