python的时间处理模块主要有time,datetime,calendar几个模块,对时间的处理,python已经封装的比较完美,比如对时间进行计算,格式化时间等等操作。
简要的术语
UTC:是协调世界时(以前称为格林威治标准时间,或GMT),中国是UTC+8
DST:是夏令时,在一部分时间内通过(通常)一个小时调整时区,比如夏天日照时间较长,人为的调整了时间提前一小时,让人们提前进入工作
起始时间点:一般是从1970年1月1日0时开始,当然这个不是一定的,你可以通过gmtime(0)
来获取你系统的起始时间点,注意大多数总时间都是浮点类型的,而不是整形的
time模块:由于datetime模块里面有一个类也叫time,所以为了区分,datetime模块里面的time一律使用datetime.time的方式来描述,而直接使用time则表示的是time这个独立的模块而不是datetime里的time类
time模块
要使用time模块里面的功能,需要先引入time模块:
import time
time模块里面经常用到一个数据类型struct_time
,它是一个类,继承了tuple
,一般我们会用到它的如下几个属性:
比如有现在有人返回了一个time_struct
对象t
,我们可以通过t[0]
或者t.tm_year
的方式获得这个对象所代表的年份是多少,其它几个属性类似。这个结构非常常用,time模块里面至少有6个常用的函数会用它作为参数或者返回一个这样的实例,用它的实例作为参数的函数有asctime mktime strftime
,返回它的实例的函数有gmtime localtime strptime
常用的几个函数:
In [60]: import time
In [61]: time.gmtime()
Out[61]: time.struct_time(tm_year=2018, tm_mon=7, tm_mday=24, tm_hour=10, tm_min=9, tm_sec=43, tm_wday=1, tm_yday=205, tm_isdst=0)
In [62]: time.localtime()
Out[62]: time.struct_time(tm_year=2018, tm_mon=7, tm_mday=24, tm_hour=18, tm_min=9, tm_sec=46, tm_wday=1, tm_yday=205, tm_isdst=0)
In [63]: time.strptime("20180710192018", "%Y%m%d%H%M%S")
Out[63]: time.struct_time(tm_year=2018, tm_mon=7, tm_mday=10, tm_hour=19, tm_min=20, tm_sec=18, tm_wday=1, tm_yday=191, tm_isdst=-1)
In [64]: time.asctime()
Out[64]: 'Tue Jul 24 18:12:51 2018'
In [65]: time.mktime(time.localtime())
Out[65]: 1532427184.0
In [66]: time.strftime("%Y%m%d%H%M%S")
Out[66]: '20180724181331'
In [67]: time.time()
Out[67]: 1532427216.649
说明:
time.time()
函数返回当前本地时间从1970年1月1日0时的总秒数asctime([t])
可以接受一个time_struct的参数,返回一个类似'Tue Jul 24 18:12:51 2018'
格式的字符串,参数默认值是locatime
的返回值mktime(t)
,是localtime
函数的反函数,把struct_time
格式的转换为特定的秒strftime(fmt[, t])
,把struct_time
格式的时间转换为指定的字符串表示,其中t
参数的默认值是localtime
的返回值gmtime([t])
,参数的默认值是time.time()
的返回值,返回一个struct_time
对象,如果参数传递是0,那么就可以获取到系统的起始时间了localtime([t])
,参数默认值是time.time()
的返回值,返回一个struct_time
对象,与gmtime
不同的是,gmtime
返回UTC时间,而localtime
返回的是本地时间,比如中国gmtime
获取到的时间会比localtime
少8个小时strptime(s, fmt)
,需要两个参数,第一个是时间的字符串表示,第二个参数是格式化字符串,返回一个struct_time
对象
字符串格式化支持下面的方式(常用的用红框标识起来了):
当然time模块还有个常用的函数time.sleep(t)
,可以让线程挂起指定的秒数。
datetime模块
datetime模块下面有几个常用类,分别是datetime date time timedelta
。他们的继承关系如下:
object
timedelta
tzinfo
timezone
time
date
datetime
timedelta
timedelta
是表示时间的间隔,也就是表示两个时间的差值,看一下定义:
class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
也就是说,我们可以按照days(天), hours(小时)等方式构造这个对象,直接上代码:
In [26]: import datetime
In [27]: d = datetime.datetime.now() #获取到了当前时间,参考Out[29]
In [28]: delta = datetime.timedelta(hours=1) #构造了一个时间差对象,使用1小时作为差值
In [29]: d
Out[29]: datetime.datetime(2018, 7, 24, 19, 9, 31, 5000)
In [30]: delta
Out[30]: datetime.timedelta(0, 3600)
In [31]: d1 = d + delta #当前时间+1小时的差值
In [32]: d1
Out[32]: datetime.datetime(2018, 7, 24, 20, 9, 31, 5000) #19点变成了20点
In [33]: d2 = d - delta #当前时间-1小时的差值
In [34]: d2
Out[34]: datetime.datetime(2018, 7, 24, 18, 9, 31, 5000) #19点变成了18点
In [43]: new_delta = d1 - d #相当于是两个datetime对象进行运算,产生的是一个timedelta对象
In [44]: new_delta
Out[44]: datetime.timedelta(0, 3600)
In [45]: new_delta.seconds # 3600秒,也就是1个小时
Out[45]: 3600
In [46]: new_delta.days
Out[46]: 0
注意: timedelta对象只有
days seconds microseconds
三个属性可以访问,不要以为在创建的时候可以传递hours weeks
等参数,就同样可以获取一样,实际是不能获取到的,比如:
In [47]: delta = datetime.timedelta(weeks=1)
In [48]: delta
Out[48]: datetime.timedelta(7)
In [49]: delta.days
Out[49]: 7
In [50]: delta.seconds
Out[50]: 0
In [52]: delta = datetime.timedelta(minutes=1)
In [53]: delta.days
Out[53]: 0
In [54]: delta.seconds
Out[54]: 60
date
也就是只有日月年的时间表示,常用的产生date
对象常用的两种方式是,直接初始化,比如:
import datetime
d = datetime.date(2018, 09, 11) #产生的就是2018年09月11日
上面的方法是定制化时间,我们如果想要获取本地的当前时间,可以使用:
import datetime
d = datetime.date.today() #返回的就是本地的当前时间
其实
datetime.date.fromtimestamp()
和datetime.datetime().date()
也算是产生date
对象的方式。
date
对象有三个属性year, month, day
分别获取到年月日
还可以和time
模块进行转换:
import datetime
import time
d = datetime.date.fromtimestamp(time.time()) # 从time转换为date
st = d.timetuple() # 从date转换为struct_time
其中fromtimestamp
是从一个时间戳转换为一个date
对象,比如转换为了datetime.date(2018, 7, 24)
,而timetuple
可以把当前的date
对象转换为time
模块的struct_time
对象,但是只保留了年月日,时分秒被置为了0,比如转换为了time.struct_time(tm_year=2018, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=205, tm_isdst=-1)
time
只能通过下面一种方式产生datetime.time
对象:
class datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
datetime().datetime().time()
也是产生datetime.time
对象的一种方式。
这个对象的几个属性和参数一样,都支持访问,比如有一个datetime.time
实例t
,可以通过t.hour
访问小时属性。
datetime
datetime.datetime
是datetime.date
和datetime.time
的综合,可以通过如下集中方式进行创建:
class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
classmethod datetime.today()
classmethod datetime.now(tz=None)
classmethod datetime.fromtimestamp(timestamp, tz=None)
classmethod datetime.strptime(date_string, format)
而且我们可以(假设d是datetime实例)通过d.date()
和d.time()
返回datetime.data
和datetime.time
对象。同理可以通过d.year d.month d.day d.hour d.minute d.second
等方式访问年月日时分秒信息。
周的处理
周的处理有时候关心的较少,但是又会使用到,所以单独列举出来。
总结
- 几个时间对象其实都有
strftime
函数,用于格式化时间为字符串形式的表示,其中time datetime.datetime
有strptime
函数,用于把格式化的时间字符串转换成time
或者datetime.datetime
对象 -
struct_time
和datetime的date datetime
之间可以相互转换,转换函数是fromtimestamp timetuple
,但是不能和datetime.time
进行转换,说白了,datetime.time
只是一个有时分秒信息的对象,没有具体的日期,根本无法计算是具体的哪一天 - 同样,
datetime.time
是不支持运算的,也就没有和timedelta
相关的操作了