@@ -4,7 +4,7 @@ use crate::offset::{FixedOffset, TimeZone, Utc};
4
4
#[ cfg( feature = "clock" ) ]
5
5
use crate :: offset:: { Local , Offset } ;
6
6
use crate :: oldtime:: Duration ;
7
- use crate :: { Datelike , Days , LocalResult , Months , NaiveDateTime } ;
7
+ use crate :: { Datelike , Days , LocalResult , Months , NaiveDateTime , Timelike , Weekday } ;
8
8
9
9
#[ derive( Clone ) ]
10
10
struct DstTester ;
@@ -1347,6 +1347,157 @@ fn test_datetime_sub_assign() {
1347
1347
assert_eq ! ( datetime_sub, datetime - Duration :: minutes( 90 ) ) ;
1348
1348
}
1349
1349
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
+
1350
1501
#[ test]
1351
1502
#[ cfg( feature = "clock" ) ]
1352
1503
fn test_datetime_sub_assign_local ( ) {
0 commit comments