@@ -23,7 +23,7 @@ use crate::format::{Item, Numeric, Pad};
23
23
use crate :: month:: Months ;
24
24
use crate :: naive:: { IsoWeek , NaiveDateTime , NaiveTime } ;
25
25
use crate :: oldtime:: Duration as OldDuration ;
26
- use crate :: { Datelike , Duration , Weekday } ;
26
+ use crate :: { Datelike , Weekday } ;
27
27
28
28
use super :: internals:: { self , DateImpl , Mdf , Of , YearFlags } ;
29
29
use super :: isoweek;
@@ -76,10 +76,10 @@ impl NaiveWeek {
76
76
#[ inline]
77
77
#[ must_use]
78
78
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 ( )
83
83
}
84
84
85
85
/// Returns a date representing the last day of the week.
@@ -96,7 +96,10 @@ impl NaiveWeek {
96
96
#[ inline]
97
97
#[ must_use]
98
98
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 ( )
100
103
}
101
104
102
105
/// Returns a [`RangeInclusive<T>`] representing the whole week bounded by
@@ -3005,23 +3008,31 @@ mod tests {
3005
3008
fn test_naiveweek ( ) {
3006
3009
let date = NaiveDate :: from_ymd_opt ( 2022 , 5 , 18 ) . unwrap ( ) ;
3007
3010
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" ) ,
3015
3018
] ;
3016
3019
for ( start, first_day, last_day) in asserts {
3017
3020
let week = date. week ( start) ;
3018
3021
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" ) ) ;
3021
3024
assert ! ( days. contains( & date) ) ;
3022
3025
}
3023
3026
}
3024
3027
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
+
3025
3036
#[ test]
3026
3037
fn test_weeks_from ( ) {
3027
3038
// tests per: https://github.com/chronotope/chrono/issues/961
0 commit comments