Loading

python时间处理

Python提供了三种时间处理模块,分别是time、datetime和calendar,这三个模块均被收录到Python标准库中。

概述

  • time模块主要用三种表现形式来表示时间,分别是时间戳、结构化时间、格式化时间字符串,在官方文档中,time是归类在Generic Operating System Services中,提供的功能更加贴近于操作系统层面的,主要是围绕着Unix Timestamp进行 的。

  • datetime模块重新封装了time模块,提供了更多的函数,提供的类包含time、date、datetime、timedelta、tzinfo。通常来处理常用的年月日时分秒。

  • calendar模块有很广泛的方法用来处理年历和月历,一般用来表示年月日、星期几之类的信息。

    粗略从功能上看,可以认为三者是一个互补关系,侧重点不同。

基本概念

epoch

​ 我们经常可以看到时间戳表示为毫秒数,比如1596425403毫秒,那这个毫秒是从什么起点开始计算的呢?比如一个人身高是1.8米,那这个身高就是相对于地面的这个基准点来说的。时间的基准点就是epoch,在Unix上,epoch就是UTC时间1970年1月1日 00:00:00

GMT&UTC

epoch的基准点是1970年1月1日 00:00:00,这个时间又叫做格林尼治时间,也叫做GTM(Greenwich Mean Time)或者UTC(Coordinated Universal Time)。

  • GTM是指位于伦敦郊区的皇家格林尼治天文台时间。以地球自转和公转来计时。

  • UTC别称世界标准国际协调时间,以原子时计时,更加精确,比如北斗全球定位系统的卫星上搭载的就是原子钟。

在实际生活中,计算机中一般有一个硬件模块RCT,由独立的电池驱动,即便关机仍然可以正常运行。

时区

​ 生活中特别是国际新闻中经常听到东八区18:50分,很多时候需要根据地区的实际情况对时间进行调整,这种表达方式就是时区tzone。另一个对时间做出调整的的就是DST。

​ DST(Daylight Saving Time),是说根据日升日落人为的对时间做出一个调整,比如冬天7点天亮起床,夏天6点天亮。那么在夏天到来时人为将时间加1个小时,这样就可以让你还是觉得7点起床,但实际上是提前一个小时了。

​ 而Python是通过环境变量获取tzone和DST的值,我们国家现在不在实行DST,故只需考虑时区,无需再考虑DST调整时间。

time模块

  • 时间戳
In [2]: time.time()                                                                       
Out[2]: 1596433362.4333951

​ 指的是从epoch到现在的秒数,返回值类型为浮点数,用的是UTC时间。一般在使用时会进行时间戳和格式化或结构化转换。

  • 结构化时间

把时间戳使用年月日分时秒的方式展示,这种转换分为两种,一种还是用UTC时间,一种是用所在时区进行调整后的时间。返回的是一个时间元组。

In [3]: t = time.time()     
In [4]: time.gmtime(t)   # 使用UTC时间转换                                           
Out[4]: time.struct_time(tm_year=2020, tm_mon=8, tm_mday=3, tm_hour=5, tm_min=51, tm_sec=53, tm_wday=0, tm_yday=216, tm_isdst=0)

In [5]: time.localtime()    # 使用本地时间转换                  
Out[5]: time.struct_time(tm_year=2020, tm_mon=8, tm_mday=3, tm_hour=13, tm_min=52, tm_sec=15, tm_wday=0, tm_yday=216, tm_isdst=0)

​ 上面这两种转换方式都返回一个类struct_time的实例,这两个函数内部默认会调用time.time(),并用返回的秒数进行转换,同样python也提供了将这两种sturct_time转换成秒数的方法

In [9]: import calendar    # 使用到calendar模块                   
                                                  
In [12]: calendar.timegm(time.gmtime())   # 把UTC的struct_time转成秒数                 
Out[12]: 1596434271

In [13]: time.mktime(time.localtime())  # 把时间调整过的struct_time转成秒数
Out[13]: 1596405471.0

​ 上面的mktime方法会先找到系统中的时区和DST信息,然后对sturct_time进行调整后转换。

  • 格式化时间字符串

上述的sturct_time的展示方式并不太利于日常使用,使用中最常见的需求是在时间和字符串之间进行转换,time模块提供了strftime和strptime来实现。

1、strftime 即 string format time,用来将时间格式化成字符串

2、strptime 即 string parse time,用来将字符串解析成时间

PS:这里需要转换的时间都是sturct_time对象

In [15]: gmtime = time.gmtime()                                                       
In [16]: time.strftime('%Y-%m-%d %H:%M:%S', gmtime)       # struct_time转换成字符串
Out[16]: '2020-08-03 06:09:08'
    
In [18]: datestring = '2020-08-03 10:43:17'           
In [19]: time.strptime(datestring, '%Y-%m-%d %H:%M:%S')   # 字符串转成struct_time   
Out[19]: time.struct_time(tm_year=2020, tm_mon=8, tm_mday=3, tm_hour=10, tm_min=43, tm_sec=17, tm_wday=0, tm_yday=216, tm_isdst=-1)

官网也提供了Python中时间日期格式化符号:

%a    本地星期名称的简写(如星期四为Thu)
%A    本地星期名称的全称(如星期四为Thursday)
%b    本地月份名称的简写(如八月份为agu)
%B    本地月份名称的全称(如八月份为august)
%c    本地相应的日期表示和时间表示
%d    一个月中的第几天(01 - 31)
%f    微秒(范围0.999999)
%H    一天中的第几个小时(24小时制,00 - 23)
%I    第几个小时(12小时制,0 - 11)
%j    一年中的第几天(001 - 366)
%m    月份(01 - 12)
%M    分钟数(00 - 59)
%p    本地am或者pm的标识符
%S    秒数(00 - 59)
%U    一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。
%w    一个星期中的第几天(0 - 6,0是星期天)
%W    和%U基本相同,不同的是%W以星期一为一个星期的开始。
%x    本地相应的日期表示
%X    本地相应的时间表示
%y    两位数的年份表示(00-99)
%Y    四位数的年份表示(000-9999)
%z    与UTC时间的间隔(如果是本地时间,返回空字符串)
%Z    时区的名字(如果是本地时间,返回空字符串)
%%    %本身

除了上面的两个函数,time模块还提供了两个简单的方法,用来做时间和字符串之间的转换

1、asctime用来将一个struct_time对象转成标准的24字符的字符串

2、ctime方法与asctime类似,只不过接收的参数是秒数,在内部会先将秒数通过localtime转为struct_time对象,再转成标准的24字符的字符串

In [21]: gmtime = time.gmtime()                                         
In [22]: time.asctime(gmtime)       # struct_time转字符串        
Out[22]: 'Mon Aug  3 06:30:47 2020'

In [25]: t = time.time()  
In [26]: time.ctime(t)            # 时间秒数转字符串            
Out[26]: 'Mon Aug  3 14:31:22 2020'
  • 其他time常用操作
time.sleep(t)  # 推迟t秒执行
time.clock()  # 返回当前cpu时间,一般用来记录程序占用的时间复杂度
  • 总结

    time模块中时间格式主要有三种,timestamp时间戳、struct_time时间元组、format_time格式化时间字符串,可以用下图描述转换方式:

    time01

datime模块

time模块解决了时间的获取和表示,datetime则进一步解决了快速获取并操作时间中年月日时分秒的能力。提供的类主要有time、date、datetime、timedelta、tzinfo

函数 属性
today() 获取当前日期和时间
date() 将日期时间转为日期
time() 将日期时间转为时间
timestamp() 将日期时间转为时间戳
now() 获取当前日期和时间
strftime() 格式化日期时间为字符串
fromtimestamp() 时间戳转为datetime
  • 创建datetime对象
In [27]: import datetime         

In [28]: datetime.datetime.fromtimestamp(time.time())  # fromtimestamp将time.time()转换成datetime对象
Out[28]: datetime.datetime(2020, 8, 3, 14, 48, 31, 746524)

In [29]: datetime.datetime.now()    # 获取当前时间的datetime对象
Out[29]: datetime.datetime(2020, 8, 3, 14, 48, 36, 456256)

In [30]: datetime.datetime.today()  # 获取当前时间的datetime对象  
Out[30]: datetime.datetime(2020, 8, 3, 14, 48, 43, 250030)
    
In [31]: datetime.datetime.utcnow()   # 获取utc时间的datetime对象     
Out[31]: datetime.datetime(2020, 8, 3, 6, 50, 35, 730178)
  • 字符串转换datetime对象
In [32]: datestring = '2020-08-03 10:43:17'                                               
In [33]: print(type(datetime.datetime.strptime(datestring, '%Y-%m-%d %H:%M:%S')))         
<class 'datetime.datetime'>
# 其内部还是先调用time的striptime方法,获取struct_time对象,再转换成datetime对象
# 同样的datetime转字符串对象应该使用striftime方法了。
  • time类

    time类表示时间值,可以创建的对象只有时分秒毫秒等,常用属性见下表

函数 说明
hour 小时
minute 分钟
second
isoformat() 格式化时间
tzname() 获取时区名
replace() 替换

示例:

In [34]: t = datetime.time(15,12,25)  
In [35]: t                
Out[35]: datetime.time(15, 12, 25)
In [38]: t.second                        
Out[38]: 25
  • date类

    date类表示日期值,可以创建的对象只有年月日,常用属性如下表:

函数 说明
fromtimestamp() 时间戳转为datetime
today() 返回当前日期
year/month/day 年/月/日
strftime 将datetime格式化成字符串
strptime 字符串格式化成datetime
isoformat() 格式化成'YYYY-MM-DD'
replace() 替换
weekday() 返回周几

示例:

In [39]: today = datetime.date.today()      
In [40]: today                 
Out[40]: datetime.date(2020, 8, 3)
    
In [42]: today.year                        
Out[42]: 2020
    
In [44]: today.timetuple()   # 转换成struct_time对象          
Out[44]: time.struct_time(tm_year=2020, tm_mon=8, tm_mday=3, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=216, tm_isdst=-1)
  • timedelta类
函数 说明
total_seconds() 计算时间差的总秒数
days 获得指定天数为单位的timedelta对象
seconds 获得指定秒数
microseconds 获得指定微秒数

实际使用中,常用的除了各种时间的转换外,还有对日期时间的比较和加减运算。得益于Python的运算符重载能力,对日期时间也可以方便的使用运算符操作。

PS:对日期时间的运算,仅限于同类对象之间,且不包括time对象。

In [55]: today = datetime.date.today()     # 获取当前日期的datetime对象     
In [56]: onday = datetime.timedelta(days=1)   # 获取一个单位为一天的timedelta对象                                                                          
In [57]: today - onday          # 取前一天
Out[57]: datetime.date(2020, 8, 2)

In [58]: today + onday       # 取后一天    
Out[58]: datetime.date(2020, 8, 4)
    
In [59]: tomorrow = today + onday    # 后一天存入变量
In [60]: yesterday = today - onday   # 前一天存入变量

In [61]: tomorrow - yesterday                        
Out[61]: datetime.timedelta(days=2)  # 获得一个days=2的timedelta对象
    
In [62]: yesterday - tomorrow       
Out[62]: datetime.timedelta(days=-2)   # 获得一个days=-2的timedetla对象

​ 做几个实例

# 获取前一天的日期和时间
In [97]: (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d %H:%M:%S")                          
Out[97]: '2020-08-02 16:07:22'
# 获取一天的总秒数
In [92]: datetime.timedelta(1).total_seconds()                           
Out[92]: 86400.0
# 获取三个小时后的日期和时间
In [98]: (datetime.datetime.now() + datetime.timedelta(hours=3)).strftime("%Y-%m-%d %H:%M:%S")                          
Out[98]: '2020-08-03 19:07:35'
# 获取一天前的日期
In [99]: (datetime.date.today() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d")    
Out[99]: '2020-08-02'

calendar模块

这个模块用的比较少,不如放弃。。。。

posted @ 2021-07-14 11:02  勤俭持家亮公子  阅读(514)  评论(0)    收藏  举报