22use crate :: no_std_prelude:: * ;
33use crate :: {
44 format:: parse:: { parse, ParseError , ParseResult , ParsedItems } ,
5- ComponentRangeError , DeferredFormat , Duration , PrimitiveDateTime , Time ,
5+ internals , ComponentRangeError , DeferredFormat , Duration , PrimitiveDateTime , Time ,
66 Weekday :: { self , Friday , Monday , Saturday , Sunday , Thursday , Tuesday , Wednesday } ,
77} ;
88use core:: {
@@ -72,9 +72,7 @@ pub const fn days_in_year(year: i32) -> u16 {
7272/// ```
7373#[ inline( always) ]
7474pub fn weeks_in_year ( year : i32 ) -> u8 {
75- let weekday = Date :: try_from_yo ( year, 1 )
76- . expect ( "date is always valid" )
77- . weekday ( ) ;
75+ let weekday = internals:: Date :: from_yo ( year, 1 ) . weekday ( ) ;
7876
7977 if ( weekday == Thursday ) || ( weekday == Wednesday && is_leap_year ( year) ) {
8078 53
@@ -125,22 +123,10 @@ impl Date {
125123 #[ cfg( feature = "panicking-api" ) ]
126124 #[ cfg_attr( doc, doc( cfg( feature = "panicking-api" ) ) ) ]
127125 pub fn from_ymd ( year : i32 , month : u8 , day : u8 ) -> Self {
128- /// Cumulative days through the beginning of a month in both common and
129- /// leap years.
130- const DAYS_CUMULATIVE_COMMON_LEAP : [ [ u16 ; 12 ] ; 2 ] = [
131- [ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 ] ,
132- [ 0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335 ] ,
133- ] ;
134-
135126 assert_value_in_range ! ( month in 1 => 12 ) ;
136127 assert_value_in_range ! ( day in 1 => days_in_year_month( year, month) , given year, month) ;
137128
138- let ordinal = DAYS_CUMULATIVE_COMMON_LEAP [ is_leap_year ( year) as usize ] [ month as usize - 1 ] ;
139-
140- Self {
141- year,
142- ordinal : ordinal + day as u16 ,
143- }
129+ internals:: Date :: from_ymd ( year, month, day)
144130 }
145131
146132 /// Attempt to create a `Date` from the year, month, and day.
@@ -159,22 +145,10 @@ impl Date {
159145 /// ```
160146 #[ inline]
161147 pub fn try_from_ymd ( year : i32 , month : u8 , day : u8 ) -> Result < Self , ComponentRangeError > {
162- /// Cumulative days through the beginning of a month in both common and
163- /// leap years.
164- const DAYS_CUMULATIVE_COMMON_LEAP : [ [ u16 ; 12 ] ; 2 ] = [
165- [ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 ] ,
166- [ 0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335 ] ,
167- ] ;
168-
169148 ensure_value_in_range ! ( month in 1 => 12 ) ;
170149 ensure_value_in_range ! ( day in 1 => days_in_year_month( year, month) , given year, month) ;
171150
172- let ordinal = DAYS_CUMULATIVE_COMMON_LEAP [ is_leap_year ( year) as usize ] [ month as usize - 1 ] ;
173-
174- Ok ( Self {
175- year,
176- ordinal : ordinal + day as u16 ,
177- } )
151+ Ok ( internals:: Date :: from_ymd ( year, month, day) )
178152 }
179153
180154 /// Create a `Date` from the year and ordinal day number.
@@ -248,20 +222,7 @@ impl Date {
248222 #[ cfg_attr( doc, doc( cfg( feature = "panicking-api" ) ) ) ]
249223 pub fn from_iso_ywd ( year : i32 , week : u8 , weekday : Weekday ) -> Self {
250224 assert_value_in_range ! ( week in 1 => weeks_in_year( year) , given year) ;
251-
252- let ordinal = week as u16 * 7 + weekday. iso_weekday_number ( ) as u16
253- - ( Self :: from_yo ( year, 4 ) . weekday ( ) . iso_weekday_number ( ) as u16 + 3 ) ;
254-
255- if ordinal < 1 {
256- return Self :: from_yo ( year - 1 , ordinal + days_in_year ( year - 1 ) ) ;
257- }
258-
259- let days_in_cur_year = days_in_year ( year) ;
260- if ordinal > days_in_cur_year {
261- Self :: from_yo ( year + 1 , ordinal - days_in_cur_year)
262- } else {
263- Self :: from_yo ( year, ordinal)
264- }
225+ internals:: Date :: from_iso_ywd ( year, week, weekday)
265226 }
266227
267228 /// Attempt to create a `Date` from the ISO year, week, and weekday.
@@ -286,24 +247,7 @@ impl Date {
286247 weekday : Weekday ,
287248 ) -> Result < Self , ComponentRangeError > {
288249 ensure_value_in_range ! ( week in 1 => weeks_in_year( year) , given year) ;
289-
290- let ordinal = week as u16 * 7 + weekday. iso_weekday_number ( ) as u16
291- - ( Self :: try_from_yo ( year, 4 )
292- . expect ( "date is always valid" )
293- . weekday ( )
294- . iso_weekday_number ( ) as u16
295- + 3 ) ;
296-
297- if ordinal < 1 {
298- return Self :: try_from_yo ( year - 1 , ordinal + days_in_year ( year - 1 ) ) ;
299- }
300-
301- let days_in_cur_year = days_in_year ( year) ;
302- if ordinal > days_in_cur_year {
303- Self :: try_from_yo ( year + 1 , ordinal - days_in_cur_year)
304- } else {
305- Self :: try_from_yo ( year, ordinal)
306- }
250+ Ok ( internals:: Date :: from_iso_ywd ( year, week, weekday) )
307251 }
308252
309253 /// Create a `Date` representing the current date.
@@ -674,8 +618,9 @@ impl Date {
674618 let month = ( h / S + M ) . rem_euclid ( N ) + 1 ;
675619 let year = ( e / P ) - Y + ( N + M - month) / N ;
676620
621+ // TODO Seek out a formal proof that this always results in a valid value.
677622 #[ allow( clippy:: cast_possible_truncation, clippy:: cast_sign_loss) ]
678- Self :: try_from_ymd ( year as i32 , month as u8 , day as u8 ) . expect ( "date is always valid" )
623+ internals :: Date :: from_ymd ( year as i32 , month as u8 , day as u8 )
679624 }
680625}
681626
@@ -945,10 +890,7 @@ impl Date {
945890 /// Monday-based week numbering.
946891 #[ inline( always) ]
947892 fn adjustment ( year : i32 ) -> i16 {
948- match Date :: try_from_yo ( year, 1 )
949- . expect ( "date is always valid" )
950- . weekday ( )
951- {
893+ match internals:: Date :: from_yo ( year, 1 ) . weekday ( ) {
952894 Monday => 7 ,
953895 Tuesday => 1 ,
954896 Wednesday => 2 ,
@@ -959,37 +901,33 @@ impl Date {
959901 }
960902 }
961903
904+ // Verification for all components is done at parse time.
962905 match items {
963- items ! ( year, month, day) => Ok ( Self :: try_from_ymd ( year, month. get ( ) , day. get ( ) )
964- . expect ( "components are checked when parsing" ) ) ,
965- items ! ( year, ordinal_day) => Ok ( Self :: try_from_yo ( year, ordinal_day. get ( ) )
966- . expect ( "components are checked when parsing" ) ) ,
967- items ! ( week_based_year, iso_week, weekday) => {
968- Ok (
969- Self :: try_from_iso_ywd ( week_based_year, iso_week. get ( ) , weekday)
970- . expect ( "components are checked when parsing" ) ,
971- )
972- }
973- items ! ( year, sunday_week, weekday) => Ok ( Self :: try_from_yo (
906+ items ! ( year, month, day) => Ok ( internals:: Date :: from_ymd ( year, month. get ( ) , day. get ( ) ) ) ,
907+ items ! ( year, ordinal_day) => Ok ( internals:: Date :: from_yo ( year, ordinal_day. get ( ) ) ) ,
908+ items ! ( week_based_year, iso_week, weekday) => Ok ( internals:: Date :: from_iso_ywd (
909+ week_based_year,
910+ iso_week. get ( ) ,
911+ weekday,
912+ ) ) ,
913+ items ! ( year, sunday_week, weekday) => Ok ( internals:: Date :: from_yo (
974914 year,
975915 #[ allow( clippy:: cast_sign_loss) ]
976916 {
977917 ( sunday_week as i16 * 7 + weekday. number_days_from_sunday ( ) as i16
978918 - adjustment ( year)
979919 + 1 ) as u16
980920 } ,
981- )
982- . expect ( "components are checked when parsing" ) ) ,
983- items ! ( year, monday_week, weekday) => Ok ( Self :: try_from_yo (
921+ ) ) ,
922+ items ! ( year, monday_week, weekday) => Ok ( internals:: Date :: from_yo (
984923 year,
985924 #[ allow( clippy:: cast_sign_loss) ]
986925 {
987926 ( monday_week as i16 * 7 + weekday. number_days_from_monday ( ) as i16
988927 - adjustment ( year)
989928 + 1 ) as u16
990929 } ,
991- )
992- . expect ( "components are checked when parsing" ) ) ,
930+ ) ) ,
993931 _ => Err ( ParseError :: InsufficientInformation ) ,
994932 }
995933 }
0 commit comments