@@ -1348,56 +1348,64 @@ Examples of working with datetime objects:
13481348
13491349Using datetime with tzinfo:
13501350
1351- >>> from datetime import timedelta, datetime, tzinfo
1352- >>> class GMT1 (tzinfo ):
1351+ >>> from datetime import timedelta, datetime, tzinfo, timezone
1352+ >>> class KabulTz (tzinfo ):
1353+ ... # Kabul used +4 until 1945, when they moved to +4:30
1354+ ... UTC_MOVE_DATE = datetime(1944 , 12 , 31 , 20 , tzinfo = timezone.utc)
13531355 ... def utcoffset (self , dt ):
1354- ... return timedelta(hours = 1 ) + self .dst(dt)
1355- ... def dst (self , dt ):
1356- ... # DST starts last Sunday in March
1357- ... d = datetime(dt.year, 4 , 1 ) # ends last Sunday in October
1358- ... self .dston = d - timedelta(days = d.weekday() + 1 )
1359- ... d = datetime(dt.year, 11 , 1 )
1360- ... self .dstoff = d - timedelta(days = d.weekday() + 1 )
1361- ... if self .dston <= dt.replace(tzinfo = None ) < self .dstoff:
1362- ... return timedelta(hours = 1 )
1356+ ... if dt.year < 1945 :
1357+ ... return timedelta(hours = 4 )
1358+ ... elif (1945 , 1 , 1 , 0 , 0 ) <= dt.timetuple()[:5 ] < (1945 , 1 , 1 , 0 , 30 ):
1359+ ... # If dt falls in the imaginary range, use fold to decide how
1360+ ... # to resolve. See PEP495
1361+ ... return timedelta(hours = 4 , minutes = (30 if dt.fold else 0 ))
13631362 ... else :
1364- ... return timedelta(0 )
1365- ... def tzname (self ,dt ):
1366- ... return " GMT +1"
1363+ ... return timedelta(hours = 4 , minutes = 30 )
1364+ ...
1365+ ... def fromutc (self , dt ):
1366+ ... # A custom implementation is required for fromutc as
1367+ ... # the input to this function is a datetime with utc values
1368+ ... # but with a tzinfo set to self
1369+ ... # See datetime.astimezone or fromtimestamp
1370+ ...
1371+ ... # Follow same validations as in datetime.tzinfo
1372+ ... if not isinstance (dt, datetime):
1373+ ... raise TypeError (" fromutc() requires a datetime argument" )
1374+ ... if dt.tzinfo is not self :
1375+ ... raise ValueError (" dt.tzinfo is not self" )
1376+ ...
1377+ ... if dt.replace(tzinfo = timezone.utc) >= self .UTC_MOVE_DATE :
1378+ ... return dt + timedelta(hours = 4 , minutes = 30 )
1379+ ... else :
1380+ ... return dt + timedelta(hours = 4 )
13671381 ...
1368- >>> class GMT2 (tzinfo ):
1369- ... def utcoffset (self , dt ):
1370- ... return timedelta(hours = 2 ) + self .dst(dt)
13711382 ... def dst (self , dt ):
1372- ... d = datetime(dt.year, 4 , 1 )
1373- ... self .dston = d - timedelta(days = d.weekday() + 1 )
1374- ... d = datetime(dt.year, 11 , 1 )
1375- ... self .dstoff = d - timedelta(days = d.weekday() + 1 )
1376- ... if self .dston <= dt.replace(tzinfo = None ) < self .dstoff:
1377- ... return timedelta(hours = 1 )
1383+ ... return timedelta(0 )
1384+ ...
1385+ ... def tzname (self , dt ):
1386+ ... if dt >= self .UTC_MOVE_DATE :
1387+ ... return " +04:30"
13781388 ... else :
1379- ... return timedelta(0 )
1380- ... def tzname (self ,dt ):
1381- ... return " GMT +2"
1389+ ... return " +04"
13821390 ...
1383- >>> gmt1 = GMT1()
1384- >>> # Daylight Saving Time
1385- >>> dt1 = datetime( 2006 , 11 , 21 , 16 , 30 , tzinfo = gmt1)
1386- >>> dt1.dst ()
1387- datetime.timedelta(0)
1388- >>> dt1.utcoffset( )
1389- datetime.timedelta(seconds=3600 )
1390- >>> dt2 = datetime( 2006 , 6 , 14 , 13 , 0 , tzinfo = gmt1)
1391- >>> dt2.dst()
1392- datetime.timedelta(seconds=3600 )
1393- >>> dt2.utcoffset()
1394- datetime.timedelta(seconds=7200)
1391+ ... def __repr__ ( self ):
1392+ ... return f " { self . __class__ . __name__ } () "
1393+ ...
1394+ >>> tz1 = KabulTz ()
1395+ >>> # Datetime before the change
1396+ >>> dt1 = datetime( 1900 , 11 , 21 , 16 , 30 , tzinfo = tz1 )
1397+ >>> print (dt1.utcoffset() )
1398+ 4:00:00
1399+ >>> # Datetime after the change
1400+ >>> dt2 = datetime( 2006 , 6 , 14 , 13 , 0 , tzinfo = tz1 )
1401+ >>> print ( dt2.utcoffset() )
1402+ 4:30:00
13951403 >>> # Convert datetime to another time zone
1396- >>> dt3 = dt2.astimezone(GMT2() )
1397- >>> dt3 # doctest: +ELLIPSIS
1398- datetime.datetime(2006, 6, 14, 14, 0 , tzinfo=<GMT2 object at 0x...> )
1399- >>> dt2 # doctest: +ELLIPSIS
1400- datetime.datetime(2006, 6, 14, 13, 0, tzinfo=<GMT1 object at 0x...> )
1404+ >>> dt3 = dt2.astimezone(timezone.utc )
1405+ >>> dt3
1406+ datetime.datetime(2006, 6, 14, 8, 30 , tzinfo=datetime.timezone.utc )
1407+ >>> dt2
1408+ datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz() )
14011409 >>> dt2.utctimetuple() == dt3.utctimetuple()
14021410 True
14031411
@@ -1639,26 +1647,27 @@ Instance methods:
16391647Example:
16401648
16411649 >>> from datetime import time, tzinfo, timedelta
1642- >>> class GMT1 (tzinfo ):
1650+ >>> class TZ1 (tzinfo ):
16431651 ... def utcoffset (self , dt ):
16441652 ... return timedelta(hours = 1 )
16451653 ... def dst (self , dt ):
16461654 ... return timedelta(0 )
16471655 ... def tzname (self ,dt ):
1648- ... return " Europe/Prague"
1656+ ... return " +01:00"
1657+ ... def __repr__ (self ):
1658+ ... return f " { self .__class__ .__name__ } () "
16491659 ...
1650- >>> t = time(12 , 10 , 30 , tzinfo = GMT1())
1651- >>> t # doctest: +ELLIPSIS
1652- datetime.time(12, 10, 30, tzinfo=<GMT1 object at 0x...>)
1653- >>> gmt = GMT1()
1660+ >>> t = time(12 , 10 , 30 , tzinfo = TZ1())
1661+ >>> t
1662+ datetime.time(12, 10, 30, tzinfo=TZ1())
16541663 >>> t.isoformat()
16551664 '12:10:30+01:00'
16561665 >>> t.dst()
16571666 datetime.timedelta(0)
16581667 >>> t.tzname()
1659- 'Europe/Prague '
1668+ '+01:00 '
16601669 >>> t.strftime(" %H:%M:%S %Z" )
1661- '12:10:30 Europe/Prague '
1670+ '12:10:30 +01:00 '
16621671 >>> ' The {} is {: %H:%M} .' .format(" time" , t)
16631672 'The time is 12:10.'
16641673
0 commit comments