@@ -96,7 +96,7 @@ public static string asctime(CodeContext/*!*/ context)
9696 => AscTimeFormat ( DateTime . Now ) ;
9797
9898 public static string asctime ( CodeContext /*!*/ context , [ NotNone ] PythonTuple time )
99- => AscTimeFormat ( GetDateTimeFromTupleNoDst ( context , time ) ) ;
99+ => AscTimeFormat ( GetDateTimeFromTuple ( time , out _ ) ) ;
100100
101101 public static double clock ( ) {
102102 InitStopWatch ( ) ;
@@ -163,25 +163,23 @@ public static PythonTuple gmtime(object? seconds) {
163163 }
164164
165165 public static double mktime ( CodeContext /*!*/ context , [ NotNone ] PythonTuple localTime ) {
166- DateTime raw = GetDateTimeFromTupleNoDst ( context , localTime , out int [ ] ? ints ) ;
166+ DateTime raw = GetDateTimeFromTuple ( localTime , out int isDst ) ;
167167 TimeZoneInfo tz = TimeZoneInfo . Local ;
168168 if ( tz . IsAmbiguousTime ( raw ) ) {
169169 // raw occurs twice (once under daylight, once under standard). Resolve directly from the
170170 // ambiguous offset pair rather than going through RemoveDst+GetStandardOffset: raw can sit
171171 // exactly on an AdjustmentRule's date boundary (e.g. a jurisdiction abolishing DST), where
172172 // date-only rule matching can't tell which side of the transition the shifted result landed on.
173- bool preferDaylight = ints is null || ints [ IsDaylightSavingsIndex ] != 0 ;
173+ bool preferDaylight = isDst != 0 ;
174174 var offsets = tz . GetAmbiguousTimeOffsets ( raw ) ;
175175 return TicksToTimestamp ( ( raw - ( preferDaylight ? offsets . Max ( ) : offsets . Min ( ) ) ) . Ticks ) ;
176176 }
177177
178- DateTime res = raw ;
179- if ( ints != null ) {
180- switch ( ints [ IsDaylightSavingsIndex ] ) {
181- case - 1 : res = RemoveDst ( raw ) ; break ;
182- case 1 : res = RemoveDst ( raw , true ) ; break ;
183- }
184- }
178+ DateTime res = isDst switch {
179+ 0 => raw ,
180+ < 0 => RemoveDst ( raw ) ,
181+ _ => RemoveDst ( raw , true ) ,
182+ } ;
185183 return TicksToTimestamp ( ( res - GetStandardOffset ( res ) ) . Ticks ) ;
186184 }
187185
@@ -190,7 +188,7 @@ public static string strftime(CodeContext/*!*/ context, [NotNone] string format)
190188 }
191189
192190 public static string strftime ( CodeContext /*!*/ context , [ NotNone ] string format , [ NotNone ] PythonTuple dateTime ) {
193- return strftime ( context , format , GetDateTimeFromTupleNoDst ( context , dateTime ) , null , TimeZoneInfo . Local , errorOnF : true ) ;
191+ return strftime ( context , format , GetDateTimeFromTuple ( dateTime , out _ ) , null , TimeZoneInfo . Local , errorOnF : true ) ;
194192 }
195193
196194 public static object ? strptime ( CodeContext /*!*/ context , [ NotNone ] string @string ) {
@@ -473,46 +471,30 @@ internal static struct_time GetDateTimeTuple(DateTime dt, bool dstMode) {
473471 return new struct_time ( dt . Year , dt . Month , dt . Day , dt . Hour , dt . Minute , dt . Second , Weekday ( dt ) , dt . DayOfYear , dstMode ? 1 : 0 ) ;
474472 }
475473
476- private static DateTime GetDateTimeFromTupleNoDst ( CodeContext context , PythonTuple t ) {
477- return GetDateTimeFromTupleNoDst ( context , t , out _ ) ;
478- }
479-
480- private static DateTime GetDateTimeFromTupleNoDst ( CodeContext context , PythonTuple t , out int [ ] ? ints ) {
481- if ( t == null ) {
482- ints = null ;
483- return DateTime . Now ;
484- }
485-
486- ints = ValidateDateTimeTuple ( context , t ) ;
474+ private static int ToInt32 ( object ? o )
475+ => Converter . TryConvertToIndex ( o , out int i ) ? i : throw PythonOps . TypeErrorForUnIndexableObject ( o ) ;
487476
488- var month = ints [ MonthIndex ] ;
489- if ( month == 0 ) month = 1 ;
490- var day = ints [ DayIndex ] ;
491- if ( day == 0 ) day = 1 ;
492-
493- return new DateTime ( ints [ YearIndex ] , month , day , ints [ HourIndex ] , ints [ MinuteIndex ] , ints [ SecondIndex ] ) ;
494- }
495-
496- private static int [ ] ValidateDateTimeTuple ( CodeContext /*!*/ context , PythonTuple t ) {
477+ private static DateTime GetDateTimeFromTuple ( PythonTuple t , out int isDst ) {
497478 if ( t . __len__ ( ) != MaxIndex ) throw PythonOps . TypeError ( "expected tuple of length {0}" , MaxIndex ) ;
498479
499- int [ ] ints = new int [ MaxIndex ] ;
500- for ( int i = 0 ; i < MaxIndex ; i ++ ) {
501- ints [ i ] = context . LanguageContext . ConvertToInt32 ( t [ i ] ) ;
502- }
480+ var year = ToInt32 ( t [ YearIndex ] ) ;
481+ var month = ToInt32 ( t [ MonthIndex ] ) ;
482+ var day = ToInt32 ( t [ DayIndex ] ) ;
483+ var hour = ToInt32 ( t [ HourIndex ] ) ;
484+ var minute = ToInt32 ( t [ MinuteIndex ] ) ;
485+ var second = ToInt32 ( t [ SecondIndex ] ) ;
486+ var weekday = ToInt32 ( t [ WeekdayIndex ] ) ;
487+ ToInt32 ( t [ DayOfYearIndex ] ) ; // validate
488+ isDst = ToInt32 ( t [ IsDaylightSavingsIndex ] ) ;
503489
504- int year = ints [ YearIndex ] ;
505- if ( year >= 0 && year <= 99 ) {
506- if ( year > 68 ) {
507- year += 1900 ;
508- } else {
509- year += 2000 ;
510- }
511- }
512490 if ( year < DateTime . MinValue . Year ) throw PythonOps . ValueError ( "year is too low" ) ;
513491 if ( year > DateTime . MaxValue . Year ) throw PythonOps . ValueError ( "year is too high" ) ;
514- if ( ints [ WeekdayIndex ] < 0 || ints [ WeekdayIndex ] >= 7 ) throw PythonOps . ValueError ( "day of week is outside of 0-6 range" ) ;
515- return ints ;
492+ if ( weekday < 0 || weekday >= 7 ) throw PythonOps . ValueError ( "day of week is outside of 0-6 range" ) ;
493+
494+ if ( month == 0 ) month = 1 ;
495+ if ( day == 0 ) day = 1 ;
496+
497+ return new DateTime ( year , month , day , hour , minute , second ) ;
516498 }
517499
518500 [ MemberNotNull ( nameof ( sw ) ) ]
0 commit comments