@@ -358,12 +358,11 @@ fn resolve_posix_tz_string_for_epoch_seconds(
358358 // TODO: Resolve safety issue around utils.
359359 // Using f64 is a hold over from early implementation days and should
360360 // be moved away from.
361+ let epoch = utils:: Epoch :: from_seconds ( seconds) ;
361362
362- let ( is_transition_day, transition) =
363- cmp_seconds_to_transitions ( & start. day , & end. day , seconds) ?;
363+ let ( is_transition_day, transition) = cmp_seconds_to_transitions ( & start. day , & end. day , epoch) ?;
364364
365- let transition =
366- compute_tz_for_epoch_seconds ( is_transition_day, transition, seconds, dst_variant) ;
365+ let transition = compute_tz_for_epoch ( is_transition_day, transition, epoch, dst_variant) ;
367366 let std_offset = LocalTimeRecord :: from_standard_time ( & posix_tz_string. std_info ) . offset ;
368367 let dst_offset = LocalTimeRecord :: from_daylight_savings_time ( & dst_variant. variant_info ) . offset ;
369368 let ( old_offset, new_offset) = match transition {
@@ -374,23 +373,20 @@ fn resolve_posix_tz_string_for_epoch_seconds(
374373 TransitionType :: Dst => start,
375374 TransitionType :: Std => end,
376375 } ;
377- let year = utils:: epoch_time_to_epoch_year ( seconds * 1000 ) ;
378- let year_epoch = utils:: epoch_days_for_year ( year) * 86400 ;
379- let leap_day = utils:: mathematical_in_leap_year ( seconds * 1000 ) as u16 ;
376+ let year_epoch = epoch. year ( ) * 86400 ;
377+ let leap_day = epoch. in_leap_year ( ) ;
380378
381379 let days = match transition. day {
382- TransitionDay :: NoLeap ( day) if day > 59 => day - 1 + leap_day,
380+ TransitionDay :: NoLeap ( day) if day > 59 => day - 1 + u16 :: from ( leap_day) ,
383381 TransitionDay :: NoLeap ( day) => day - 1 ,
384382 TransitionDay :: WithLeap ( day) => day,
385383 TransitionDay :: Mwd ( month, week, day) => {
386- let days_to_month = utils:: month_to_day ( ( month - 1 ) as u8 , leap_day) ;
387- let days_in_month = u16:: from ( utils:: iso_days_in_month ( year, month as u8 ) - 1 ) ;
384+ let transition_epoch = utils:: Epoch :: from_gregorian_date ( year_epoch, month as u8 , 1 ) ;
385+ let days_to_month = transition_epoch. day_of_year_until_start_of_month ( ) ;
386+ let days_in_month = u16:: from ( transition_epoch. days_in_month ( ) ) ;
388387
389388 // Month starts in the day...
390- let day_offset =
391- ( u16:: from ( utils:: epoch_seconds_to_day_of_week ( i64:: from ( year_epoch) ) )
392- + days_to_month)
393- . rem_euclid ( 7 ) ;
389+ let day_offset = ( u16:: from ( epoch. day_in_week ( ) ) + days_to_month) . rem_euclid ( 7 ) ;
394390
395391 // EXAMPLE:
396392 //
@@ -456,10 +452,11 @@ fn resolve_posix_tz_string(
456452 // NOTE:
457453 // STD -> DST == start
458454 // DST -> STD == end
455+ let epoch = utils:: Epoch :: from_seconds ( seconds) ;
459456 let ( is_transition_day, is_dst) =
460- cmp_seconds_to_transitions ( & dst. start_date . day , & dst. end_date . day , seconds ) ?;
457+ cmp_seconds_to_transitions ( & dst. start_date . day , & dst. end_date . day , epoch ) ?;
461458 if is_transition_day {
462- let time = utils :: epoch_ms_to_ms_in_day ( seconds * 1_000 ) as i64 / 1_000 ;
459+ let time = epoch . millis_since_start_of_day ( ) as i64 / 1_000 ;
463460 let transition_time = if is_dst == TransitionType :: Dst {
464461 dst. start_date . time . 0
465462 } else {
@@ -493,20 +490,19 @@ fn resolve_posix_tz_string(
493490 }
494491}
495492
496- fn compute_tz_for_epoch_seconds (
493+ fn compute_tz_for_epoch (
497494 is_transition_day : bool ,
498495 transition : TransitionType ,
499- seconds : i64 ,
496+ epoch : utils :: Epoch ,
500497 dst_variant : & DstTransitionInfo ,
501498) -> TransitionType {
499+ let time = epoch. millis_since_start_of_day ( ) / 1000 ;
502500 if is_transition_day && transition == TransitionType :: Dst {
503- let time = utils:: epoch_ms_to_ms_in_day ( seconds * 1_000 ) / 1_000 ;
504501 let transition_time = dst_variant. start_date . time . 0 - dst_variant. variant_info . offset . 0 ;
505502 if i64:: from ( time) < transition_time {
506503 return TransitionType :: Std ;
507504 }
508505 } else if is_transition_day {
509- let time = utils:: epoch_ms_to_ms_in_day ( seconds * 1_000 ) / 1_000 ;
510506 let transition_time = dst_variant. end_date . time . 0 - dst_variant. variant_info . offset . 0 ;
511507 if i64:: from ( time) < transition_time {
512508 return TransitionType :: Dst ;
@@ -523,26 +519,26 @@ fn compute_tz_for_epoch_seconds(
523519struct Mwd ( u16 , u16 , u16 ) ;
524520
525521impl Mwd {
526- fn from_seconds ( seconds : i64 ) -> Self {
527- let month = utils :: epoch_ms_to_month_in_year ( seconds * 1_000 ) as u16 ;
528- let day_of_month = utils :: epoch_seconds_to_day_of_month ( seconds ) ;
522+ fn from_epoch ( epoch : utils :: Epoch ) -> Self {
523+ let month = epoch . month_in_year ( ) ;
524+ let day_of_month = epoch . day_of_month ( ) ;
529525 let week_of_month = day_of_month / 7 + 1 ;
530- let day_of_week = utils :: epoch_seconds_to_day_of_week ( seconds ) ;
531- Self ( month, week_of_month, u16:: from ( day_of_week ) )
526+ let day_in_week = epoch . day_in_week ( ) ;
527+ Self ( u16 :: from ( month) , week_of_month, u16:: from ( day_in_week ) )
532528 }
533529}
534530
535531fn cmp_seconds_to_transitions (
536532 start : & TransitionDay ,
537533 end : & TransitionDay ,
538- seconds : i64 ,
534+ epoch : utils :: Epoch ,
539535) -> TemporalResult < ( bool , TransitionType ) > {
540536 let cmp_result = match ( start, end) {
541537 (
542538 TransitionDay :: Mwd ( start_month, start_week, start_day) ,
543539 TransitionDay :: Mwd ( end_month, end_week, end_day) ,
544540 ) => {
545- let mwd = Mwd :: from_seconds ( seconds ) ;
541+ let mwd = Mwd :: from_epoch ( epoch ) ;
546542 let start = Mwd ( * start_month, * start_week, * start_day) ;
547543 let end = Mwd ( * end_month, * end_week, * end_day) ;
548544
@@ -556,7 +552,7 @@ fn cmp_seconds_to_transitions(
556552 ( is_transition, is_dst)
557553 }
558554 ( TransitionDay :: WithLeap ( start) , TransitionDay :: WithLeap ( end) ) => {
559- let day_in_year = utils :: epoch_time_to_day_in_year ( seconds * 1_000 ) as u16 ;
555+ let day_in_year = epoch . days_in_year ( ) ;
560556 let is_transition = * start == day_in_year || * end == day_in_year;
561557 let is_dst = if start > end {
562558 day_in_year < * end || * start <= day_in_year
@@ -567,7 +563,7 @@ fn cmp_seconds_to_transitions(
567563 }
568564 // TODO: do we need to modify the logic for leap years?
569565 ( TransitionDay :: NoLeap ( start) , TransitionDay :: NoLeap ( end) ) => {
570- let day_in_year = utils :: epoch_time_to_day_in_year ( seconds * 1_000 ) as u16 ;
566+ let day_in_year = epoch . days_in_year ( ) ;
571567 let is_transition = * start == day_in_year || * end == day_in_year;
572568 let is_dst = if start > end {
573569 day_in_year < * end || * start <= day_in_year
@@ -1082,10 +1078,7 @@ mod tests {
10821078 }
10831079
10841080 #[ test]
1085- fn mwd_transition_epoch ( ) {
1086- #[ cfg( not( target_os = "windows" ) ) ]
1087- let tzif = Tzif :: read_tzif ( "Europe/Berlin" ) . unwrap ( ) ;
1088- #[ cfg( target_os = "windows" ) ]
1081+ fn mwd_transition_epoch_with_slim_format ( ) {
10891082 let tzif = Tzif :: from_bytes ( jiff_tzdb:: get ( "Europe/Berlin" ) . unwrap ( ) . 1 ) . unwrap ( ) ;
10901083
10911084 let start_date = crate :: iso:: IsoDate {
0 commit comments