This is a simplified (i.e., wrong for a few cases) set of rules for US
DST start and end times. For a complete and up-to-date set of DST rules
and timezone definitions, visit the Olson Database (or try pytz):
http://www.twinsun.com/tz/tz-link.htm
http://sourceforge.net/projects/pytz/ (might not be up-to-date)
In the US, since 2007, DST starts at 2am (standard time) on the second
Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
and ends at 2am (DST time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 2)
From 1987 to 2006, DST used to start at 2am (standard time) on the first
Sunday in April and to end at 2am (DST time) on the last
Sunday of October, which is the first Sunday on or after Oct 25.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
From 1967 to 1986, DST used to start at 2am (standard time) on the last
Sunday in April (the one on or after April 24) and to end at 2am (DST time)
on the last Sunday of October, which is the first Sunday
on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006
def us_dst_range(year):
# Find start and end times for US DST. For years before 1967, return
# start = end for no DST.
if 2006 < year:
dststart, dstend = DSTSTART_2007, DSTEND_2007
elif 1986 < year < 2007:
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
elif 1966 < year < 1987:
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
else:
return (datetime(year, 1, 1), ) * 2
start = first_sunday_on_or_after(dststart.replace(year=year))
end = first_sunday_on_or_after(dstend.replace(year=year))
return start, end
class USTimeZone(tzinfo):
def \_\_init\_\_(self, hours, reprname, stdname, dstname):
self.stdoffset = timedelta(hours=hours)
self.reprname = reprname
self.stdname = stdname
self.dstname = dstname
def \_\_repr\_\_(self):
return self.reprname
def tzname(self, dt):
if self.dst(dt):
return self.dstname
else:
return self.stdname
def utcoffset(self, dt):
return self.stdoffset + self.dst(dt)
def dst(self, dt):
if dt is None or dt.tzinfo is None:
# An exception may be sensible here, in one or both cases.
# It depends on how you want to treat them. The default
# fromutc() implementation (called by the default astimezone()
# implementation) passes a datetime with dt.tzinfo is self.
return ZERO
assert dt.tzinfo is self
start, end = us_dst_range(dt.year)
# Can't compare naive to aware objects, so strip the timezone from
# dt first.
dt = dt.replace(tzinfo=None)
if start + HOUR <= dt < end - HOUR:
# DST is in effect.
return HOUR
if end - HOUR <= dt < end:
# Fold (an ambiguous hour): use dt.fold to disambiguate.
return ZERO if dt.fold else HOUR
if start <= dt < start + HOUR:
# Gap (a non-existent hour): reverse the fold rule.
return HOUR if dt.fold else ZERO
# DST is off.
return ZERO
def fromutc(self, dt):
assert dt.tzinfo is self
start, end = us_dst_range(dt.year)
start = start.replace(tzinfo=self)
end = end.replace(tzinfo=self)
std_time = dt + self.stdoffset
dst_time = std_time + HOUR
if end <= dst_time < end + HOUR:
# Repeated hour
return std_time.replace(fold=1)
if std_time < start or dst_time >= end:
# Standard time
return std_time
if start <= std_time < end - HOUR:
# Daylight saving time
return dst_time
Eastern = USTimeZone(-5, “Eastern”, “EST”, “EDT”)
Central = USTimeZone(-6, “Central”, “CST”, “CDT”)
Mountain = USTimeZone(-7, “Mountain”, “MST”, “MDT”)
Pacific = USTimeZone(-8, “Pacific”, “PST”, “PDT”)
#### 1.2.2 timezone类
`timezone` 类是 `tzinfo` 的子类,其每个实例表示与UTC有固定偏移量的时区。注意,这个类的对象不能用于表示在一年中的不同日期使用不同偏移量的位置上的时区信息,或者在对民用时间进行了历史更改的位置上的时区信息。。
该类的构造方法如下:
class datetime.**timezone(offset, name=None)**
参数 `offset` 必须是表示本地时间和UTC时间差异的 `timedelta` 对象实例,并且必须严格介于 `-timedelta(hours=24)` 和 `timedelta(hours=24)` 之间,否则,将会引发 `ValueError` 异常。
参数 `name` 是可选的。如果要为其指定一个值,则其必须是用于 `datetime.tzname()` 方法的返回值的一个字符串。
##### 1.2.2.1 timezone对象实例方法
`timezone` 对象有如下几个实例方法:
* timezone.**utcoffset(dt)**
返回构造 `timezone` 实例时指定的固定值。而参数 `dt` 将会被忽略。返回值是一个表示本地时间与UTC时间差值的`timedelta` 对象实例。
* timezone.**tzname(dt)**
返回构造 `timezone` 实例时指定的固定值。如果在构造时未提供 `name` 参数,那么该方法的返回值由 `offset` 的值确定。如果 `offset` 是 `timedelta(0)`,那么该方法的返回值为`UTC`;其他情况下,该方法的返回值是形如 `UTC±HH:MM` 的字符串,其中 `±` 是`offset` 的符号,`HH` 和`MM` 分别表示 `offset.hours` 和 `offset.minutes` 。
* timezone.**dst(dt)**
通常返回 `None`
* timezone.**fromutc(dt)**
返回 `dt + offset` 。其中 `dt` 必须是一个 `aware` 的 `tzinfo` 属性为 `self` 的 `datetime` 对象的实例。
##### 1.2.2.2 timezone对象类属性
`timezone` 对象有一个类属性:
* timezone.**utc**
表示UTC时区,值为 `timezone(timedelta(0))` 。
#### 1.2.3 timedelta类
一个 `timedelta` 对象表示两个日期或时间之间的持续时间(duration)。
*class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)*
以上所有的参数都是可选的,并且默认值都是0,参数可以是整型或浮点型,可为正也可以为负。
一个`timedelta` 对象内部只存储 `days`,`seconds` 和 `microseconds` 这三个参数,其他参数均会被进行如下转换:
* 每毫秒(millisecond)将被转化为1000微秒(microsecond)。
* 每分钟(minute)将被转化为60秒(second)。
* 每小时(hour)将被转化为3600秒(second)。
* 每星期(week)将被转化为7天(day)。
然后,将 `days`,`seconds` 和 `microseconds` 进行如下的标准化处理,从而使得一个 `timedelta` 对象只有一种唯一的表示方式:
* 0 <= microseconds < 1000000,即microseconds取值范围
* 0 <= seconds < 3600\*24(一天当中的秒数),即seconds的取值范围
* -999999999 <= days <= 999999999,即days的取值范围
如果有浮点型的参数并且有小数微秒,则将所有参数剩余的小数微秒加起来,并使用 `四舍六入五进偶` (round-half-to-even) 的规则进行进位处理。如果没有参数是浮点型,则转化和规范化过程是精确的(不会丢失任何信息)。
如果 `days` 的标准化值超出了指定的范围,则会引发 `OverflowError` 异常。
如果对上述的文字说明不太理解,看看下面的例子应该就明白了:
from datetime import timedelta
td = timedelta(10, 10, 10, 10, 10, 10, 10)
td
datetime.timedelta(days=80, seconds=36610, microseconds=10010)
上例中`timedelta` 对象 `td` 的构造过程如下:
1. 将毫秒转化为微秒:10 milliseconds = 1000\*10 microseconds =10000 microseconds
2. 将分钟转化为秒:10 minutes = 60\*10 seconds = 600 seconds
3. 将小时转化为秒:10 hours = 3600\*10 seconds = 36000 seconds
4. 将星期转化为天:10 weeks = 7\*10 days = 70 days
5. 计算毫秒和微秒之和得到 microseconds参数的值:10000 microseconds + 10 microseconds = 10010 microseconds
6. 计算分钟、小时和秒之和得到seconds参数的值:600 seconds + 36000 seconds + 10 seconds = 36610 seconds
7. 计算星期和天之和得到days参数的值:70 days + 10days = 80 days
8. 判断microseconds、seconds和days参数的值是否在规定的取值范围内,即 0<microseconds<1000000,
0<seconds<3600\*24,-999999999<=days<= 999999999,由于microseconds、seconds和days的值均未超过其取值范围,则不再进行下一步处理,由此得到最终的`timedelta` 对象 `td` 的表示形式:
`datetime.timedelta(days=80, seconds=36610, microseconds=10010)`
我们再来看下一个例子:
td1 = timedelta(10, 10, 10, 1000, 10, 25, 10)
td1
datetime.timedelta(days=81, seconds=4211, microseconds=10)
1. 将毫秒转化为微秒:10 milliseconds = 1000\*1000 microseconds =1000000 microseconds
2. 将分钟转化为秒:10 minutes = 60\*10 seconds = 600 seconds
3. 将小时转化为秒:10 hours = 3600\*25 seconds = 90000 seconds
4. 将星期转化为天:10 weeks = 7\*10 days = 70 days
5. 计算毫秒和微秒之和得到 microseconds参数的值:1000000 microseconds + 10 microseconds = 1000010 microseconds
6. 计算分钟、小时和秒之和得到seconds参数的值:600 seconds + 90000 seconds + 10 seconds = 90610 seconds
7. 计算星期和天之和得到days参数的值:70 days + 10days = 80 days
8. 判断microseconds、seconds和days参数的值是否在规定的取值范围内,即 0<microseconds<1000000,
0<seconds<3600\*24,-999999999<=days<= 999999999,由于microseconds的值1000010已经超过其取值范围1000000,那么将进行进位处理,1000010 microseconds = 1seconds + 10 microseconds,microseconds的值变为10 seconds,seconds的值变为 90611 seconds;由于seconds的值也超出了其取值范围,故也要进行进位处理,90611 seconds = 3600\*24 seconds + 4211 seconds = 1 days + 4211 seconds, 因此seconds的值变为 4211 seconds,days的值变为 81 days,故而,最终的 `timedelta` 对象 `td1` 的表示形式:
`datetime.timedelta(days=81, seconds=4211, microseconds=10)`
下面的例子将演示当 `days` 参数的值超过其取值范围时的情况:
td2 = timedelta(days = 1000000000)
Traceback (most recent call last):
File “”, line 1, in
OverflowError: days=1000000000; must have magnitude <= 999999999
##### 1.2.3.1 timedeltad对象的类属性
`timedelta` 包含如下几个类属性:
* timedelta.min
表示最小timedelta对象 timedelta(-999999999)
* timedelta.max
表示最大timedelta对象 timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999)
* timedelta.resolution
表示不相等的两个timedelta对象的最小差值的timedelta 对象timedelta(microseconds=1)
timedelta.max
datetime.timedelta(days=999999999, seconds=86399, microseconds=999999)
timedelta.min
datetime.timedelta(days=-999999999)
timedelta.resolution
datetime.timedelta(microseconds=1)
注意,由于要进行标准化处理,所以 `timedelta.max` > `-timedelta.min`,并且 `-timedelta.max` 不表示一个timedelta对象。
timedelta.max > -timedelta.min
True
-timedelta.max
Traceback (most recent call last):
File “”, line 1, in
OverflowError: days=-1000000000; must have magnitude <= 999999999
##### 1.2.3.2 timedelta类实例属性
timedelta实例包含如下几个只读属性:
* days
* seconds
* microseconds
td = timedelta(10, 10, 10, 10, 10, 10, 10)
td.days
80
td.seconds
36610
td.microseconds
10010
##### 1.2.3.3 timedelta类实例方法
timedelta实例对象有一个实例方法\*\*`timedelta.total_seconds()`\*\*,返回当前实例所表示持续时间总共包含的秒数:
td = timedelta(10, 10, 10, 10, 10, 10, 10)
td.total_seconds()
6948610.01001
#### 1.2.4 data类
`date` 对象表示理想化日历中的日期(由年、月、日组成),即当前公历日日历在两个方向上无限扩展。第一年的1月1日被称为第一日,第一年的1月2日被称为第二日,以此类推。这与德肖维茨和林戈尔德的《历法计算》(Calendrical Calculations)中对 “预期公历” 的定义相吻合,它是所有计算的基本历法。要了解在格雷戈里公会和许多其他日历系统之间进行转换的算法,请参阅其具体内容。
**class** datetime.**date(year, month, day)**
所有参数都是必须的,并且必须为整数,各个参数的取值范围如下:
* MINYEAR <= year <=MAXYEAR
* 1 <= month <= 12
* 1 <= day <= 给定的year和month参数中的天数
如果某个参数超过了取值范围,则引发 `ValueError` 异常。
##### 1.2.4.1 date对象类方法
`date` 类包含如下几个类方法,均可用来构造一个`date` 类型的对象:
* **date.today()**
返回当前的本地日期,等于`date.fromtimestamp(time.time())`
* **date.fromtimestamp(timestamp)**
返回POSIX时间戳对应的本地日期,与 `time.time()` 返回的日期类似。如果时间戳超出了当前平台的C语言的 `localtime()` 函数支持的值的范围,那么可能会引发`OverflowError` 异常,如果`localtime()` 方法执行失败,则会引发`OSError` 异常。常见的做法是将年份限制在1970到2038之间。注意,对于在时间戳概念中包含闰秒的非posix系统,`fromtimestamp()` 会忽略闰秒。
* **date.fromordinal(ordinal)**
返回与给定的公历序数对应的 `date` 对象的实例,其中第一年1月1日的序数为1。如果不满足 1 <= ordinal <= date.max.toordinal(),则会引发 `ValueError` 异常。对于任意日期 `d`,date.fromordinal(d.toordinal()) == d。
* **date.fromisoformat(date\_string)**
返回字符串 `date_string` 所表示的 `date` 对象实例,其中 `date_string` 中的日期的格式与`date.isoformat()` 返回的日期格式一致。具体来说,这个函数支持格式为`YYYY-MM-DD` 的字符串。
注意,这并不支持解析任意的ISO 8601字符串——它只是作为`date.isoformat()` 的反向操作。
from datetime import date
date.today()
datetime.date(2019, 2, 28)
import time as _time
date.fromtimestamp(_time.time())
datetime.date(2019, 2, 28)
date.today().toordinal()
737118
date.fromordinal(737118)
datetime.date(2019, 2, 28)
date_str = date.today().isoformat()
date_str
‘2019-02-28’
date.fromisoformat(date_str)
datetime.date(2019, 2, 28)
##### 1.2.4.2 date对象类属性
`date` 类包含如下几个类属性:
* date.min
可表示的最小的日期:date(MINYEAR, 1, 1)
* date.max
可表示的最大的日期:date(MAXYEAR, 12, 31)
* date.resolution
两个不相等的`date` 对象的最小差值,等于timedelta(days=1)
* date.year
date.min
datetime.date(1, 1, 1)
date.max
datetime.date(9999, 12, 31)
date.resolution
datetime.timedelta(days=1)
##### 1.2.4.3 date对象实例属性
`date` 对象的实例有如下几个只读实例属性:
* year
`date` 实例对象所表示的日期的年份
* month
`date` 实例对象所表示的日期的月份
* day
`date` 实例对象所表示的日期的天
d = date.today()
d.year
2019
d.month
2
d.day
28
`date` 实例对象支持如下操作:
| 操作 | 结果 |
| --- | --- |
| date2 = date1 + timedelta | date2表示给date1增加 timedeltla.days 天。(1) |
| date2 = date1 - timedelta | 计算date2,使得date2 + timedelta == date1。(2) |
| timedelta = date1 - date2 | 计算date1和date2之间的差值。(3) |
| date1 < date2 | 如果date1是比date2更早的时间,则date1小于date2。(4) |
注解:
(1). 如果 timedelta.days < 0,则 date2在日期上向后移动(即date2是比date1更早的日期);如果 timedelta.days == 0,则date2与date1相等(即date2和date1表示相同的日期);如果timedelta.days > 0,则date2在日期上向前移动(即date2是比date1更晚的日期)。之后,timedelta.seconds 和 timedelta.microseconds 将会被忽略。如果 date2.year 小于 `MINYEAR` 或大于 `MAXYEAR`,则会引发 `OverflowError` 异常。
(2). 这不完全等同于 `date1 + (-timedelta)`,因为 `-timedelta` 在单独的情况下可能会溢出,而 `date2 - timedelta`不会。timedelta.seconds 和 timedelta.microseconds 将会被忽略。
(3). 结果是精确的,并且不会溢出。之后,timedelta.seconds 和 timedelta.microseconds 都是0,并且 date2 + timedelta == date1。
(4). 只有当date1.toordinal() < date2.toordinal() 时,date1 < date2。为了防止比较操作回退到默认的比较对象地址的方式,如果另一比较对象不是 `date` 对象实例,通常会引发 `TypeError` 异常。但是,如果另一个比较对象具有 `timetuple()` 属性,则会返回 `NotImplemented` 。这个钩子为其他种类的日期对象实现混合型比较提供了机会,否则,将一个 `date` 对象实例与一个不同类型的对象进行非相等(==)或不等(!=)比较时,将会引发 `TypeError` 异常。
`date` 对象的实例可以作为字典的键。在布尔上下文中,所有的 `date` 对象实例均会被当作 `True`。
##### 1.2.4.4 date对象实例方法
`date`实例对象有如下几个实例方法:
* date.replace(year=self.year, month=self.month, day=self.day)
将原实例对象中的属性值替换为由关键字参数指定的新的值,其他属性值保持不变。
d = date.today()
d
datetime.date(2019, 2, 28)
d.replace() # 不指定参数,则返回相同的对象
datetime.date(2019, 2, 28)
d.replace(2018) # 只替换年份
datetime.date(2018, 2, 28)
d.replace(2018, 1, 17) # 替换年份、月份和日
datetime.date(2018, 1, 17)
* date.timetuple()
返回一个 `time.struct_time` 对象实例,类似于 `time.localtime()` 的返回值。其中,hours,minuts和seconds参数的值为0,DST flag的值为 -1。如果 `d` 是一个date对象的实例,那么,`d.timetuple()` 等价于以下表达式:
***ime.struct\_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1))***
其中,yday = d.toordinal() - date(d.year, 1, 1) + 1 。
d = date.today()
d.timetuple()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=60, tm_isdst=-1)
d.timetuple().tm_year
2019
d.timetuple().tm_mon
3
yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1
yday
60
_time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1))
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=60, tm_isdst=-1)
d1 = date(2019, 3, 1)
d1
datetime.date(2019, 3, 1)
t = d1.timetuple()
for i in t:
… print(i)
…
2019 # year
3 # month
1 # day
0
0
0
4 # weekday (0 = Monday)
60 # 60th day in the year
-1
* date.toordinal()
返回`date` 实例对象的预期公历序数,其中第一年的1月1日的序数为1。对于任何日期对象`d`, `date.fromordinal(d.toordinal()) == d`
date.today().toordinal()
737119
* date.weekday()
返回当前日期在一周内的序号,即星期几,其中周一表示为0,周日表示为6。
date.today().weekday()
4
* date.isoweekday()
返回当前日期在一周内的序号,即星期几,其中周一表示为1,周日表示为7。
date.today().isoweekday()
5
* date.isocalendar()
返回一个包含给定日期对象的ISO year、ISO week number和ISO weekday的三元组。
ISO日历是公历的一种变体。ISO年包括52或53个整周,其中一周从星期一开始到星期天结束。ISO年的第一周是一年中第一个包含星期四的(公历)日历周。这个周为周数1,并且这个周的星期四的ISO年和公历年相同。
例如,2004年从星期四开始,因此ISO 2004年的第一周从2003年12月29日星期一开始,到2004年1月4日星期日结束,因此 `date(2003,12,29).isocalendar() ==(2004, 1, 1)`,`date(2004,1,4).isocalendar() ==(2004, 1, 7)`。
date(2003, 12, 29).isocalendar()
(2004, 1, 1)
date(2004, 1, 4).isocalendar()
(2004, 1, 7)
d = date.today
d
datetime.date(2019, 3, 1)
ic = d.isocalendar()
for i in ic:
… print(i)
…
2019 # ISO year
9 # ISO week number
5 # ISO day number (1 = Monday)
* date.isoformat()
以ISO 8601格式返回表示日期的字符串’YYYY-MM-DD’。例如,`date(2002, 12, 4).isoformat() == '2002-12-04'`
date.today().isoformat()
‘2019-03-01’
* date.\_\_str\_\_()
对date 的实例对象`d`,`str(d)` 等同于 `d.isoformat()`
date.today().isoformat()
‘2019-03-01’
str(date.today())
‘2019-03-01’
d.isoformat()
‘2019-03-01’
* date.ctime()
返回表示日期的字符串。例如 `date(2002, 12, 4).ctime() == 'Wed Dec 400:00:00 2002'` 。在原生的C函数`ctime()`(`time.ctime()`调用它,但是`date.ctime()` 不调用它)遵守C标准的平台上,对于`date`的实例对象 `d`,`d.ctime()` 等同于 `time.ctime(time.mktime(d.timetuple()))`
date.today().ctime()
‘Fri Mar 1 00:00:00 2019’
_time.ctime(_time.mktime(date.today().timetuple()))
‘Fri Mar 1 00:00:00 2019’
* date.strftime(format)
返回表示日期的字符串,日期格式由显式的格式化字符串指定。如果格式化代码中引用到了小时、分或秒,那么对应的值将被置为0。完整的格式化指令,请参考 [strftime() and strptime() Behavior]( ) 。
d = date.today
d
datetime.date(2019, 3, 1)
d.strftime(‘%d/%m/%y’)
‘01/03/19’
* date.\_\_format\_\_(format)
与 `date.strftime()` 相同。同时,这也使得在使用 `str.format()` 时,可以使用带格式的字符串文本为日期对象指定格式字符串。完整的格式化指令,请参考 [strftime() and strptime() Behavior]( ) 。
d = date.today
d
datetime.date(2019, 3, 1)
‘The {1} is {0:%d}, the {2} is {0:%B}.’.format(d, “day”, “month”)
‘The day is 01, the month is March.’
#### 1.2.5 time类
`time` 对象表示一天中的(本地)时间,独立于任何特定的一天,并且可以通过 `tzinfo` 对象进行调整。
**class** datetime.**time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, \*, fold=0 )**
所有参数都是可选的。`tzinfo` 可以是 `None` 或者 `tzinfo` 抽象类的子类的实例;其他参数可以是整型,取值范围如下:
* 0 <= hour < 24
* 0 <= minute < 60
* 0 <= second < 60
* 0 <= microsecond < 1000000
* fold 0或1
如果某个参数超过了其取值范围,会引发 `ValueError` 异常。除过tzinfo参数,其他参数的默认值均为0,`tzinfo` 参数的默认值是 `None` 。
##### 1.2.5.1 time对象类属性
* time.min
可以表示的最早的时间,值为 `time(0, 0)`
time.min
datetime.time(0, 0)
* time.max
可以表示的最晚的时间,值为 `time(23, 59, 59, 999999)`
time.max
datetime.time(23, 59, 59, 999999)
* time.resolution
两个不相等的 `time` 对象的最小差值,即 `timedelta(microseconds=1)` 。
不过需要注意, `time` 对象不支持算术运算。
time.resolution
datetime.timedelta(microseconds=1)
`time` 对象实例支持如下操作:
* `time` 对象实例之间的比较。
如果 `time` 实例对象 `a` 是比 `time` 实例对象 `b` 更早的时间,则 a < b。如果一个操作数是 `naive` 的,而另一个操作数是 `aware` 的,那么在进行顺序比较时将会引发 `TypeError` 异常。对于相等比较,一个 `naive` 的实例永远不会等于一个 `aware` 的实例。
如果两个操作数都是 `aware` 的,并且具有相同的 `tzinfo` 属性,那么将忽略共同的`tzinfo` 属性,并比较基本的 `times` 数据;如果两个操作数都是 `aware` 的并且具有不同的 `tzinfo` 属性,则首先通过减去它们的UTC偏移量(从`self.utcoffset()`获得)来调整比较数,然后再进行比较。为了防止混合类型之间的比较回退到默认的以对象地址进行的比较,当将`time`对象与其他类型的对象进行非相等(==)和不等(!=)比较时,会引发`TypeError` 异常。
* 可以当作字典的键。
* 可进行高效的 `pickling` 操作。
##### 1.2.5.2 time对象实例属性
`time` 对象实例有如下几个只读属性:
* time.hour
`time` 对象实例中的小时(hour),范围为[0, 23]
* time.minute
`time` 对象实例中的分钟(minute),范围为[0, 59]
* time.second
`time` 对象实例中的秒(second),范围为[0, 59]
* time.microseond
`time` 对象实例中的微秒,范围为[0, 999999]
* time.tzinfo
`time` 构造方法中传递给 `tzinfo` 参数的对象。如果未给 `tzinfo` 参数传递值,则为 `None` 。
##### 1.2.5.3 time对象类方法
`time` 对象有一个类方法 `time.fromisoformat(time_string)`,并且这个方法也是 `time` 类的另一个构造方法。
*classmethod time.fromisoformat(time\_string)*
该方法根据给定的`time_string` 参数的字符串值和这个字符串值的时间格式,返回一个 `time` 对象实例,其中 `time_string` 参数的值所表示的时间格式与 `time.isoformat()` 的返回值一致。具体来说,该函数支持格式为`HH[:MM[:SS[.fff[fff]]] [+HH:MM[:SS[.ffffff]]` 的字符串。
*注意,该方法并不支持解析任意的ISO 8601字符串——它只是作为time.isoformat()的逆操作*。
##### 1.2.5.4 time对象实例方法
`time` 对象有如下几个实例方法:
* time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, \*, fold=0)
返回由指定的关键字参数替换`time` 对象实例中同名属性值后的新的 `time` 对象实例。请注意,可以指定 `tzinfo=None` 来从 `aware` 时间创建 `naive` 时间,并且在此过程中不会进行时间数据的转换。
t = time(14, 30, 15, 500)
t
datetime.time(14, 30, 15, 500)
t.replace(15, 50, 10, 300)
datetime.time(15, 50, 10, 300)
* time.isoformat(timespec=‘auto’)
返回一个表示时间的字符串,这个字符串的格式为ISO 8601格式 HH:MM:SS.ffffff;如果 `microsecond` 为0,则格式为 `HH:MM:SS`;如果 `utcoffset()` 方法的返回值不为 `None`,则追加一个字符串,给出UTC偏移量, 其格式为 `HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]`;或者,如果 `self.microsecond` 是0, 则格式为 `HH:MM:SS+HH:MM[:SS[.ffffff]]` 。
可选参数 `timespec` 指定要包含的时间的其他组件的数量(默认值是 `auto` )。它可以是以下值:
+ `auto` :如果 `microsecond` 为0,则与 `second` 相同,否则,与 `microseconds` 相同。
+ `hours`:包含 `hour`,格式为 `HH` 。
+ `minutes`:包含 `hour` 和 `minute`,格式为 `HH:MM`。
+ `seconds`:包含 `hour`、`minute` 和 `second`,格式为 `HH:MM:SS`。
+ `milliseconds`:包含完整的时间格式,但是会忽略微秒,并表示为这样的格式 `HH:MM:SS.sss`。
+ `microseconds`:包含完整的时间格式 `HH:MM:SS.ffffff`如果指定的 `timespec` 参数的值不在上述列举的范围内,则会引发 `ValueError` 异常。
t = time(1, 1, 1, 300)
t
datetime.time(1, 1, 1, 300)
t.isoformat(timespec=‘milliseconds’)
‘01:01:01.000’
t.isoformat(timespec=‘auto’)
‘01:01:01.000300’
t.isoformat(timespec=‘hours’)
‘01’
t.isoformat(timespec=‘minutes’)
‘01:01’
t.isoformat(timespec=‘seconds’)
‘01:01:01’
t.isoformat(timespec=‘microseconds’)
‘01:01:01.000300’
* time.\_\_str\_\_()
对于一个 `time` 对象实例 `t`, `str(t)` 等同于 `t.isoformat()`
t = time(1, 1, 1, 200)
str(t)
‘01:01:01.000200’
t.isoformat()
‘01:01:01.000200’
* time.strftime(format)
返回表示时间的字符串,时间格式由显式的格式化字符串指定。完整的格式化指令,请参考 [strftime() and strptime() Behavior]( ) 。
* time.\_\_format\_\_(format)
与 `time.strftime()` 方法功能相同。同时,这也使得在使用 `str.format()` 时,可以使用带格式的字符串文本为时间对象指定格式字符串。完整的格式化指令, [strftime() and strptime() Behavior]( ) 。
* time.utcoffset()
返回使用 `datetime.timedelta` 对象实例表示的 `time` 实例对象的时区偏移量, UTC东部为正(UTC西部为负)。如果 `tzinfo` 为 `None`,则返回 `None`;否则返回 `self.tzinfo.utcoffset(self)` 的返回值;如果该方法的返回值不是 `None` 或者一个小于一天的 `timedelta` 对象,则会引发异常。
* time.dst()
返回 `time` 实例对象的DST偏移量。如果 `tzinfo` 为 `None`,则返回 `None`;否则返回 `self.tzinfo.dst(self)` 的返回值;如果DST未生效,则返回值为 `datetime.timedelta(0)`,如果DST生效,则返回使用 `datetime.timedelta` 对象实例表示的DST偏移量。如果该方法的返回值不是 `None` 或者一个小于一天的 `timedelta` 对象,则会引发异常。
* time.tzname()
返回 `time` 实例对象的时区名称。如果 `tzinfo` 为 `None`,则返回 `None`;否则返回 `self.tzinfo.tzname(None)` ;如果该方法的返回值不是 `None` 或者一个字符串对象,则会引发异常。
class GMT1(tzinfo):
… def utcoffset(self, dt):
… return timedelta(hours=1)
… def dst(self, dt):
… return timedelta(0)
… def tzname(self, dt):
… return ‘Europe/Prague’
…
t = time(12, 10, 30, tzinfo=GMT1())
t
datetime.time(12, 10, 30, tzinfo=<main.GMT1 object at 0x108171588>)
gmt = GMT1()
t.isoformat()
‘12:10:30+01:00’
t.dst()
datetime.timedelta(0)
t.tzname()
‘Europe/Prague’
t.utcoffset()
datetime.timedelta(seconds=3600)
t1 = time(13, 40, 14) # tzinfo参数值为None
t1.utcoffset() # 返回值为None
t1.tzname() # 返回值为None
t1.dst() # 返回值为None
#### 1.2.6 datetime类
`datetime` 对象是一个包含 `date` 对象和 `time` 对象所有信息的单个对象。像 `date` 对象一样,`datetime` 假设当前公历向两个方向扩展。像时间对象一样,`datetime`假设每天正好有3600\*24秒。
`datetime` 类的构造函数如下:
**class** datetime.**datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0,tzinfo=None)**
其中,`year`,`month`,`day` 三个参数是必须的。`tzinfo` 可以是 `None` 或 `tzinfo` 子类的实例。其余参数必须是整形,各自的取值范围如下:
* MINYEAR <= year <= MAXYEAR
* 1 <= month <= 12
* 1 <= day <= 给定的年份内给定月份的天数
* 0 <= hour < 24
* 0 <= minute < 60
* 0 <= second < 60
* 0 <= microsecond < 1000000
* fold 0或1
##### 1.2.6.1 datetime对象的类方法
`datetime` 对象有如下几个类方法,同时,这些类方法也是 `datetime` 类的构造方法:
* datetime.today()
返回表示当前本地日期时间的`datetime` 对象,其中 `tzinfo` 参数值为 `None`。该方法的返回值等同于 `datetime.fromtimestamp(time.time())`。
import time as _time
dt = datetime.today()
dt
datetime.datetime(2019, 3, 1, 17, 38, 41, 90585)
* datetime.now(tz=None)
返回表示当前本地日期时间的`datetime` 对象。如果可选参数`tz` 为 `None` 或者未指定,该方法与 `datetime.today()` 方法相似。但是,如果可能,通过 `time.time` 时间戳可以提供更高的精度(例如,这在提供C `gettimeofday()` 函数的平台上是可能的)。
如果 `tz` 参数不为 `None`,则其必须为 `tzinfo` 抽象基类的子类实例,并且当前日期和时间将被转换为使用 `tz` 指定的时区表示。这种情况下,结果等价于:
`tz.fromutc(datetime.utcnow().replace(tzinfo=tz))`。
class GMT1(tzinfo):
… def utcoffset(self, dt):
… return timedelta(hours=1)
… def dst(self, dt):
… return timedelta(0)
… def tzname(self, dt):
… return ‘Europe/Prague’
…
gmt = GMT1()
dt = datetime.now(tz=gmt)
str(dt)
‘2019-03-01 10:52:33.900215+01:00’
* datetime.utcnow()
返回当前UTC日期和时间, `tzinfo` 为 `None`。该方法类似于 `datetime.now()` ,但是返回的是表示当前UTC日期和时间的 `naive`的 `datetime` 对象实例。要获取表示当前UTC日期和时间的 `aware` 的 `datetime` 对象实例,可以使用 `datetime.now(timezone.utc)` 。
dt2 = datetime.utcnow()
dt2
datetime.datetime(2019, 3, 1, 10, 10, 52, 172822)
dt3 = datetime.now(tz=timezone.utc)
dt3
datetime.datetime(2019, 3, 1, 10, 11, 20, 885170, tzinfo=datetime.timezone.utc)
* datetime.fromtimestamp(timestamp, tz=None)
返回POSIX时间戳对应的本地日期和时间,就像 `time.time()` 的返回值。如果可选参数 `tz` 为 `None` 或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的datetime对象是 `naive` 的。
如果 `tz` 不是 `None`,那么它必须是 `tzinfo` 抽象基类的子类的一个实例,并且时间戳被转换为 `tz` 的时区。在这种情况下,结果等价于:
`tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))`。
如果时间戳超出平台C `localtime()` 或 `gmtime()` 函数支持的值的范围,`fromtimestamp()` 可能会引发 `OverflowError` 异常。如果 `localtime()` 或`gmtime()` 执行失败,则会引发 `OSError` 异常。常见的做法是将年份限制在1970到2038之间。注意,对于在时间戳概念中包含闰秒的非posix系统,`fromtimestamp()` 会忽略闰秒,这可能使得两个相差1秒的时间戳产生相同的 `datetime` 实例对象。参见`utcfromtimestamp ()`。
dt = datetime.now()
ts = dt.timestamp()
dt1 = datetime.fromtimestamp(ts)
dt1
datetime.datetime(2019, 3, 1, 18, 24, 18, 317862)
dt2 = datetime.fromtimestamp(ts, tz=gmt)
dt2
datetime.datetime(2019, 3, 1, 11, 24, 18, 317862, tzinfo=<main.GMT1 object at 0x108171668>)
str(dt1)
‘2019-03-01 11:24:18.317862+01:00’
str(dt2)
‘2019-03-01 11:24:18.317862+01:00’
* datetime.utcfromtimestamp(timestamp)
返回与POSIX时间戳对应的UTC `datetime` ,其中 `tzinfo` 为 `None`。如果时间戳超出了平台C `gmtime()`函数支持的值的范围,那么可能会导致 `OverflowError` 异常。如果`gmtime()` 执行失败则会引发 `OSError` 异常。常见的做法是将年份限制在1970到2038之间。
要获取 `aware` 的 `datetime` 对象实例,可以调用 `fromtimestamp()` 方法:
ts = datetime.now().timestamp()
datetime.fromtimestamp(ts, timezone.utc)
datetime.datetime(2019, 3, 1, 10, 33, 45, 746328, tzinfo=datetime.timezone.utc)
在兼容POSIX的平台上,上述方法的返回值等价于以下表达式:
ts = datetime.now().timestamp()
datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=ts)
datetime.datetime(2019, 3, 1, 10, 33, 45, 746328, tzinfo=datetime.timezone.utc)
但后者总是支持完整的年份范围:[MINYEAR, MAXYEAR] 。
* datetime.fromordinal(ordinal)
返回给定的公历序数对应的 `datetime` 对象实例,其中第一年的1月1日的序数为1。如果不满足 `1 <= ordinal <= datetime.max.toordinal()`,则会引发 `ValueError` 异常。其中返回的 `datetime` 对象实例的小时、分钟、秒和微秒都为0,tzinfo为 `None`。
od = date.today().toordinal()
od
737119
datetime.fromordinal(od)
datetime.datetime(2019, 3, 1, 0, 0)
* datetime.combine(date, time, tzinfo=self.tzinfo)
返回一个新的 `datetime` 对象,其日期组件等于给定日期对象的日期组件,其时间组件等于给定时间对象的时间组件。如果提供了 `tzinfo` 参数,则使用其值设置结果的 `tzinfo` 属性,否则使用 `time` 参数的 `tzinfo` 属性。
对于任意 `datetime` 对象 `d`,`d == datetime.combine(d.date(), d.time(), d.tzinfo)`。如果 `date` 的值是 `datetime` 对象,则忽略其时间组件和 `tzinfo` 属性。
d = date.today()
d
datetime.date(2019, 3, 1)
t = time(14, 30, 25)
t
datetime.time(14, 30, 25)
ntd = datetime.combine(d, t)
ntd
datetime.datetime(2019, 3, 1, 14, 30, 25)
ntd1 = datetime.combine(d, t, gmt)
ntd1
datetime.datetime(2019, 3, 1, 14, 30, 25, tzinfo=<main.GMT1 object at 0x108171668>)
str(ntd1)
‘2019-03-01 14:30:25+01:00’
* datetime.fromisoformat(date\_string)
以 `date.isoformat()` 和 `datetime.isoformat()` 发出的格式之一返回 `date_string` 对应的 `datetime` 对象实例。具体来说,该函数支持如下格式的字符串:
`YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]`
其中\*可以匹配任何单个字符。
***警告:这并不支持解析任意的ISO 8601字符串——它只是作为datetime.isoformat()的反向操作。***
dt = datetime.now()
dt.isoformat()
‘2019-03-01T19:04:18.736531’
dt.fromisoformat(dt.isoformat())
datetime.datetime(2019, 3, 1, 19, 4, 18, 736531)
date_str = ‘2019-03-01 19:04:18’
dt.fromisoformat(date_str)
datetime.datetime(2019, 3, 1, 19, 4, 18)
* datetime.strptime(date\_string, format)
返回一个 `date_string` 对应的 `datetime` 对象实例。这相当于如下的表达式的值:
`datetime(*(time.strptime(date_string, format)[0:6]))`
如果 `date_string` 参数和 `format` 参数不能被 `time.strptime()` 解析,或者它们解析后的返回值不是一个时间元组,就会引发 `ValueError` 异常。有关格式化指令的完整列表,请参见 [strftime() and strptime() Behavior]( ).
dt = datetime.strptime(“21/11/06 16:30”, “%d/%m/%y %H:%M”)
dt
datetime.datetime(2006, 11, 21, 16, 30)
##### 1.2.6.2 datetime 对象类属性
* datetime.min
表示 `datetime` 对象实例能表示的最早的日期时间,等同于:
`datetime(MINYEAR, 1, 1, tzinfo=None)`
* datetime.max
表示 `datetime` 对象实例能表示的最晚的日期时间,等同于:
`datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999,tzinfo=None)`
* datetime.resolution
表示两个不相等的 `datetime` 对象实例的最小差值,等同于:
`timedelta(microseconds=1)`
datetime.min
datetime.datetime(1, 1, 1, 0, 0)
datetime.max
datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
datetime.resolution
datetime.timedelta(microseconds=1)
##### 1.2.6.3 datetime对象实例属性
`datetime` 对象实例有如下几个只读属性:
* datetime.year
`datetime` 对象实例的年份
* datetime.month
`datetime` 对象实例的月份
* datetime.day
`datetime` 对象实例的天
* datetime.hour
`datetime` 对象实例的小时
* datetime.minute
`datetime` 对象实例的分钟
* datetime.second
`datetime` 对象实例的秒
* datetime.microsecond
`datetime` 对象实例的微秒
* datetime.tzinfo
`datetime` 对象实例的时区
* datetime.fold
dt = datetime.now(gmt)
dt
datetime.datetime(2019, 3, 1, 12, 25, 58, 595967, tzinfo=<main.GMT1 object at 0x108171668>)
dt.year
2019
dt.month
3
dt.day
1
dt.hour
12
dt.minute
25
dt.second
58
dt.microsecond
595967
dt.tzinfo
<main.GMT1 object at 0x108171668>
`datetime` 对象实例支持如下操作:
| Operation | Result |
| --- | --- |
| datetime2 = datetime1 + timedelta | (1) |
| datetime2 = datetime1 - timedelta | (2) |
| timedelta = datetime1 - datetime2 | (3) |
| datetime1 < datetime2 | (4) 比较两个`datetime` 对象实例 |
(1). 如果 timedelta.days > 0,那么datetime2表示比datetime1更晚的时间;如果如果timedelta.days < 0, 那么datetime2表示比datetime1更早的时间。datetime2与datetime1的 `tzinfo` 属性值相同,并且 `datetime2 - datetime1 == timedelta`。如果datetime2.year 大于MAXYEAR或者datetime2.year小于MINYEAR,将会引发 `OverflowError` 异常。注意,即使 datetime1是 `aware` 的,在计算过程中,也不会出现时区的调整。
(2). 表示计算出一个 `datetime` 对象实例datetime2,使得 datetime2 + timedelta == datetime1。另外,datetime2与datetime1的 `tzinfo` 属性值相同,并且即使datetime1是 `aware` 的,在计算完以后,也不会出现时区的调整。
(3). 只有当两个操作数都是 `aware`的,或者两个操作数都是 `naive` 的,才可以定义从一个 `datetime` 对象实例中减去另一个 `datetime` 对象实例。如果其中一个是 `aware` 的,而另一个是 `naive` 的,则会引发 `TypeError` 异常。
如果两者都是 `naive` 的,或者都是有 `aware` 的,并且具有相同的 `tzinfo` 属性,则将会忽略 `tzinfo` 属性,并且结果会是一个 `timedelta` 对象实例 `t`,使得 datetime2 + t == datetime1。在这种情况下不会做时区调整。
如果两者都是有 `aware` 的,并且具有不同的 `tzinfo` 属性,那么在计算 `a-b` 时会先将a和b转换为 `naive`的UTC日期时间然后再进行计算。在不会溢出的情况下,结果将等于:
(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())。
(4). 当datetime1表示的是比datetime2更早的时间时,我们认为 datetime1小于datetime2。如果一个比较对象是 `naive` 的,而另一个比较对象是 `aware`的,那么如果尝试进行顺序比较时,则会引发 `TypeError` 异常。对于相等比较,`naive` 的 `datetime` 对象实例永远不等于 `aware`的 `datetime` 对象实例。
如果两个比较数都是 `aware` 的,并且具有相同的 `tzinfo` 属性,则忽略公共 `tzinfo` 属性并比较基准日期时间。如果两个比较数都是 `aware` 的并且具有不同的 `tzinfo` 属性,则首先通过减去它们的UTC偏移量(从self.utcoffset()获得)来调整比较数。
***注意,为了防止比较退回到比较对象地址的默认模式,如果另一个操作数不是datetime对象,那么datetime比较通常会引发 `TypeError` 异常。但是,如果另一个比较数具有timetuple()属性,则引发 `NotImplemded` 异常。这个钩子为其他类型的日期对象提供了实现混合类型比较的机会。如果另一个比较数不具有 `timetuple()` 属性,当将datetime对象与另一种类型的对象进行比较时,则会引发 `TypeError` 异常,除非是进行相等比较(==)或不相等比较(!=)。***
`datetime` 对象实例可以作为字典的键。在布尔型上下文中, `datetime` 对象实例总是被当作 `True`。
##### 1.2.6.4 `datetime` 对象的实例方法
* datetime.date()
返回与 `datetime`对象实例有相同的year、month和day属性的 `date` 对象实例。
dt = datetime.now()
dt
datetime.datetime(2019, 3, 2, 16, 47, 22, 670443)
dt.date()
datetime.date(2019, 3, 2)
* datetime.time()
返回与 `datetime`对象实例有相同的hour、minute、second、microsecond、fold属性的 `time` 对象实例,并且tzinfo属性为`None`。
dt = datetime.now()
dt
datetime.datetime(2019, 3, 2, 16, 52, 34, 189630)
t = dt.time()
t
datetime.time(16, 52, 34, 189630)
t.tzinfo is None
True
* datetime.timetz()
返回与 `datetime`对象实例有相同的hour、minute、second、microsecond、fold和tzinfo属性的 `time` 对象实例
dt = datetime.now(tz=gmt)
dt
datetime.datetime(2019, 3, 2, 9, 54, 56, 808581, tzinfo=<main.GMT1 object at 0x108171668>)
t = dt.timetz()
t
datetime.time(9, 54, 56, 808581, tzinfo=<main.GMT1 object at 0x108171668>)
dt.tzinfo == t.tzinfo
True
* datetime.replace(*year=self.year*, *month=self.month*, *day=self.day*, *hour=self.hour*, *minute=self.minute*, *second=self.second*, *microsecond=self.microsecond*, *tzinfo=self.tzinfo*, \*\* fold=0\*)
返回由指定的关键字参数替换`datetime` 对象实例中同名属性值后的新的 `datetime` 对象实例。请注意,可以指定 `tzinfo=None` 来从 `aware` 的 `datetime` 对象实例创建 `naive` 的 `datetime` 对象实例,而不需要转换日期和时间数据。
dt = datetime.now()
dt
datetime.datetime(2019, 3, 2, 17, 2, 16, 122112)
new_dt = dt.replace(year=2008, month=3, day=8, hour=14, minute=30, second=45, microsecond=9000, tzinfo=gmt, fold=1)
new_dt
datetime.datetime(2008, 3, 8, 14, 30, 45, 9000, fold=1, tzinfo=<main.GMT1 object at 0x108171668>)
* datetime.astimezone(tz=None)
返回带有新 `tzinfo` 属性 `tz` 的 `datetime` 对象实例,调整日期和时间数据使结果与 `self` 的UTC时间相同,但为用 `tz` 表示的本地时间。
如果为 `tz` 参数提供非 `None` 值,则该值必须是 `tzinfo` 子类的实例,并且其 `utcoffset()` 和 `dst()` 方法不得返回 `None` 。`self` 必须是 `aware` 的(`self.tzinfo`不能是`None`,以及`self.utcoffset()`不能返回`None`)。
如果不带参数调用(或`tz=None`),则假定使用系统本地时区。转换后的 `datetime` 实例的`tzinfo`属性将设置为 `timezone` 的实例,其带有从操作系统获取的时区名称和偏移量。
如果`self.tzinfo` 与 `tz` 参数值相同,则 `self.astimezone(tz)` 等于 `self` ,并且日期和时间数据不会调整。否则结果是使用时区 `tz` 表示的本地时间,表示与 `tz` 相同的UTC时间。`astz = dt.astimezone(tz)` 之后,`astz -astz.utcoffset()`通常具有与`dt - dt.utcoffset()`相同的日期和时间数据。类 `tzinfo` 的讨论解释了无法实现的在夏令时转换边界的情况(仅当 `tz` 同时建模标准时和夏令时的时候才出现问题)。
如果你只想在不调整日期和时间数据的情况下将时区对象 `tz` 附加到 `datetime` 实例对象 `dt`,请使用 `dt.replace(tzinfo=tz)`。如果你只想从 `aware` 的 `datetime` 实例对象 `dt` 中删除时区对象而不转换日期和时间数据,请使用 `dt.replace(tzinfo=None)`。
请注意,可以在 `tzinfo` 子类中覆盖默认的 `tzinfo.fromutc()` 方法,以影响 `astimezone()` 返回的结果。忽略错误情况,`astimezone()` 的行为如下:
def astimezone(self, tz):
if self.tzinfo is tz:
return self
# Convert self to UTC, and attach the new time zone object.
utc = (self - self.utcoffset()).replace(tzinfo=tz)
# Convert from UTC to tz’s local time.
return tz.fromutc(utc)
该方法使用示例:
class TestGMT(tzinfo):
… def utcoffset(self, dt):
… return timedelta(hours=1)
… def dst(self, dt):
… return timedelta(0)
… def tzname(self, dt):
… return ‘Europe/Prague’
…
gmt = TestGMT()
dt = datetime.now()
dt
datetime.datetime(2019, 3, 4, 0, 43, 13, 363694)
dt1 = dt.astimezone()
dt1
datetime.datetime(2019, 3, 4, 0, 43, 13, 363694, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800), ‘CST’))
dt1.tzinfo
datetime.timezone(datetime.timedelta(seconds=28800), ‘CST’)
dt1.tzname()
‘CST’
dt2 = dt1.astimezone(tz=gmt)
dt2
datetime.datetime(2019, 3, 3, 17, 43, 13, 363694, tzinfo=<main.TestGMT object at 0x10462e978>)
dt2.tzinfo
<main.TestGMT object at 0x10462e978>
dt2.tzname()
‘Europe/Prague’
* datetime.utcoffset()
返回使用 `datetime.timedelta` 对象实例表示的 `datetime` 实例对象的时区偏移量。如果 `datetime` 对象实例的 `tzinfo` 属性为 `None`,则返回 `None`;否则返回 `self.tzinfo.utcoffset(self)` 的返回值;如果该方法的返回值不是 `None` 或者一个小于一天的 `timedelta` 对象,则会引发异常。
class GMT1(tzinfo):
… def utcoffset(self, dt):
… return timedelta(hours=1)
… def dst(self, dt):
… return timedelta(0)
… def tzname(self, dt):
… return ‘Europe/Prague’
…
gmt = GMT1()
dt = datetime.now(gmt)
dt
datetime.datetime(2019, 3, 2, 18, 54, 39, 389884, tzinfo=<main.GMT1 object at 0x10751e390>)
dt.utcoffset()
datetime.timedelta(seconds=3600)
dt1 = datetime.now()
dt1.utcoffset() is None
True
* datetime.dst()
返回使用 `datetime.timedelta` 对象实例表示的 `datetime` 实例对象的时区偏移量。如果 `datetime` 对象实例的 `tzinfo` 属性为 `None`,则返回 `None`;否则返回 `self.tzinfo.dst(self)` 的返回值;如果该方法的返回值不是 `None` 或者一个小于一天的 `timedelta` 对象,则会引发异常。
dt = datetime.now(gmt)
dt.dst()
datetime.timedelta(0)
dt1 = datetime.now()
dt1.dst() is None
True
* datetime.tzname()
返回 `datetime` 实例对象的时区名称。如果 `datetime` 实例对象的 `tzinfo` 属性是 `None`,则返回 `None`,否则返回 `self.tzinfo.tzname(self)`。如果该方法的返回值不是 `None` 或者自一个字符串对象,则会引发异常。
dt = datetime.now(gmt)
dt.tzname()
‘Europe/Prague’
dt1 = datetime.now()
dt1.tzname() is None
True
* datetime.timetuple()
返回一个 `time.struct_time` 对象实例,类似于 `time.localtime()` 的返回值。如果 `d` 是一个`datetime`对象的实例,那么,`d.timetuple()` 等价于以下表达式:
***time.struct\_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, -1))***
其中,yday = d.toordinal() - date(d.year, 1, 1) + 1 。
`tm_isdst` 的取值由 `dst()` 方法的返回值决定:如果 `tzinfo` 是 `None` 或者 `dst()` 的返回值是 `None`,`tm_isdst` 的值将取-1;如果 `dst()` 方法的返回值是一个非零值,那么 `tm_isdst` 的值取1,否则,`tm_isdst` 的值取0。
dt = datetime.now(gmt)
dt.timetuple()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=2, tm_hour=19, tm_min=0, tm_sec=35, tm_wday=5, tm_yday=61, tm_isdst=0)
dt1 = datetime.now()
dt1.timetuple()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=3, tm_hour=1, tm_min=59, tm_sec=48, tm_wday=6, tm_yday=62, tm_isdst=-1)
* datetime.utctimetuple()
如果 `datetime` 实例 `d` 是 `naive` 的,那么这个方法的返回值与 `timetuple()` 方法的返回值相似,只是`tm_isdst` 被强制设置为0,而不管 `d.dst()`的返回值是什么。
如果 `d` 是 `aware` 的,则通过减去 `d.utcoffset()`,将 `d` 规范化为UTC时间,然后返回这个规范化时间的`struct_time`,并且 `tm_isdst` 强制为0。请注意,如果 `d.year` 是MINYEAR或MAXYEAR,并且UTC调整超出了一年的边界,那么可能会引发 `OverflowError` 异常。
dt = datetime.now() # 当datetime实例是’naive’的时
dt.utctimetuple()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=3, tm_hour=2, tm_min=40, tm_sec=7, tm_wday=6, tm_yday=62, tm_isdst=0)
dt1 = datetime.now(gmt) # 当datetime实例是’aware’的时
dt1.utctimetuple()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=2, tm_hour=18, tm_min=40, tm_sec=34, tm_wday=5, tm_yday=61, tm_isdst=0)
dt1.utctimetuple() == (dt1 - dt1.utcoffset()).timetuple()
True
* datetime.toordinal()
返回日期的预期公历序号。与 `self.date().toordinal()` 的值相同。
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、学习软件
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
三、全套PDF电子书
书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。
四、入门学习视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
五、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!