@@ -4,7 +4,7 @@ use crate::offset::{FixedOffset, TimeZone, Utc};
44#[ cfg( feature = "clock" ) ]
55use crate :: offset:: { Local , Offset } ;
66use crate :: oldtime:: Duration ;
7- use crate :: { Datelike , Days , LocalResult , Months , NaiveDateTime } ;
7+ use crate :: { Datelike , Days , LocalResult , Months , NaiveDateTime , Timelike , Weekday } ;
88
99#[ derive( Clone ) ]
1010struct DstTester ;
@@ -1347,6 +1347,157 @@ fn test_datetime_sub_assign() {
13471347 assert_eq ! ( datetime_sub, datetime - Duration :: minutes( 90 ) ) ;
13481348}
13491349
1350+ #[ test]
1351+ fn test_min_max_datetimes ( ) {
1352+ let offset_min = FixedOffset :: west_opt ( 2 * 60 * 60 ) . unwrap ( ) ;
1353+ let min = offset_min. from_utc_datetime ( & NaiveDateTime :: MIN ) ;
1354+ let offset_max = FixedOffset :: east_opt ( 2 * 60 * 60 ) . unwrap ( ) ;
1355+ let max = offset_max. from_utc_datetime ( & NaiveDateTime :: MAX ) ;
1356+
1357+ assert_eq ! ( format!( "{:?}" , min) , "-262144-12-31T22:00:00-02:00" ) ;
1358+ // RFC 2822 doesn't support years with more than 4 digits.
1359+ // assert_eq!(min.to_rfc2822(), "");
1360+ #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
1361+ assert_eq ! ( min. to_rfc3339( ) , "-262144-12-31T22:00:00-02:00" ) ;
1362+ #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
1363+ assert_eq ! ( min. format( "%Y-%m-%dT%H:%M:%S%:z" ) . to_string( ) , "-262144-12-31T22:00:00-02:00" ) ;
1364+ assert_eq ! ( min. year( ) , -262144 ) ;
1365+ assert_eq ! ( min. month( ) , 12 ) ;
1366+ assert_eq ! ( min. month0( ) , 11 ) ;
1367+ assert_eq ! ( min. day( ) , 31 ) ;
1368+ assert_eq ! ( min. day0( ) , 30 ) ;
1369+ assert_eq ! ( min. ordinal( ) , 366 ) ;
1370+ assert_eq ! ( min. ordinal0( ) , 365 ) ;
1371+ assert_eq ! ( min. weekday( ) , Weekday :: Wed ) ;
1372+ assert_eq ! ( min. iso_week( ) . year( ) , -262143 ) ;
1373+ assert_eq ! ( min. iso_week( ) . week( ) , 1 ) ;
1374+ assert_eq ! ( min. checked_add_days( Days :: new( 0 ) ) , None ) ;
1375+ assert_eq ! (
1376+ min. checked_add_days( Days :: new( 1 ) ) ,
1377+ Some ( offset_min. from_utc_datetime( & ( NaiveDate :: MIN + Days ( 1 ) ) . and_time( NaiveTime :: MIN ) ) )
1378+ ) ;
1379+ assert_eq ! ( min. checked_sub_days( Days :: new( 0 ) ) , None ) ;
1380+ assert_eq ! ( min. checked_sub_days( Days :: new( 1 ) ) , None ) ;
1381+ assert_eq ! ( min. checked_add_months( Months :: new( 0 ) ) , Some ( min) ) ;
1382+ assert_eq ! (
1383+ min. checked_add_months( Months :: new( 1 ) ) ,
1384+ Some ( offset_min. from_utc_datetime( & ( NaiveDate :: MIN + Months ( 1 ) ) . and_time( NaiveTime :: MIN ) ) )
1385+ ) ;
1386+ assert_eq ! ( min. checked_sub_months( Months :: new( 0 ) ) , Some ( min) ) ;
1387+ assert_eq ! ( min. checked_sub_months( Months :: new( 1 ) ) , None ) ;
1388+ assert_eq ! ( min. with_year( min. year( ) ) , Some ( min) ) ;
1389+ assert_eq ! (
1390+ min. with_year( 2020 ) ,
1391+ offset_min
1392+ . from_local_datetime(
1393+ & ( NaiveDate :: MIN . with_year( 2021 ) . unwrap( ) . and_time( NaiveTime :: MIN ) + offset_min)
1394+ )
1395+ . single( )
1396+ ) ;
1397+ assert_eq ! ( min. with_month( min. month( ) ) , Some ( min) ) ;
1398+ assert_eq ! ( min. with_month( 3 ) , None ) ;
1399+ assert_eq ! ( min. with_month0( min. month0( ) ) , Some ( min) ) ;
1400+ assert_eq ! ( min. with_month0( 3 ) , None ) ;
1401+ assert_eq ! ( min. with_day( min. day( ) ) , Some ( min) ) ;
1402+ assert_eq ! ( min. with_day( 15 ) , None ) ;
1403+ assert_eq ! ( min. with_day0( min. day0( ) ) , Some ( min) ) ;
1404+ assert_eq ! ( min. with_day0( 15 ) , None ) ;
1405+ assert_eq ! ( min. with_ordinal( min. ordinal( ) ) , Some ( min) ) ;
1406+ assert_eq ! ( min. with_ordinal( 200 ) , None ) ;
1407+ assert_eq ! ( min. with_ordinal0( min. ordinal0( ) ) , Some ( min) ) ;
1408+ assert_eq ! ( min. with_ordinal0( 200 ) , None ) ;
1409+ assert_eq ! ( min. hour( ) , 22 ) ;
1410+ assert_eq ! ( min. minute( ) , 0 ) ;
1411+ assert_eq ! ( min. second( ) , 0 ) ;
1412+ assert_eq ! ( min. nanosecond( ) , 0 ) ;
1413+ assert_eq ! ( min. with_hour( min. hour( ) ) , Some ( min) ) ;
1414+ assert_eq ! ( min. with_hour( 23 ) , min. checked_add_signed( Duration :: hours( 1 ) ) ) ;
1415+ assert_eq ! ( min. with_hour( 5 ) , None ) ;
1416+ assert_eq ! ( min. with_minute( 0 ) , Some ( min) ) ;
1417+ assert_eq ! ( min. with_second( 0 ) , Some ( min) ) ;
1418+ assert_eq ! ( min. with_nanosecond( 0 ) , Some ( min) ) ;
1419+
1420+ assert_eq ! ( format!( "{:?}" , max) , "+262143-01-01T01:59:59.999999999+02:00" ) ;
1421+ // RFC 2822 doesn't support years with more than 4 digits.
1422+ // assert_eq!(min.to_rfc2822(), "");
1423+ #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
1424+ assert_eq ! ( max. to_rfc3339( ) , "+262143-01-01T01:59:59.999999999+02:00" ) ;
1425+ #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
1426+ assert_eq ! (
1427+ max. format( "%Y-%m-%dT%H:%M:%S%.9f%:z" ) . to_string( ) ,
1428+ "+262143-01-01T01:59:59.999999999+02:00"
1429+ ) ;
1430+ assert_eq ! ( max. year( ) , 262143 ) ;
1431+ assert_eq ! ( max. month( ) , 1 ) ;
1432+ assert_eq ! ( max. month0( ) , 0 ) ;
1433+ assert_eq ! ( max. day( ) , 1 ) ;
1434+ assert_eq ! ( max. day0( ) , 0 ) ;
1435+ assert_eq ! ( max. ordinal( ) , 1 ) ;
1436+ assert_eq ! ( max. ordinal0( ) , 0 ) ;
1437+ assert_eq ! ( max. weekday( ) , Weekday :: Tue ) ;
1438+ assert_eq ! ( max. iso_week( ) . year( ) , 262143 ) ;
1439+ assert_eq ! ( max. iso_week( ) . week( ) , 1 ) ;
1440+ assert_eq ! ( max. checked_add_days( Days :: new( 0 ) ) , None ) ;
1441+ assert_eq ! ( max. checked_add_days( Days :: new( 1 ) ) , None ) ;
1442+ assert_eq ! ( max. checked_sub_days( Days :: new( 0 ) ) , None ) ;
1443+ assert_eq ! (
1444+ max. checked_sub_days( Days :: new( 1 ) ) ,
1445+ Some ( offset_max. from_utc_datetime( & ( NaiveDate :: MAX - Days ( 1 ) ) . and_time( NaiveTime :: MAX ) ) )
1446+ ) ;
1447+ assert_eq ! ( max. checked_add_months( Months :: new( 0 ) ) , Some ( max) ) ;
1448+ assert_eq ! ( max. checked_add_months( Months :: new( 1 ) ) , None ) ;
1449+ assert_eq ! ( max. checked_sub_months( Months :: new( 0 ) ) , Some ( max) ) ;
1450+ assert_eq ! (
1451+ max. checked_sub_months( Months :: new( 1 ) ) ,
1452+ Some ( offset_max. from_utc_datetime( & ( NaiveDate :: MAX - Months ( 1 ) ) . and_time( NaiveTime :: MAX ) ) )
1453+ ) ;
1454+ assert_eq ! ( max. with_year( max. year( ) ) , Some ( max) ) ;
1455+ assert_eq ! (
1456+ max. with_year( 2020 ) ,
1457+ offset_max
1458+ . from_local_datetime(
1459+ & ( NaiveDate :: MAX . with_year( 2019 ) . unwrap( ) . and_time( NaiveTime :: MAX ) + offset_max)
1460+ )
1461+ . single( )
1462+ ) ;
1463+ assert_eq ! ( max. with_month( max. month( ) ) , Some ( max) ) ;
1464+ assert_eq ! ( max. with_month( 3 ) , None ) ;
1465+ assert_eq ! ( max. with_month0( max. month0( ) ) , Some ( max) ) ;
1466+ assert_eq ! ( max. with_month0( 3 ) , None ) ;
1467+ assert_eq ! ( max. with_day( max. day( ) ) , Some ( max) ) ;
1468+ assert_eq ! ( max. with_day( 15 ) , None ) ;
1469+ assert_eq ! ( max. with_day0( max. day0( ) ) , Some ( max) ) ;
1470+ assert_eq ! ( max. with_day0( 15 ) , None ) ;
1471+ assert_eq ! ( max. with_ordinal( max. ordinal( ) ) , Some ( max) ) ;
1472+ assert_eq ! ( max. with_ordinal( 200 ) , None ) ;
1473+ assert_eq ! ( max. with_ordinal0( max. ordinal0( ) ) , Some ( max) ) ;
1474+ assert_eq ! ( max. with_ordinal0( 200 ) , None ) ;
1475+ assert_eq ! ( max. hour( ) , 1 ) ;
1476+ assert_eq ! ( max. minute( ) , 59 ) ;
1477+ assert_eq ! ( max. second( ) , 59 ) ;
1478+ assert_eq ! ( max. nanosecond( ) , 999_999_999 ) ;
1479+ assert_eq ! ( max. with_hour( max. hour( ) ) , Some ( max) ) ;
1480+ assert_eq ! ( max. with_hour( 0 ) , max. checked_sub_signed( Duration :: hours( 1 ) ) ) ;
1481+ assert_eq ! ( max. with_hour( 5 ) , None ) ;
1482+ assert_eq ! ( max. with_minute( max. minute( ) ) , Some ( max) ) ;
1483+ assert_eq ! ( max. with_second( max. second( ) ) , Some ( max) ) ;
1484+ assert_eq ! ( max. with_nanosecond( max. nanosecond( ) ) , Some ( max) ) ;
1485+ }
1486+
1487+ #[ test]
1488+ #[ should_panic]
1489+ fn test_local_beyond_min_datetime ( ) {
1490+ let min = FixedOffset :: west_opt ( 2 * 60 * 60 ) . unwrap ( ) . from_utc_datetime ( & NaiveDateTime :: MIN ) ;
1491+ let _ = min. naive_local ( ) ;
1492+ }
1493+
1494+ #[ test]
1495+ #[ should_panic]
1496+ fn test_local_beyond_max_datetime ( ) {
1497+ let max = FixedOffset :: east_opt ( 2 * 60 * 60 ) . unwrap ( ) . from_utc_datetime ( & NaiveDateTime :: MAX ) ;
1498+ let _ = max. naive_local ( ) ;
1499+ }
1500+
13501501#[ test]
13511502#[ cfg( feature = "clock" ) ]
13521503fn test_datetime_sub_assign_local ( ) {
0 commit comments