@@ -23,7 +23,7 @@ use crate::format::{Item, Numeric, Pad};
2323use crate :: month:: Months ;
2424use crate :: naive:: { IsoWeek , NaiveDateTime , NaiveTime } ;
2525use crate :: oldtime:: Duration as OldDuration ;
26- use crate :: { Datelike , Duration , Weekday } ;
26+ use crate :: { Datelike , Weekday } ;
2727
2828use super :: internals:: { self , DateImpl , Mdf , Of , YearFlags } ;
2929use super :: isoweek;
@@ -76,10 +76,10 @@ impl NaiveWeek {
7676 #[ inline]
7777 #[ must_use]
7878 pub fn first_day ( & self ) -> NaiveDate {
79- let start = self . start . num_days_from_monday ( ) ;
80- let end = self . date . weekday ( ) . num_days_from_monday ( ) ;
81- let days = if start > end { 7 - start + end } else { end - start } ;
82- self . date - Duration :: days ( days. into ( ) )
79+ let start = self . start . num_days_from_monday ( ) as i32 ;
80+ let ref_day = self . date . weekday ( ) . num_days_from_monday ( ) as i32 ;
81+ let days = if start > ref_day { start - ref_day - 7 } else { start - ref_day } ;
82+ self . date . add_days ( days, false ) . unwrap ( )
8383 }
8484
8585 /// Returns a date representing the last day of the week.
@@ -96,7 +96,10 @@ impl NaiveWeek {
9696 #[ inline]
9797 #[ must_use]
9898 pub fn last_day ( & self ) -> NaiveDate {
99- self . first_day ( ) + Duration :: days ( 6 )
99+ let end = self . start . pred ( ) . num_days_from_monday ( ) as i32 ;
100+ let ref_day = self . date . weekday ( ) . num_days_from_monday ( ) as i32 ;
101+ let days = if end < ref_day { end - ref_day + 7 } else { end - ref_day } ;
102+ self . date . add_days ( days, false ) . unwrap ( )
100103 }
101104
102105 /// Returns a [`RangeInclusive<T>`] representing the whole week bounded by
@@ -3005,23 +3008,31 @@ mod tests {
30053008 fn test_naiveweek ( ) {
30063009 let date = NaiveDate :: from_ymd_opt ( 2022 , 5 , 18 ) . unwrap ( ) ;
30073010 let asserts = vec ! [
3008- ( Weekday :: Mon , "2022-05-16" , "2022-05-22" ) ,
3009- ( Weekday :: Tue , "2022-05-17" , "2022-05-23" ) ,
3010- ( Weekday :: Wed , "2022-05-18" , "2022-05-24" ) ,
3011- ( Weekday :: Thu , "2022-05-12" , "2022-05-18" ) ,
3012- ( Weekday :: Fri , "2022-05-13" , "2022-05-19" ) ,
3013- ( Weekday :: Sat , "2022-05-14" , "2022-05-20" ) ,
3014- ( Weekday :: Sun , "2022-05-15" , "2022-05-21" ) ,
3011+ ( Weekday :: Mon , "Mon 2022-05-16" , "Sun 2022-05-22" ) ,
3012+ ( Weekday :: Tue , "Tue 2022-05-17" , "Mon 2022-05-23" ) ,
3013+ ( Weekday :: Wed , "Wed 2022-05-18" , "Tue 2022-05-24" ) ,
3014+ ( Weekday :: Thu , "Thu 2022-05-12" , "Wed 2022-05-18" ) ,
3015+ ( Weekday :: Fri , "Fri 2022-05-13" , "Thu 2022-05-19" ) ,
3016+ ( Weekday :: Sat , "Sat 2022-05-14" , "Fri 2022-05-20" ) ,
3017+ ( Weekday :: Sun , "Sun 2022-05-15" , "Sat 2022-05-21" ) ,
30153018 ] ;
30163019 for ( start, first_day, last_day) in asserts {
30173020 let week = date. week ( start) ;
30183021 let days = week. days ( ) ;
3019- assert_eq ! ( Ok ( week. first_day( ) ) , NaiveDate :: parse_from_str( first_day, "%Y-%m-%d" ) ) ;
3020- assert_eq ! ( Ok ( week. last_day( ) ) , NaiveDate :: parse_from_str( last_day, "%Y-%m-%d" ) ) ;
3022+ assert_eq ! ( Ok ( week. first_day( ) ) , NaiveDate :: parse_from_str( first_day, "%a % Y-%m-%d" ) ) ;
3023+ assert_eq ! ( Ok ( week. last_day( ) ) , NaiveDate :: parse_from_str( last_day, "%a % Y-%m-%d" ) ) ;
30213024 assert ! ( days. contains( & date) ) ;
30223025 }
30233026 }
30243027
3028+ #[ test]
3029+ fn test_naiveweek_min_max ( ) {
3030+ let date_max = NaiveDate :: MAX ;
3031+ assert ! ( date_max. week( Weekday :: Mon ) . first_day( ) <= date_max) ;
3032+ let date_min = NaiveDate :: MIN ;
3033+ assert ! ( date_min. week( Weekday :: Mon ) . last_day( ) >= date_min) ;
3034+ }
3035+
30253036 #[ test]
30263037 fn test_weeks_from ( ) {
30273038 // tests per: https://github.com/chronotope/chrono/issues/961
0 commit comments