Index: Lib/datetime.py =================================================================== --- Lib/datetime.py (revision 88001) +++ Lib/datetime.py (working copy) @@ -1421,6 +1421,53 @@ time.hour, time.minute, time.second, time.microsecond, time.tzinfo) + @classmethod + def localtime(cls, dt=None, isdst=-1): + """Return local time as an aware datetime object. + + If called without arguments, return current time. Otherwise + *dt* argument should be a datetime instance that is converted + to local time zone according to the system time zone database. + If *dt* is naive (i.e. t.tzinfo is None), it is assumed to be + in local time. In this case, a positive or zero value for + *isdst* causes localtime to presume initially that summer time + (for example, Daylight Saving Time) is or is not + (respectively) in effect for the specified time. A negative + value for *isdst* causes the localtime() function to attempt + to divine whether summer time is in effect for the specified + time. + """ + if dt is None: + seconds = _time.time() + else: + if dt.tzinfo is None: + # A naive datetime is given. Convert to a (localtime) + # timetuple and pass to system mktime together with + # the isdst hint. System mktime will return seconds + # sysce epoch. + tm = dt.timetuple()[:-1] + (isdst,) + seconds = _time.mktime(tm) + else: + # An aware datetime is given. Use aware datetime + # arithmetics to find seconds since epoch. + delta = dt - datetime(1970, 1, 1, tzinfo=timezone.utc) + seconds = delta.total_seconds() + tm = _time.localtime(seconds) + + # XXX: The following logic may not work correctly if UTC + # offset has changed since time provided in dt. This will be + # corrected in C implementation for platforms that support + # tm_gmtoff. + if _time.daylight: + if tm.tm_isdst: + offset = _time.altzone + tzname = _time.tzname[1] + else: + offset = _time.timezone + tzname = _time.tzname[0] + tz = timezone(timedelta(seconds=-offset), tzname) + return cls.fromtimestamp(seconds, tz) + def timetuple(self): "Return local time tuple compatible with time.localtime()." dst = self.dst() Index: Lib/test/datetimetester.py =================================================================== --- Lib/test/datetimetester.py (revision 88001) +++ Lib/test/datetimetester.py (working copy) @@ -1948,6 +1948,26 @@ self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + dt1.second - 7) + + def test_localtime(self): + t = self.theclass.localtime() + self.assertIsNot(t.tzinfo, None) + t0 = datetime(1970, 1, 1, tzinfo = timezone.utc) + t1 = self.theclass.localtime(t0) + self.assertEqual(t0, t1) + t2 = self.theclass.localtime(t1.replace(tzinfo=None)) + self.assertEqual(t1, t2) + # The following tests use local time that is ambiguous in the + # US, but should work in any location + t0 = datetime(2010, 11, 7, 1, 30) + t1 = self.theclass.localtime(t0, isdst=0) + t2 = self.theclass.localtime(t1) + self.assertEqual(t1, t2) + t1 = self.theclass.localtime(t0, isdst=1) + t2 = self.theclass.localtime(t1) + self.assertEqual(t1, t2) + + class TestSubclassDateTime(TestDateTime): theclass = SubclassDatetime # Override tests not designed for subclass