python中处理时间的模块有三个,datetime, time,calendar,融汇贯通三个模块,才能为所欲为地用python处理时间。本文就是为此而写,文章着重点在于梳理出三个模块的设计脉络,便于你们记忆里面的api。在须要的时候可以去查找相应的方法。但因为calendar模块使用很少,限于篇幅,本文没有涉及。python
datetime模块主要是用来表示日期的,就是咱们常说的年月日时分秒,calendar模块主要是用来表示年月日,是星期几之类的信息,time模块主要侧重点在时分秒,粗略从功能来看,咱们能够认为三者是一个互补的关系,各自专一一块。方便用户依据不一样的使用目的选用趁手的模块。linux
为了学习time模块,咱们须要先知道几个与时间相关的概念:api
假设咱们要将时间表示成毫秒数,比方说1000000毫秒,那有一个问题必须解决,这个1000000毫秒的起点是什么时间,也就是咱们的时间基准点是什么时间?比如我说你身高1.8米,那这个身高是指相对于你站立的地面说的。这个时间基准点就是epoch,在Unix系统中,这个基准点就是1970年1月1日0点整那个时间点。app
上面咱们说epoch表示1970年的起始点,那这个1970年又是相对于哪一个基准时间呢?通常来讲,就是相对于格林尼治时间,也叫作GMT(Greenwich Mean Time)时间,还叫作UTC(Coordinated Universal Time),为啥一个时间基准有两个名字?历史上,先有的GMT,后有的UTC.ide
UTC是咱们如今用的时间标准,GMT是老的时间计量标准。UTC是根据原子钟来计算时间,而GMT是根据地球的自转和公转来计算时间。函数
因此,能够认为UTC是真正的基准时间,GMT相对UTC的误差为0。学习
在实际中,咱们的计算机中有一个硬件模块RCT,里面会实时记录UTC 时间,该模块有单独的电池供电,即便关机也不影响。spa
有了epoch这个时间基准,又有了UTC这个基准的基准,咱们就能够精确地表示一个时间了。设计
尽管咱们已经能够精确地表示一个时间,不少状况下,咱们仍是要根据地区实际状况对时间进行一个调整,最多见的就是时区,tzone,相信你们都比较熟悉。orm
此时,当咱们说5点5分这个时间时,还需加上是哪一个时区的5点5分才能精确说明一个时间。
另一个对时间作出调整的就是DST.
DST 全称是Daylight Saving Time,是说,为了充分利用日光,减小用电,人为地对时间作出一个调整,这取决于不一样国家和地区的政策法规。好比说,假设你冬天7点天亮起床,但夏天6点天亮,那么在夏天到来时人为将时间加1个小时,这样就可让你仍是以为7点起床,但其实是提早一个小时了。
那么,好奇的咱们,必定要问一问,python是如何知道tzone和DST这两个的值呢?答案是经过环境变量。
这里咱们只以linux为例来讲明一下。
在linux中有TZ环境变量,其值相似这样:
CST+08EDT,M4.1.0,M10.5.0,这个字符串能够作以下解读,用空格分开他们,分红三部分
CST+08 EDT, M4.1.0,M10.5.0
第一部分中的CST表示时区的名字,即China Standard Time,也就是咱们说的北京时间,+8表示北京时间加上8小时就是UTC时间
第二部分EDT表示DST的名字,咱们说DST是因各个国家地区的政策法规不一样而不一样的,EDT后面也能够像CST后面同样加一个时间调整值,但因为咱们国内只在86年到92年实行过一段时间DST,如今已经废止,因此后面不用加调整时间。
第三部分表示的是实行DST的开始和结束时间,咱们就不细解读了。
time模块中获取时间的基本方法是
t = time.time()
它返回的是从epoch到如今的秒数(用浮点数表示),用的是UTC时间。
咱们天然而然地想把这个秒数转为年月日时分秒的形式,而这种转换又分两种,一种仍是用UTC时间,一种用咱们所在时区进行调整后的时间。
time模块给咱们提供了两个方法,
time. gmtime(t)
time.localtime(t)
两者都返回一个类struct_time的实例,该实例具备以下属性:
相比用秒数表示的时间,这样的表示更适合咱们理解。
这两个函数若是调用时不传参数,它们内部会调用time.time(),并用返回的秒数作转换。
相反的,python一样提供了将这两种struct_time转为秒数的方法。
calendar.timegm()方法用来把UTC的struct_time(gmtime的返回对象)转为从epoch开始的秒数
time.mktime()用来把用时区调整过的struct_time(即localtime的返回对象)对象转为从epoch开始的秒数
也就是说mktime方法会先找到系统中的时区和DST信息,并利用这个信息对struct_time进行调整后再换算成秒数。
另外一种常见的需求是在时间和表示时间的字符串之间进行转换。
time模块中的strftime和strptime就是作这个用的。
看名字你们就应该知道它们的含义,
strftime 即 string format time,用来将时间格式化成字符串
strptime 即string parse time,用来将字符串解析成时间。
须要注意的是,这里的时间都是struct_time对象。
关于怎么格式化时间,是很简单的知识,这里就借用官网文档的内容了。
除了这两个函数,time模块中还提供了两个简便方法,来帮助将时间转为字符串
asctime用来将一个struct_time对象转为标准24字符的字符串,以下所示:
Sun Jun 20 23:21:05 1993
ctime方法与asctime做用相同,只不过它接收的是秒数,在内部,会先把秒数经过localtime转为struct_time,再日后就与asctime同样了。
以上就是time模块的核心内容,我尝试用一个口诀帮助记忆这些API
time点time得秒数
传入gm, local time得struct_time
要想变回原秒数
你得传回calendar.timegm和time. mktime
string f和string p
格式化时间靠哥俩
你要仍是嫌费事
asctime ,ctime来助力
专门帮你转字符串
前者接收struct_time
后者专门处理秒数
分工合做不费力
学好time模块基本功
作个时间的明白人!
下面,咱们要开始学习datetime模块。
time模块解决了时间的获取和表示,datetime模块则进一步解决了快速获取并操做时间中的年月日时分秒信息的能力。
简单说,该模块核心的类就三个,date类表示年月日,time类表示时分秒毫秒,这里不要和time模块搞混淆了。一句顺口溜能够帮助记清这个状况:
time里面没time
藏在datetime里
编的是否是不咋地?嗯,我也这么以为。
datetime类就是date和time的组合。
有一点须要提早说明一下,time类和datetime类都有一个属性,它的值是一个tzinfo对象,里面包含了该time或者datetime的时区信息,通常称这个time或者datetime对象是aware的,它可以准确换算成自epoch开始的秒数。
若是该属性设置为None,那么,这时的time对象或者datetime对象就没有时区信息,具体它表示的是local time仍是utc time,须要咱们本身在程序中去决定。
这里咱们所说的local time是指咱们所在时区的时间, utc time指的就是国际标准时间,也就是格林尼治时间。下文同。
请记住一点,date中是没有时区信息的。
建立datetime对象,我最经常使用的办法以下
dt=datetime.datetime.fromtimestamp(time.time())
以上,time.time()得到自epoch开始的秒数,fromtimestamp方法会将这个秒数转变成一个datetime对象。
这里有一个问题,这个datetime对象到底是utc的仍是local的?
答案是local的,这是该方法的默认行为。若是你在fromtimestamp方法中传入一个表示时区的参数,即tzinfo对象,就会按传入的时区信息进行转换。
得到表示当前local时间的datetime对象,还有两个简便方法
datetime. datetime. now()
datetime. datetime. today()
以上咱们获得的都是local的datetime对象,如何得到utc的datetime对象呢?有两个办法
datetime. datetime. utcfromtimestamp()
datetime. datetime. utcnow()
咱们还能够从字符串中建立datetime对象,
方法为datetime.striptime(date_string, format)
其内部仍是先调用的time模块中的striptime方法,获取struct_time对象,再利用struct_time对象中的年月日时分秒信息构建datetime对象。
一样的,datetime类也提供了strftime(),asctime(),ctime()方法,相信不说你也知道是作什么的了。
datetime类还提供了一个combine方法,用来将一个date对象和一个time对象组合成一个datetime对象。
须要注意的是,datetime模块中出现timestamp时,通常可将其理解成time.time()返回的秒数
date对象的建立和datetime很是类似,
datetime. date. today()
datetime.date.fromtimestamp()均可以建立一个date对象。
固然,你也能够经过构造方法传入年月日来建立date对象。
相比之下,time对象的建立就颇有限,只能经过
datetime.time([hour[, minute[, second[, microsecond[, tzinfo]]]]])
这个方法建立。
在实际使用中,咱们有一大块需求就是对日期进行比较和加减运算。得益于python的操做符重载能力,python中能够方便地对
date对象之间,或者datetime对象之间进行小于(<)比较和减法(-)操做。
注意,这里仅限于同类对象之间,并且,不包括time对象之间。
两个date对象做减,或者两个datetime对象之间做减,差值用一个timedelta对象表示。
同理,一个date 对象或者datetime对象也能够加或者减一个timedelta对象。
一个timedelta对象含有三个属性:days,seconds, microseconds,days属性能够取负值,另外两个属性都只能是正值。
你能够用total_seconds()方法得到一个timedelta对象的秒数表示。
两个timedelta对象之间可加,可减,但不能作大小比较,由于这样没什么意义。
一个timedelta对象还能够与整数相乘,或经过//操做与一个整数相除。
还能够取反,或者用abs函数得到绝对值
本文的目的不在于详细说明python处理时间日期的api如何使用,而是想经过一个概览的形式,让你们抓住time和datetime模块的设计结构,从而可以清楚这些模块提供了哪些能力,在须要的时候可以想起来去用,至于查详细的api,应该是能够轻松解决的。