@@ -386,33 +386,26 @@ def localtime(dt=None, isdst=-1):
386
386
387
387
"""
388
388
if dt is None :
389
- seconds = time .time ()
390
- else :
391
- if dt .tzinfo is None :
392
- # A naive datetime is given. Convert to a (localtime)
393
- # timetuple and pass to system mktime together with
394
- # the isdst hint. System mktime will return seconds
395
- # sysce epoch.
396
- tm = dt .timetuple ()[:- 1 ] + (isdst ,)
397
- seconds = time .mktime (tm )
389
+ dt = datetime .datetime .now (datetime .timezone .utc )
390
+ if dt .tzinfo is not None :
391
+ return dt .astimezone ()
392
+ # We have a naive datetime. Convert to a (localtime) timetuple and pass to
393
+ # system mktime together with the isdst hint. System mktime will return
394
+ # seconds since epoch.
395
+ tm = dt .timetuple ()[:- 1 ] + (isdst ,)
396
+ seconds = time .mktime (tm )
397
+ localtm = time .localtime (seconds )
398
+ try :
399
+ delta = datetime .timedelta (seconds = localtm .tm_gmtoff )
400
+ tz = datetime .timezone (delta , localtm .tm_zone )
401
+ except AttributeError :
402
+ # Compute UTC offset and compare with the value implied by tm_isdst.
403
+ # If the values match, use the zone name implied by tm_isdst.
404
+ delta = dt - datetime .datetime (* time .gmtime (ts )[:6 ])
405
+ dst = time .daylight and localtm .tm_isdst > 0
406
+ gmtoff = - (time .altzone if dst else time .timezone )
407
+ if delta == datetime .timedelta (seconds = gmtoff ):
408
+ tz = datetime .timezone (delta , time .tzname [dst ])
398
409
else :
399
- # An aware datetime is given. Use aware datetime
400
- # arithmetics to find seconds since epoch.
401
- delta = dt - datetime .datetime (1970 , 1 , 1 ,
402
- tzinfo = datetime .timezone .utc )
403
- seconds = delta .total_seconds ()
404
- tm = time .localtime (seconds )
405
-
406
- # XXX: The following logic may not work correctly if UTC
407
- # offset has changed since time provided in dt. This will be
408
- # corrected in C implementation for platforms that support
409
- # tm_gmtoff.
410
- if time .daylight and tm .tm_isdst :
411
- offset = time .altzone
412
- tzname = time .tzname [1 ]
413
- else :
414
- offset = time .timezone
415
- tzname = time .tzname [0 ]
416
-
417
- tz = datetime .timezone (datetime .timedelta (seconds = - offset ), tzname )
418
- return datetime .datetime .fromtimestamp (seconds , tz )
410
+ tz = datetime .timezone (delta )
411
+ return dt .replace (tzinfo = tz )
0 commit comments