@@ -54,8 +54,11 @@ public static string MapTimeZoneId (string id)
5454 return "New Zealand Standard Time" ;
5555 case "Europe/Athens" :
5656 return "GTB Standard Time" ;
57+ case "Europe/Chisinau" :
58+ return "E. Europe Standard Time" ;
5759 case "US/Eastern" :
5860 return "Eastern Standard Time" ;
61+ case "America/Chicago" :
5962 case "US/Central" :
6063 return "Central Standard Time" ;
6164 case "US/Pacific" :
@@ -64,18 +67,57 @@ public static string MapTimeZoneId (string id)
6467 case "Australia/Melbourne" :
6568 return "AUS Eastern Standard Time" ;
6669 case "Europe/Brussels" :
70+ case "Europe/Copenhagen" :
71+ case "Europe/Paris" :
72+ case "Europe/Madrid" :
6773 return "Romance Standard Time" ;
6874 case "Africa/Kinshasa" :
6975 return "W. Central Africa Standard Time" ;
7076 case "Europe/Rome" :
7177 case "Europe/Vatican" :
78+ case "Europe/Vienna" :
79+ case "Europe/Berlin" :
80+ case "Europe/Luxembourg" :
81+ case "Europe/Malta" :
82+ case "Europe/Monaco" :
83+ case "Europe/Amsterdam" :
84+ case "Europe/Oslo" :
85+ case "Europe/San_Marino" :
7286 return "W. Europe Standard Time" ;
7387 case "Canada/Eastern" :
7488 return "Eastern Standard Time" ;
7589 case "Asia/Tehran" :
7690 return "Iran Standard Time" ;
7791 case "Europe/Guernsey" :
92+ case "Europe/Dublin" :
93+ case "Europe/Isle_of_Man" :
94+ case "Europe/Jersey" :
95+ case "Europe/Lisbon" :
96+ case "Europe/London" :
7897 return "GMT Standard Time" ;
98+ case "America/Havana" :
99+ return "Cuba Standard Time" ;
100+ case "America/Anchorage" :
101+ return "Alaskan Standard Time" ;
102+ case "Atlantic/Azores" :
103+ return "Azores Standard Time" ;
104+ case "Asia/Jerusalem" :
105+ return "Israel Standard Time" ;
106+ case "Asia/Amman" :
107+ return "Jordan Standard Time" ;
108+ case "Europe/Tirane" :
109+ case "Europe/Warsaw" :
110+ return "Central European Standard Time" ;
111+ case "Europe/Sofia" :
112+ case "Europe/Tallinn" :
113+ case "Europe/Riga" :
114+ case "Europe/Vilnius" :
115+ case "Europe/Kiev" :
116+ return "FLE Standard Time" ;
117+ case "Europe/Prague" :
118+ case "Europe/Budapest" :
119+ case "Europe/Bratislava" :
120+ return "Central Europe Standard Time" ;
79121 default :
80122 Assert . Fail ( $ "No mapping defined for zone id '{ id } '") ;
81123 return null ;
@@ -482,6 +524,218 @@ public void Bug_9664 ()
482524 Assert . AreEqual ( new TimeSpan ( 0 , 0 , 0 ) , tzi . GetUtcOffset ( date ) ) ;
483525#endif
484526 }
527+
528+ [ Test ]
529+ public void Bug_16395 ( )
530+ {
531+ // Cuba, Havana (Cuba Standard Time): Jumps ahead at 12:00 AM on 3/8/2020 to 1:00 AM
532+ CheckJumpingIntoDST ( "America/Havana" ,
533+ new DateTime ( 2020 , 3 , 8 , 0 , 0 , 0 ) , new DateTime ( 2020 , 3 , 8 , 0 , 30 , 0 ) , new DateTime ( 2020 , 3 , 8 , 1 , 0 , 0 ) ,
534+ new TimeSpan ( - 5 , 0 , 0 ) , new TimeSpan ( - 4 , 0 , 0 ) ) ;
535+
536+ // US, Kansas City, MO (US Central Time): Jumps ahead at 2:00 AM on 3/8/2020 to 3:00 AM
537+ CheckJumpingIntoDST ( "America/Chicago" ,
538+ new DateTime ( 2020 , 3 , 8 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 8 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 8 , 3 , 0 , 0 ) ,
539+ new TimeSpan ( - 6 , 0 , 0 ) , new TimeSpan ( - 5 , 0 , 0 ) ) ;
540+
541+ // Anchorage, AK (Alaska Time): Jumps ahead at 2:00 AM on 3/8/2020 to 3:00 AM
542+ CheckJumpingIntoDST ( "America/Anchorage" ,
543+ new DateTime ( 2020 , 3 , 8 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 8 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 8 , 3 , 0 , 0 ) ,
544+ new TimeSpan ( - 9 , 0 , 0 ) , new TimeSpan ( - 8 , 0 , 0 ) ) ;
545+
546+ // Azores ST (Ponta Delgada, Portugal): Jumps ahead at 12:00 AM on 3/29/2020 to 1:00 AM
547+ CheckJumpingIntoDST ( "Atlantic/Azores" ,
548+ new DateTime ( 2020 , 3 , 29 , 0 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 0 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 1 , 0 , 0 ) ,
549+ new TimeSpan ( - 1 , 0 , 0 ) , new TimeSpan ( 0 , 0 , 0 ) ) ;
550+
551+ // Iran, Tehran (Iran ST): Jumps ahead at 12:00 AM on 3/21/2020 to 1:00 AM
552+ CheckJumpingIntoDST ( "Asia/Tehran" ,
553+ new DateTime ( 2020 , 3 , 21 , 0 , 0 , 0 ) , new DateTime ( 2020 , 3 , 21 , 0 , 30 , 0 ) , new DateTime ( 2020 , 3 , 21 , 1 , 0 , 0 ) ,
554+ new TimeSpan ( 3 , 30 , 0 ) , new TimeSpan ( 4 , 30 , 0 ) ) ;
555+
556+ // Israel, Jerusalem (Israel ST): Jumps ahead at 2:00 AM on 3/27/2020 to 3:00 AM
557+ CheckJumpingIntoDST ( "Asia/Jerusalem" ,
558+ new DateTime ( 2020 , 3 , 27 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 27 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 27 , 3 , 0 , 0 ) ,
559+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
560+
561+ // Jordan, Amman (Eastern European ST): Jumps ahead at 12:00 AM on 3/27/2020 to 1:00 AM
562+ CheckJumpingIntoDST ( "Asia/Amman" ,
563+ new DateTime ( 2020 , 3 , 27 , 0 , 0 , 0 ) , new DateTime ( 2020 , 3 , 27 , 0 , 30 , 0 ) , new DateTime ( 2020 , 3 , 27 , 1 , 0 , 0 ) ,
564+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
565+
566+ // Albania, Tirana (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
567+ CheckJumpingIntoDST ( "Europe/Tirane" ,
568+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
569+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
570+
571+ // Austria, Vienna (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
572+ CheckJumpingIntoDST ( "Europe/Vienna" ,
573+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
574+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
575+
576+ // Belgium, Brussels (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
577+ CheckJumpingIntoDST ( "Europe/Brussels" ,
578+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
579+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
580+
581+ // Bulgaria, Sofia (Eastern European ST): Jumps ahead at 3:00 AM on 3/29/2020 to 4:00 AM
582+ CheckJumpingIntoDST ( "Europe/Sofia" ,
583+ new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 4 , 0 , 0 ) ,
584+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
585+
586+ // Czechia, Prague (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
587+ CheckJumpingIntoDST ( "Europe/Prague" ,
588+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
589+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
590+
591+ // Denmark, Copenhagen (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
592+ CheckJumpingIntoDST ( "Europe/Copenhagen" ,
593+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
594+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
595+
596+ // Estonia, Tallinn (Eastern European ST): Jumps ahead at 3:00 AM on 3/29/2020 to 4:00 AM
597+ CheckJumpingIntoDST ( "Europe/Tallinn" ,
598+ new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 4 , 0 , 0 ) ,
599+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
600+
601+ // France, Paris (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
602+ CheckJumpingIntoDST ( "Europe/Paris" ,
603+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
604+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
605+
606+ // Germany, Berlin (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
607+ CheckJumpingIntoDST ( "Europe/Berlin" ,
608+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
609+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
610+
611+ // Greece, Athens (Eastern European ST): Jumps ahead at 3:00 AM on 3/29/2020 to 4:00 AM
612+ CheckJumpingIntoDST ( "Europe/Athens" ,
613+ new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 4 , 0 , 0 ) ,
614+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
615+
616+ // Guernsey (UK) Jumps ahead at 1:00 AM on 3/29/2020 to 2:00 AM
617+ CheckJumpingIntoDST ( "Europe/Guernsey" ,
618+ new DateTime ( 2020 , 3 , 29 , 1 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 1 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) ,
619+ new TimeSpan ( 0 , 0 , 0 ) , new TimeSpan ( 1 , 0 , 0 ) ) ;
620+
621+ // Holy See, Vatican City (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
622+ CheckJumpingIntoDST ( "Europe/Vatican" ,
623+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
624+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
625+
626+ // Hungary, Budapest (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
627+ CheckJumpingIntoDST ( "Europe/Budapest" ,
628+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
629+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
630+
631+ // // Ireland, Dublin (Greenwich Mean Time -> Irish Standard Time): Jumps ahead at 1:00 AM on 3/29/2020 to 2:00 AM
632+ // CheckJumpingIntoDST ("Europe/Dublin",
633+ // new DateTime (2020, 3, 29, 1, 0, 0), new DateTime (2020, 3, 29, 1, 30, 0), new DateTime (2020, 3, 29, 2, 0, 0),
634+ // new TimeSpan (0, 0, 0), new TimeSpan (1, 0, 0));
635+
636+ // UK, Douglas, Isle of Man (GMT+1:00): Jumps ahead at 1:00 AM on 3/29/2020 to 2:00 AM
637+ CheckJumpingIntoDST ( "Europe/Isle_of_Man" ,
638+ new DateTime ( 2020 , 3 , 29 , 1 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 1 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) ,
639+ new TimeSpan ( 0 , 0 , 0 ) , new TimeSpan ( 1 , 0 , 0 ) ) ;
640+
641+ // Italy, Rome (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
642+ CheckJumpingIntoDST ( "Europe/Rome" ,
643+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
644+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
645+
646+ // Jersey (UK): Jumps ahead at 1:00 AM on 3/29/2020 to 2:00 AM
647+ CheckJumpingIntoDST ( "Europe/Jersey" ,
648+ new DateTime ( 2020 , 3 , 29 , 1 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 1 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) ,
649+ new TimeSpan ( 0 , 0 , 0 ) , new TimeSpan ( 1 , 0 , 0 ) ) ;
650+
651+ // Latvia, Riga (Eastern European ST): Jumps ahead at 3:00 AM on 3/29/2020 to 4:00 AM
652+ CheckJumpingIntoDST ( "Europe/Riga" ,
653+ new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 4 , 0 , 0 ) ,
654+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
655+
656+ // Lithuania, Vilnius (Eastern European ST): Jumps ahead at 3:00 AM on 3/29/2020 to 4:00 AM
657+ CheckJumpingIntoDST ( "Europe/Vilnius" ,
658+ new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 4 , 0 , 0 ) ,
659+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
660+
661+ // Luxembourg, Luxembourg (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
662+ CheckJumpingIntoDST ( "Europe/Luxembourg" ,
663+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
664+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
665+
666+ // Malta, Valletta (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
667+ CheckJumpingIntoDST ( "Europe/Malta" ,
668+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
669+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
670+
671+ // Moldova, Chişinău (Eastern European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
672+ CheckJumpingIntoDST ( "Europe/Chisinau" ,
673+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
674+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
675+
676+ // Monaco, Monaco (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
677+ CheckJumpingIntoDST ( "Europe/Monaco" ,
678+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
679+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
680+
681+ // Netherlands, Amsterdam (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
682+ CheckJumpingIntoDST ( "Europe/Amsterdam" ,
683+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
684+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
685+
686+ // Norway, Oslo (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
687+ CheckJumpingIntoDST ( "Europe/Oslo" ,
688+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
689+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
690+
691+ // Poland, Warsaw (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
692+ CheckJumpingIntoDST ( "Europe/Warsaw" ,
693+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
694+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
695+
696+ // Portugal, Lisbon (Western European ST): Jumps ahead at 1:00 AM on 3/29/2020 to 2:00 AM
697+ CheckJumpingIntoDST ( "Europe/Lisbon" ,
698+ new DateTime ( 2020 , 3 , 29 , 1 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 1 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) ,
699+ new TimeSpan ( 0 , 0 , 0 ) , new TimeSpan ( 1 , 0 , 0 ) ) ;
700+
701+ // San Marino, San Marino (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
702+ CheckJumpingIntoDST ( "Europe/San_Marino" ,
703+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
704+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
705+
706+ // Slovakia, Bratislava (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
707+ CheckJumpingIntoDST ( "Europe/Bratislava" ,
708+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
709+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
710+
711+ // Spain, Madrid (Central European ST): Jumps ahead at 2:00 AM on 3/29/2020 to 3:00 AM
712+ CheckJumpingIntoDST ( "Europe/Madrid" ,
713+ new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) ,
714+ new TimeSpan ( 1 , 0 , 0 ) , new TimeSpan ( 2 , 0 , 0 ) ) ;
715+
716+ // Ukraine, Kiev (Eastern European ST): Jumps ahead at 3:00 AM on 3/29/2020 to 4:00 AM
717+ CheckJumpingIntoDST ( "Europe/Kiev" ,
718+ new DateTime ( 2020 , 3 , 29 , 3 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 3 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 4 , 0 , 0 ) ,
719+ new TimeSpan ( 2 , 0 , 0 ) , new TimeSpan ( 3 , 0 , 0 ) ) ;
720+
721+ // United Kingdom, London (British ST): Jumps ahead at 1:00 AM on 3/29/2020 to 2:00 AM
722+ CheckJumpingIntoDST ( "Europe/London" ,
723+ new DateTime ( 2020 , 3 , 29 , 1 , 0 , 0 ) , new DateTime ( 2020 , 3 , 29 , 1 , 30 , 0 ) , new DateTime ( 2020 , 3 , 29 , 2 , 0 , 0 ) ,
724+ new TimeSpan ( 0 , 0 , 0 ) , new TimeSpan ( 1 , 0 , 0 ) ) ;
725+ }
726+
727+ void CheckJumpingIntoDST ( string tzId , DateTime dstDeltaStart , DateTime inDstDelta , DateTime dstDeltaEnd , TimeSpan baseOffset , TimeSpan dstOffset )
728+ {
729+ var tzi = TimeZoneInfo . FindSystemTimeZoneById ( MapTimeZoneId ( tzId ) ) ;
730+ Assert . IsFalse ( tzi . IsDaylightSavingTime ( dstDeltaStart ) , $ "{ tzId } : #1") ;
731+ Assert . AreEqual ( baseOffset , tzi . GetUtcOffset ( dstDeltaStart ) , $ "{ tzId } : #2") ;
732+
733+ Assert . IsFalse ( tzi . IsDaylightSavingTime ( inDstDelta ) , $ "{ tzId } : #3") ;
734+ Assert . AreEqual ( baseOffset , tzi . GetUtcOffset ( inDstDelta ) , $ "{ tzId } : #4") ;
735+
736+ Assert . IsTrue ( tzi . IsDaylightSavingTime ( dstDeltaEnd ) , $ "{ tzId } : #5") ;
737+ Assert . AreEqual ( dstOffset , tzi . GetUtcOffset ( dstDeltaEnd ) , $ "{ tzId } : #6") ;
738+ }
485739 }
486740
487741 [ TestFixture ]
0 commit comments