@@ -24,7 +24,7 @@ use crate::format::{Item, Numeric, Pad};
24
24
use crate :: month:: Months ;
25
25
use crate :: naive:: { IsoWeek , NaiveDateTime , NaiveTime } ;
26
26
use crate :: oldtime:: Duration as OldDuration ;
27
- use crate :: { Datelike , Duration , Weekday } ;
27
+ use crate :: { Datelike , Weekday } ;
28
28
29
29
use super :: internals:: { self , DateImpl , Mdf , Of , YearFlags } ;
30
30
use super :: isoweek;
@@ -77,10 +77,10 @@ impl NaiveWeek {
77
77
#[ inline]
78
78
#[ must_use]
79
79
pub fn first_day ( & self ) -> NaiveDate {
80
- let start = self . start . num_days_from_monday ( ) ;
81
- let end = self . date . weekday ( ) . num_days_from_monday ( ) ;
82
- let days = if start > end { 7 - start + end } else { end - start } ;
83
- self . date - Duration :: days ( days. into ( ) )
80
+ let start = self . start . num_days_from_monday ( ) as i32 ;
81
+ let ref_day = self . date . weekday ( ) . num_days_from_monday ( ) as i32 ;
82
+ let days = if start > ref_day { start - ref_day - 7 } else { start - ref_day } ;
83
+ self . date . add_days ( days, false ) . unwrap ( )
84
84
}
85
85
86
86
/// Returns a date representing the last day of the week.
@@ -97,7 +97,10 @@ impl NaiveWeek {
97
97
#[ inline]
98
98
#[ must_use]
99
99
pub fn last_day ( & self ) -> NaiveDate {
100
- self . first_day ( ) + Duration :: days ( 6 )
100
+ let end = self . start . pred ( ) . num_days_from_monday ( ) as i32 ;
101
+ let ref_day = self . date . weekday ( ) . num_days_from_monday ( ) as i32 ;
102
+ let days = if end < ref_day { end - ref_day + 7 } else { end - ref_day } ;
103
+ self . date . add_days ( days, false ) . unwrap ( )
101
104
}
102
105
103
106
/// Returns a [`RangeInclusive<T>`] representing the whole week bounded by
@@ -2965,23 +2968,31 @@ mod tests {
2965
2968
fn test_naiveweek ( ) {
2966
2969
let date = NaiveDate :: from_ymd_opt ( 2022 , 5 , 18 ) . unwrap ( ) ;
2967
2970
let asserts = vec ! [
2968
- ( Weekday :: Mon , "2022-05-16" , "2022-05-22" ) ,
2969
- ( Weekday :: Tue , "2022-05-17" , "2022-05-23" ) ,
2970
- ( Weekday :: Wed , "2022-05-18" , "2022-05-24" ) ,
2971
- ( Weekday :: Thu , "2022-05-12" , "2022-05-18" ) ,
2972
- ( Weekday :: Fri , "2022-05-13" , "2022-05-19" ) ,
2973
- ( Weekday :: Sat , "2022-05-14" , "2022-05-20" ) ,
2974
- ( Weekday :: Sun , "2022-05-15" , "2022-05-21" ) ,
2971
+ ( Weekday :: Mon , "Mon 2022-05-16" , "Sun 2022-05-22" ) ,
2972
+ ( Weekday :: Tue , "Tue 2022-05-17" , "Mon 2022-05-23" ) ,
2973
+ ( Weekday :: Wed , "Wed 2022-05-18" , "Tue 2022-05-24" ) ,
2974
+ ( Weekday :: Thu , "Thu 2022-05-12" , "Wed 2022-05-18" ) ,
2975
+ ( Weekday :: Fri , "Fri 2022-05-13" , "Thu 2022-05-19" ) ,
2976
+ ( Weekday :: Sat , "Sat 2022-05-14" , "Fri 2022-05-20" ) ,
2977
+ ( Weekday :: Sun , "Sun 2022-05-15" , "Sat 2022-05-21" ) ,
2975
2978
] ;
2976
2979
for ( start, first_day, last_day) in asserts {
2977
2980
let week = date. week ( start) ;
2978
2981
let days = week. days ( ) ;
2979
- assert_eq ! ( Ok ( week. first_day( ) ) , NaiveDate :: parse_from_str( first_day, "%Y-%m-%d" ) ) ;
2980
- assert_eq ! ( Ok ( week. last_day( ) ) , NaiveDate :: parse_from_str( last_day, "%Y-%m-%d" ) ) ;
2982
+ assert_eq ! ( Ok ( week. first_day( ) ) , NaiveDate :: parse_from_str( first_day, "%a % Y-%m-%d" ) ) ;
2983
+ assert_eq ! ( Ok ( week. last_day( ) ) , NaiveDate :: parse_from_str( last_day, "%a % Y-%m-%d" ) ) ;
2981
2984
assert ! ( days. contains( & date) ) ;
2982
2985
}
2983
2986
}
2984
2987
2988
+ #[ test]
2989
+ fn test_naiveweek_min_max ( ) {
2990
+ let date_max = NaiveDate :: MAX ;
2991
+ assert ! ( date_max. week( Weekday :: Mon ) . first_day( ) <= date_max) ;
2992
+ let date_min = NaiveDate :: MIN ;
2993
+ assert ! ( date_min. week( Weekday :: Mon ) . last_day( ) >= date_min) ;
2994
+ }
2995
+
2985
2996
#[ test]
2986
2997
fn test_weeks_from ( ) {
2987
2998
// tests per: https://github.com/chronotope/chrono/issues/961
0 commit comments