C# Add 1 day in specific TimeZone to DateTimeOffset

后端 未结 1 1569
说谎
说谎 2021-01-16 08:32

I have an instance of DateTimeOffset and I need to add 1 day to it in specific TimeZone (W. Europe Standard Time) taking into account daylight savi

相关标签:
1条回答
  • 2021-01-16 09:18

    TimeZoneInfo makes this reasonably simple - just add a day to the DateTime part of the value, check whether the result is skipped or ambiguous, and if not, ask the zone for the UTC offset. Here's a complete example showing all the different possibilities:

    using System;
    using System.Globalization;
    
    using static System.FormattableString;
    
    class Program
    {
        static void Main()
        {        
            // Stay in winter
            Test("2017-01-22T15:00:00+01:00");
            // Skipped time during transition
            Test("2017-03-25T02:30:00+01:00");
            // Offset change to summer
            Test("2017-03-25T15:00:00+01:00");
            // Stay in summer
            Test("2017-06-22T15:00:00+02:00");
            // Ambiguous time during transition
            Test("2017-10-28T02:30:00+02:00");
            // Offset change back to winter
            Test("2017-10-28T15:00:00+02:00");
            // Stay in winter
            Test("2017-12-22T15:00:00+01:00");
        }
    
        static void Test(string startText)
        {
            var zone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
            var start = DateTimeOffset.ParseExact(
                startText, "yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
            try
            {
                var end = AddOneDay(start, zone);
                Console.WriteLine(Invariant($"{startText} => {end:yyyy-MM-dd'T'HH:mm:ssK}"));
            }
            catch (Exception e)
            {
                Console.WriteLine($"{startText} => {e.Message}");
            }
        }
    
        static DateTimeOffset AddOneDay(DateTimeOffset start, TimeZoneInfo zone)
        {
            var newLocal = start.DateTime.AddDays(1);
            // TODO: Use a better exception type :)
            if (zone.IsAmbiguousTime(newLocal))
            {
                throw new Exception("Ambiguous");
            }
            if (zone.IsInvalidTime(newLocal))
            {
                throw new Exception("Skipped");
            }
            return new DateTimeOffset(newLocal, zone.GetUtcOffset(newLocal));
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题