@@ -358,12 +358,11 @@ fn resolve_posix_tz_string_for_epoch_seconds(
358
358
// TODO: Resolve safety issue around utils.
359
359
// Using f64 is a hold over from early implementation days and should
360
360
// be moved away from.
361
+ let epoch = utils:: Epoch :: from_seconds ( seconds) ;
361
362
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) ?;
364
364
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) ;
367
366
let std_offset = LocalTimeRecord :: from_standard_time ( & posix_tz_string. std_info ) . offset ;
368
367
let dst_offset = LocalTimeRecord :: from_daylight_savings_time ( & dst_variant. variant_info ) . offset ;
369
368
let ( old_offset, new_offset) = match transition {
@@ -374,23 +373,20 @@ fn resolve_posix_tz_string_for_epoch_seconds(
374
373
TransitionType :: Dst => start,
375
374
TransitionType :: Std => end,
376
375
} ;
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 ( ) ;
380
378
381
379
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) ,
383
381
TransitionDay :: NoLeap ( day) => day - 1 ,
384
382
TransitionDay :: WithLeap ( day) => day,
385
383
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 ( ) ) ;
388
387
389
388
// 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 ) ;
394
390
395
391
// EXAMPLE:
396
392
//
@@ -456,10 +452,11 @@ fn resolve_posix_tz_string(
456
452
// NOTE:
457
453
// STD -> DST == start
458
454
// DST -> STD == end
455
+ let epoch = utils:: Epoch :: from_seconds ( seconds) ;
459
456
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 ) ?;
461
458
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 ;
463
460
let transition_time = if is_dst == TransitionType :: Dst {
464
461
dst. start_date . time . 0
465
462
} else {
@@ -493,20 +490,19 @@ fn resolve_posix_tz_string(
493
490
}
494
491
}
495
492
496
- fn compute_tz_for_epoch_seconds (
493
+ fn compute_tz_for_epoch (
497
494
is_transition_day : bool ,
498
495
transition : TransitionType ,
499
- seconds : i64 ,
496
+ epoch : utils :: Epoch ,
500
497
dst_variant : & DstTransitionInfo ,
501
498
) -> TransitionType {
499
+ let time = epoch. millis_since_start_of_day ( ) / 1000 ;
502
500
if is_transition_day && transition == TransitionType :: Dst {
503
- let time = utils:: epoch_ms_to_ms_in_day ( seconds * 1_000 ) / 1_000 ;
504
501
let transition_time = dst_variant. start_date . time . 0 - dst_variant. variant_info . offset . 0 ;
505
502
if i64:: from ( time) < transition_time {
506
503
return TransitionType :: Std ;
507
504
}
508
505
} else if is_transition_day {
509
- let time = utils:: epoch_ms_to_ms_in_day ( seconds * 1_000 ) / 1_000 ;
510
506
let transition_time = dst_variant. end_date . time . 0 - dst_variant. variant_info . offset . 0 ;
511
507
if i64:: from ( time) < transition_time {
512
508
return TransitionType :: Dst ;
@@ -523,26 +519,26 @@ fn compute_tz_for_epoch_seconds(
523
519
struct Mwd ( u16 , u16 , u16 ) ;
524
520
525
521
impl 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 ( ) ;
529
525
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 ) )
532
528
}
533
529
}
534
530
535
531
fn cmp_seconds_to_transitions (
536
532
start : & TransitionDay ,
537
533
end : & TransitionDay ,
538
- seconds : i64 ,
534
+ epoch : utils :: Epoch ,
539
535
) -> TemporalResult < ( bool , TransitionType ) > {
540
536
let cmp_result = match ( start, end) {
541
537
(
542
538
TransitionDay :: Mwd ( start_month, start_week, start_day) ,
543
539
TransitionDay :: Mwd ( end_month, end_week, end_day) ,
544
540
) => {
545
- let mwd = Mwd :: from_seconds ( seconds ) ;
541
+ let mwd = Mwd :: from_epoch ( epoch ) ;
546
542
let start = Mwd ( * start_month, * start_week, * start_day) ;
547
543
let end = Mwd ( * end_month, * end_week, * end_day) ;
548
544
@@ -556,7 +552,7 @@ fn cmp_seconds_to_transitions(
556
552
( is_transition, is_dst)
557
553
}
558
554
( 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 ( ) ;
560
556
let is_transition = * start == day_in_year || * end == day_in_year;
561
557
let is_dst = if start > end {
562
558
day_in_year < * end || * start <= day_in_year
@@ -567,7 +563,7 @@ fn cmp_seconds_to_transitions(
567
563
}
568
564
// TODO: do we need to modify the logic for leap years?
569
565
( 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 ( ) ;
571
567
let is_transition = * start == day_in_year || * end == day_in_year;
572
568
let is_dst = if start > end {
573
569
day_in_year < * end || * start <= day_in_year
@@ -1082,10 +1078,7 @@ mod tests {
1082
1078
}
1083
1079
1084
1080
#[ 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 ( ) {
1089
1082
let tzif = Tzif :: from_bytes ( jiff_tzdb:: get ( "Europe/Berlin" ) . unwrap ( ) . 1 ) . unwrap ( ) ;
1090
1083
1091
1084
let start_date = crate :: iso:: IsoDate {
0 commit comments