@@ -61,7 +61,8 @@ use crate::{intern, DowncastError};
61
61
use crate :: { IntoPy , ToPyObject } ;
62
62
use chrono:: offset:: { FixedOffset , Utc } ;
63
63
use chrono:: {
64
- DateTime , Datelike , Duration , NaiveDate , NaiveDateTime , NaiveTime , Offset , TimeZone , Timelike ,
64
+ DateTime , Datelike , Duration , LocalResult , NaiveDate , NaiveDateTime , NaiveTime , Offset ,
65
+ TimeZone , Timelike ,
65
66
} ;
66
67
67
68
#[ allow( deprecated) ]
@@ -493,12 +494,26 @@ impl<Tz: TimeZone + for<'py> FromPyObject<'py>> FromPyObject<'_> for DateTime<Tz
493
494
) ) ;
494
495
} ;
495
496
let naive_dt = NaiveDateTime :: new ( py_date_to_naive_date ( dt) ?, py_time_to_naive_time ( dt) ?) ;
496
- naive_dt. and_local_timezone ( tz) . single ( ) . ok_or_else ( || {
497
- PyValueError :: new_err ( format ! (
498
- "The datetime {:?} contains an incompatible or ambiguous timezone" ,
497
+ match naive_dt. and_local_timezone ( tz) {
498
+ LocalResult :: Single ( value) => Ok ( value) ,
499
+ LocalResult :: Ambiguous ( earliest, latest) => {
500
+ #[ cfg( not( Py_LIMITED_API ) ) ]
501
+ let fold = dt. get_fold ( ) ;
502
+
503
+ #[ cfg( Py_LIMITED_API ) ]
504
+ let fold = dt. getattr ( intern ! ( dt. py( ) , "fold" ) ) ?. extract :: < usize > ( ) ? > 0 ;
505
+
506
+ if fold {
507
+ Ok ( latest)
508
+ } else {
509
+ Ok ( earliest)
510
+ }
511
+ }
512
+ LocalResult :: None => Err ( PyValueError :: new_err ( format ! (
513
+ "The datetime {:?} contains an incompatible timezone" ,
499
514
dt
500
- ) )
501
- } )
515
+ ) ) ) ,
516
+ }
502
517
}
503
518
}
504
519
0 commit comments