一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试宝典
简历模板
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
默认实现的 utcoffset()
引发 NotImplementedError
异常。
- tzinfo.dst(dt)
如果DST信息未知,则返回 None
,否则返回以 timedelta
对象实例表示的夏令时(DST)调整(UTC以东为正,UTC以西为负)。如果DST不起作用,则返回 timedelta(0)
。如果DST有效,则返回以 timedelta
对象表示的偏移量(有关详细信息,请参阅 utcoffset()
)。请注意,DST偏移(如果适用)已添加到 utcoffset()
返回的UTC偏移,因此,除非你感兴趣,否则不需要单独调用 dst()
获得DST信息。例如,datetime.timetuple()
调用其 tzinfo
属性的 dst()
方法来确定 tm_isdst
应如何设置,并且 tzinfo.fromutc()
调用 dst()
来计算跨越时区的DST更改。
对标准时和夏令时同时进行建模的 tzinfo
子类的实例 tz
必须在此意义上保持一致:
tz.utcoffset(dt) - tz.dst(dt)
必须对每个 datetime
对象的实例 dt
返回相同的结果 dt.tzinfo == tz
。对于正确的 tzinfo
子类,此表达式生成的时区的 “标准偏移量” 不应取决于日期或时间,而只取决于地理位置。datetime.astimezone()
方法的实现依赖于此,但不能检测不符合规则的 dst()
方法,必须由程序员来确保 dst()
方法得到了正确实现。如果tzinfo
子类不能保证这一点,那么 tzinfo
子类可以覆盖 tzinfo.fromutc()
的默认实现以确保 astimezone()
能够正确工作。
大多数dst()
的实现可能看起来像以下两种:
def dst(self, dt):
# a fixed-offset class: doesn't account for DST
return timedelta(0)
或者
def dst(self, dt):
# Code to set dston and dstoff to the time zone's DST
# transition times based on the input dt.year, and expressed
# in standard local time. Then
if dston <= dt.replace(tzinfo=None) < dstoff:
return timedelta(hours=1)
else:
return timedelta(0)
默认实现的 dst()
引发 NotImplementedError
异常。
- tzinfo.tzname(dt)
将与 datetime
对象实例 dt
对应的时区名称作为字符串返回。datetime
模块没有定义有关字符串名称的内容,并且没有要求它有任何特别的意思,例如 “GMT”、“UTC”、“-500”、“-5:00”、“EDT”、“US/Eastern” 都是有效的返回。如果字符串名称未知,则返回 None
。注意,这是一种方法而不是固定字符串,主要是因为一些 tzinfo
子类希望根据传递的 dt
的具体值返回不同的名称,特别是如果 tzinfo
类正在考虑夏令时。
默认实现的 tzname()
引发 NotImplementedError
。
这些方法由 datetime
或 time
实例对象调用,以对应其相同名称的方法。一个 datetime
对象传递自身作为参数,而一个 time
对象传递 None
作为参数。因此,tzinfo
子类的方法应该准备接受 None
或类 datetime
的实例 dt
作为参数。
当传递的是 None
时,由类设计器决定最佳响应。例如,如果类想要 time
对象不参与 tzinfo
协议,则返回None
是适当的。如果没有发现标准偏移量的其他约定, utcoffset(None)
返回标准UTC偏移量可能更有用。
当将 datetime
对象传递给datetime
对象实例的方法时,dt.tzinfo
与 self
是同一个对象 。除非用户代码直接调用 tzinfo
方法,否则可以通过 dt.tzinfo
实现调用。这样可以使得 tzinfo
方法将 dt
解释为本地时间,而不是其他时区的时间。
还有一个子类可能希望覆盖的方法:
- tzinfo.fromutc(dt)
这是从默认的 datetime.astimezone()
实现中调用的。当从中调用时,dt.tzinfo
为 self
,并且 datetime
对象的实例 dt
的日期和时间数据被视为表示UTC时间。fromutc()
的目的是调整日期和时间数据,返回使用 datetime
对象实例表示的与UTC时间一致的本地时间。
大多数 tzinfo
子类应该能够继承默认的 fromutc()
实现并且不会出问题。它足够强大得以能够处理固定偏移量的时区和既考虑标准时又考虑夏令时的时区,即使后者DST转换时间在不同年份有所不同。默认fromutc()
实现可能无法正确处理由于政治原因导致的标准偏移量(来自UTC)取决于特定的日期和时间的时区。如果结果是跨越标准偏移量变化的时间之一,则 astimezone()
和 fromutc()
的默认实现可能无法产生所需的结果。
跳过错误处理的代码,默认的 fromutc()
实现的行为与以下代码类似:
def fromutc(self, dt):
# raise ValueError error if dt.tzinfo is not self
dtoff = dt.utcoffset()
dtdst = dt.dst()
# raise ValueError if dtoff is None or dtdst is None
delta = dtoff - dtdst # this is self's standard offset
if delta:
dt += delta # convert to standard local time
dtdst = dt.dst()
# raise ValueError if dtdst is None
if dtdst:
return dt + dtdst
else:
return dt
下面的代码是一些 tzinfo
类的子类实现:
from datetime import tzinfo, timedelta, datetime
ZERO = timedelta(0)
HOUR = timedelta(hours=1)
SECOND = timedelta(seconds=1)
# 捕获平台的本地时间概的类。
# (在UTC偏移量和/或DST规则在过去发生过更改的时区,可能会导致历史时间的值出现错误。)
import time as _time
STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def fromutc(self, dt):
assert dt.tzinfo is self
stamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECOND
args = _time.localtime(stamp)[:6]
dst_diff = DSTDIFF // SECOND
# Detect fold
fold = (args == _time.localtime(stamp - dst_diff))
return datetime(\*args, microsecond=dt.microsecond,
tzinfo=self, fold=fold)
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def \_isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
# A complete implementation of current DST rules for major US time zones.
def first\_sunday\_on\_or\_after(dt):
days_to_go = 6 - dt.weekday()
if days_to_go:
dt += timedelta(days_to_go)
return dt
# US DST Rules
#
# 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
的构造过程如下:
- 将毫秒转化为微秒:10 milliseconds = 1000*10 microseconds =10000 microseconds
- 将分钟转化为秒:10 minutes = 60*10 seconds = 600 seconds
- 将小时转化为秒:10 hours = 3600*10 seconds = 36000 seconds
- 将星期转化为天:10 weeks = 7*10 days = 70 days
- 计算毫秒和微秒之和得到 microseconds参数的值:10000 microseconds + 10 microseconds = 10010 microseconds
- 计算分钟、小时和秒之和得到seconds参数的值:600 seconds + 36000 seconds + 10 seconds = 36610 seconds
- 计算星期和天之和得到days参数的值:70 days + 10days = 80 days
- 判断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)
- 将毫秒转化为微秒:10 milliseconds = 1000*1000 microseconds =1000000 microseconds
- 将分钟转化为秒:10 minutes = 60*10 seconds = 600 seconds
- 将小时转化为秒:10 hours = 3600*25 seconds = 90000 seconds
- 将星期转化为天:10 weeks = 7*10 days = 70 days
- 计算毫秒和微秒之和得到 microseconds参数的值:1000000 microseconds + 10 microseconds = 1000010 microseconds
- 计算分钟、小时和秒之和得到seconds参数的值:600 seconds + 90000 seconds + 10 seconds = 90610 seconds
- 计算星期和天之和得到days参数的值:70 days + 10days = 80 days
- 判断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 "<stdin>", line 1, in <module>
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 "<stdin>", line 1, in <module>
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()
的值相同。
>>> dt = datetime.now()
>>> dt.toordinal()
737121
>>> dt.date().toordinal()
737121
- datetime.timestamp()
返回与 datetime
实例对应的POSIX时间戳。返回值是一个类似于time.time()返回值的浮点数。
假定本地时间使用 navi
的 datetime
实例表示,并且该方法依赖于平台的C语言的 mktime()
函数执行转换。由于在许多平台上 datetime
支持的值比 mktime()
的范围更广,因此这种方法可能会在过去或未来很长一段时间内产生OverflowError
异常。
对于 aware
的 datetime
实例,返回值由下面的表达式计算:
(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()
>>> import time as _time
>>> dt = datetime.now()
>>> dt.timestamp()
1551552673.72456
>>> _time.time()
1551552686.284929
- datetime.weekday()
返回当前日期在一周内的序号,即星期几,其中周一表示为0,周日表示为6。
>>> dt = datetime.now()
>>> dt.weekday()
6
>>> dt.date().weekday()
6
- datetime.isoweekday()
返回当前日期在一周内的序号,即星期几,其中周一表示为1,周日表示为7。
>>> dt = datetime.now()
>>> dt.isoweekday()
7
>>> dt.date().isoweekday()
7
- datetime.isocalendar()
返回一个包含给定日期时间对象的ISO year、ISO week number和ISO weekday的三元组。
>>> dt = datetime.now()
>>> dt.isocalendar()
(2019, 9, 7)
>>> dt.date().isocalendar()
(2019, 9, 7)
- datetime.isoformat(sep=‘T’, timespec=‘auto’)
返回一个使用 ISO 8601格式表示 datetime
实例的日期和时间的字符串。
如果给定实例的 microsecond
属性值不是0,那么具体格式为 YYYY-MM-DDTHH:MM:SS.ffffff
。
如果给定实例的 microsecond
属性值是0,那么具体格式为 YYYY-MM-DDTHH:MM:SS
。
如果给定实例的 utcoffset
方法返回值不是 None
,则会附加一个字符串用来给出UTC偏移量,此时,字符串格式如下:
YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]
;
如果给定实例的 microsecond
属性值是0,字符串的格式如下:
YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]
;
可选参数 sep
(默认值为’T’) 是一个单字符分隔符,用来分隔结果中的日期和时间部分,例如:
### 一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
![](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
### 二、学习软件
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
![](https://img-blog.csdnimg.cn/img_convert/8c4513c1a906b72cbf93031e6781512b.png)
### 三、入门学习视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
![](https://img-blog.csdnimg.cn/afc935d834c5452090670f48eda180e0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5bqP5aqb56eD56eD,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618317507)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**