@@ -386,33 +386,26 @@ def localtime(dt=None, isdst=-1):
386386
387387 """
388388 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 ])
398409 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