在Python中,日期和时间的应用非常普遍。在实际应用中,大部分数据的记录和日志的处理都需要使用时间。这里将介绍Python中日期和时间的使用。
日期和时间
在代码中,我们常常需要与时间打交道。在Python中,与时间处理有关的模块包括time
、datetime
以及calendar
。
在Python中,通常用时间戳、格式化的时间字符串和元组3种方式表示时间。下面分别进行讲解。
1 时间戳
通常,时间戳(timestamp
)表示从1970年1月1日00时00分00秒开始按秒计算的偏移量,也就是从1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起到现在的总毫秒数。
时间戳是一个经加密后形成的凭证文档,包括3部分:
(1)需加时间戳的文件的摘要(digest)。
(2)DTS收到文件的日期和时间。
(3)DTS的数字签名。
一般来说,时间戳产生的过程为:用户首先将需要加时间戳的文件用Hash编码加密形成摘要,然后将该摘要发送到DTS, DTS加入收到文件摘要的日期和时间信息后再对该文件加密(数字签名),最后送回用户。
书面签署文件的时间是由签署人自己写上的,而数字时间戳是由认证单位DTS添加的,以DTS收到文件的时间为依据。
提示:Python 3.5中支持的最大时间戳为32535244799(3001-01-01 15:59:59)。
2 时间格式化符号
在Python中,一般用表所示的格式化符号对时间进行格式化。
下面介绍表备注中3个数字的含义。
1:%p只有与%I配合使用才有效果。
2:文档中强调确实是0~61,而不是59,闰年秒占两秒。
3:当使用strptime()函数时,只有这一年的周数和天数确定时%U和%W才会被计算。
这里通过表格列出这些格式化符号,读者可以大概了解一下,具体的使用会在后面慢慢渗入。
3 struct_time元组
struct_time元组共有9个元素:年、月、日、时、分、秒、一年中第几周、一年中第几天、是否为夏令时。
Python函数用一个元组装起来的9组数字处理时间,也被称作struct_time元组。表10-2列出了这种结构的属性。
time模块
前面我们讲述了时间的基本概念,本节将具体讲述time模块中的一些常用函数。time模块的内置函数有做时间处理的,也有转换时间格式的。
1 time()
函数
time()
函数用于返回当前时间的时间戳(1970年01月01日08时00分00秒到现在的浮点秒数)。
time()
函数的语法如下:
time.time()
此语法中第一个time指的是time模块,该函数不需要传递参数。
time函数返回当前时间的时间戳。
该函数使用示例如下:
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
import time
print('当前时间的时间戳: %f ' % time.time())
执行结果为:
当前时间的时间戳: 1474763819.543787
2 localtime([secs])
函数
localtime()函数的作用是格式化时间戳为本地时间。如果secs参数未输入,就以当前时间为转换标准。
localtime()函数的语法如下:
time.localtime([secs])
此语法中time指的是time模块,secs指转换为time.struct_time类型的对象的秒数。
该函数没有任何返回值。
该函数使用示例如下:
import time
print('time.localtime() : ', time.localtime())
执行结果为:
time.localtime() : time.struct_time(tm_year=2016, tm_mon=9, tm_mday=25, tm_hour=8, tm_min=51,
tm_sec=42, tm_wday=6, tm_yday=269, tm_isdst=0)
3 gmtime([secs])
函数
gmtime()
函数用于将一个时间戳转换为UTC时区(0时区)的struct_time,可选的参数sec表示从1970-1-1到现在的秒数。gmtime()函数的默认值为time.time()
,函数返回time.struct_time类型的对象(struct_time是在time模块中定义的表示时间的对象)。
gmtime()
函数的语法如下:
time.gmtime([secs])
此语法中time指的是time模块,secs指转换为time.struct_time类型的对象的秒数。
该函数没有任何返回值。
该函数使用示例如下:
import time
print('time.gmtime() : ', time.gmtime())
执行结果为:
time.gmtime() : time.struct_time(tm_year=2016, tm_mon=9, tm_mday=25, tm_hour=0, tm_min=56,
tm_sec=22, tm_wday=6, tm_yday=269, tm_isdst=0)
4 mktime(t)
函数
mktime()
函数用于执行与gmtime()、localtime()
相反的操作,接收struct_time
对象作为参数,返回用秒数表示时间的浮点数。如果输入的值不是合法时间,就会触发OverflowError或ValueError。
mktime()
函数的语法如下:
time.mktime(t)
此语法中time指的是time模块,t指结构化的时间或完整的9位元组元素。
返回用秒数表示时间的浮点数。
该函数使用示例如下:
import time
t = (2016, 9, 25, 17, 35, 38, 6, 48, 0)
print ('time.mktime(t) : %f' % time.mktime(t))
执行结果为:
time.mktime(t) : 1474796138.000000
5 asctime([t])
函数
asctime()
函数用于接收时间元组并返回一个可读的形式为Sun Sep 25 09:09:37 2016(2016年09月25日周日9时09分37秒)的24个字符的字符串。
asctime()
函数的语法如下:
time.asctime([t])
此语法中time指的是time模块,t指完整的9位元组元素或通过函数gmtime()、 localtime()
返回的时间值。
返回一个可读的形式为Sun Sep 25 09:09:37 2016(2016年09月25日周日9时09分37秒)的24个字符的字符串。
该函数使用示例如下:
import time
t = time.localtime()
print ('time.asctime(t): %s ' % time.asctime(t))
执行结果为:
time.asctime(t): Sun Sep 25 09:09:37 2016
6 ctime([secs])
函数
ctime()
函数用于把一个时间戳(按秒计算的浮点数)转化为time.asctime()
的形式。如果未指定参数secs或参数为None,就会默认将time.time()作为参数。ctime的作用相当于asctime(localtime(secs))
。
ctime()
函数的语法如下:
time.ctime([secs])
此语法中time指的是time模块,secs指要转换为字符串时间的秒数。
该函数没有任何返回值。
该函数使用示例如下:
import time
print ('time.ctime() : %s' % time.ctime())
执行结果为:
time.ctime() : Sun Sep 25 09:16:22 2016
7 sleep(secs)
函数
sleep()
函数用于推迟调用线程的运行,可通过参数secs指定进程挂起的时间。sleep()函数的语法如下:
time.sleep(secs)
此语法中time指的是time模块,secs指推迟执行的秒数。
该函数没有返回值。
该函数使用示例如下:
import time
print ('Start : %s' % time.ctime())
time.sleep(5)
print ('End : %s' % time.ctime())
执行结果为:
Start : Sun Sep 25 09:22:36 2016
End : Sun Sep 25 09:22:41 2016
由执行结果看到,输出的时间相隔了5秒。
8 clock()函数
clock()
函数用于以浮点数计算的秒数返回当前CPU时间,用来衡量不同程序的耗时,比time.time()
更有用。该函数在不同系统上含义不同。在UNIX系统上,返回的是“进程时间”,是用秒表示的浮点数(时间戳);在Windows中,第一次调用返回的是进程运行的实际时间,第二次之后的调用是自第一次调用后到现在的运行时间。
clock()
函数的语法如下:
time.clock()
此语法中time指的是time模块,该函数不需要参数。该函数有两个功能:
(1)在第一次调用时,返回程序运行的实际时间。
(2)第二次之后的调用,返回自第一次调用后到这次调用的时间间隔。
在Win32系统下,clock()
函数返回的是真实时间(wall time),而在UNIX/Linux下返回的是CPU时间。
该函数使用示例如下:
import time
def procedure():
time.sleep(2)
# measure process time
t1 = time.clock()
procedure()
print('seconds process time : ',time.clock() - t1)
# measure wall time
t2 = time.time()
procedure()
print('seconds wall time : ',time.time() - t2)
执行结果为:
seconds process time : 1.9991468375899508
seconds wall time : 2.0001144409179688
此处的执行结果会因电脑的不同而有所差异(精度存在误差)。
9 strftime(format[, t])函数
strftime()
函数用于接收时间元组,并返回以可读字符串表示的当地时间,格式由参数format决定。
strftime()
函数的语法如下:
time.strftime(format[, t])
语法中time指的是time模块,format指格式化字符串,t指可选的参数,是一个struct_time对象。
返回以可读字符串表示的当地时间。
该函数使用示例如下:
import time
t = (2016, 9, 25, 17, 50, 38, 6, 48, 0)
t = time.mktime(t)
print(time.strftime('%b %d %Y %H:%M:%S', time.gmtime(t)))
执行结果为:
Sep 25 2016 09:50:38
10 strptime(string[, format])函数
strptime()
函数用于根据指定的格式把一个时间字符串解析为时间元组。
strptime()
函数的语法如下:
time.strptime(string[, format])
此语法中time指的是time模块,string指时间字符串,format指格式化字符串。
返回struct_time对象。
该函数使用示例如下:
import time
struct_time = time.strptime("25 Sep 16", "%d %b %y")
print('returned tuple: ', struct_time)
执行结果为:
returned tuple: time.struct_time(tm_year=2016, tm_mon=9, tm_mday=25, tm_hour=0, tm_min=0,
tm_sec=0, tm_wday=6, tm_yday=269, tm_isdst=-1)
11 三种时间格式转化
我们前面提到,Python中有3种表示时间的格式。这3种时间格式可以相互转化,转化方式如图1和2所示。datetime模块
datetime是date与time的结合体,包括date与time的所有信息。datetime的功能强大,支持0001年到9999年。
datetime模块定义了两个常量:datetime.MINYEAR和datetime.MAXYEAR。这两个常量分别表示datetime所能表示的最小、最大年份。其中,MINYEAR=1,MAXYEAR=9999。
datetime模块定义了以下5个类。
- datetime.date:表示日期的类。常用的属性有year、month、day。
- datetime.time:表示时间的类。常用的属性有hour、minute、second、microsecond。
- datetime.datetime:表示日期时间。
- datetime.timedelta:表示时间间隔,即两个时间点之间的长度。
- datetime.tzinfo:与时区有关的相关信息。
其中,datetime.datetime类的应用最为普遍。下面对该类进行一些详细讲解。
datetime.datetime类中有以下方法:
1. today()
today()
方法的语法如下:
datetime.datetime.today()
此语法中datetime.datetime指的是datetime.datetime类。
返回一个表示当前本地时间的datetime对象。
该方法使用示例如下:
import datetime
print('today is:', datetime.datetime.today())
执行结果为:
today is: 2016-09-25 15:37:08.900990
2. now([tz])
now()
方法的语法如下:
datetime.datetime.now([tz])
语法中datetime.datetime指的是datetime.datetime类,如果提供了参数tz,就获取tz参数所指时区的本地时间。
返回一个datetime对象。
该方法使用示例如下:
import datetime
print('now is:', datetime.datetime.now())
执行结果为:
now is: 2016-09-25 15:40:31.634641
3.datetime.utcnow()
utcnow()
方法的语法如下:
datetime.datetime.utcnow()
此语法中datetime.datetime指的是datetime.datetime类。
返回一个当前utc时间的datetime对象。
该方法使用示例如下:
import datetime
print('utcnow is:', datetime.datetime.utcnow())
执行结果为:
utcnow is: 2016-09-25 07:42:08.520898
4. fromtimestamp(timestamp[, tz])
根据时间戮创建一个datetime对象。
fromtimestamp()
方法的语法如下:
datetime.datetime.fromtimestamp(timestamp[, tz])
此语法中datetime.datetime指的是datetime.datetime类,参数tz指定时区信息。返回一个datetime对象。
该方法使用示例如下:
import datetime
print('fromtimestamp is:', datetime.datetime.fromtimestamp(time.time()))
执行结果为:
fromtimestamp is: 2016-09-25 15:58:42.704378
5. utcfromtimestamp(timestamp)
根据时间戮创建一个datetime对象。
utcfromtimestamp()
方法的语法如下:
datetime.datetime.utcfromtimestamp(timestamp)
此语法中datetime.datetime指的是datetime.datetime类,timestamp指时间戳。
返回一个datetime对象。
该方法使用示例如下:
import datetime
print('utcfromtimestamp is:', datetime.datetime.utcfromtimestamp(time.time()))
执行结果为:
utcfromtimestamp is: 2016-09-25 07:58:42.704378
6. strptime(date_string, format)
将格式字符串转换为datetime对象。
strptime()方法的语法如下:
datetime.datetime.strptime(date_string, format)
此语法中datetime.datetime指的是datetime.datetime类,date_string指日期字符串,format为格式化方式。
返回一个datetime对象。
该方法使用示例如下:
import datetime
dt = datetime.datetime.now()
print('strptime is:', dt.strptime(str(dt), '%Y-%m-%d %H:%M:%S.%f'))
执行结果为:
strptime is: 2016-09-25 15:58:42.704378
7. strftime(format)
将格式字符串转换为datetime对象。
strftime()
方法的语法如下:
datetime.datetime.strftime(format)
此语法中datetime.datetime指的是datetime.datetime类,format为格式化方式。返回一个datetime对象。
该方法使用示例如下:
import datetime
dt = datetime.datetime.now()
print('strftime is: ', dt.strftime('%Y-%m-%d %H:%M:%S'))
执行结果为:
strftime is: 2018-09-25 16:06:39
下面看一个使用时间格式化符号操作datetime.datetime类的示例。
#!/usr/bin/python
#-*- coding:UTF-8 -*-
dt = datetime.datetime.now()
print('当前时间:', dt)
print('(%Y-%m-%d %H:%M:%S %f): ', dt.strftime('%Y-%m-%d %H:%M:%S %f'))
print('(%Y-%m-%d %H:%M:%S %p): ', dt.strftime('%y-%m-%d %I:%M:%S %p'))
print('%%a: %s ' % dt.strftime('%a'))
print('%%A: %s ' % dt.strftime('%A'))
print('%%b: %s ' % dt.strftime('%b'))
print('%%B: %s ' % dt.strftime('%B'))
print('日期时间%%c: %s ' % dt.strftime('%c'))
print('日期%%x:%s ' % dt.strftime('%x'))
print('时间%%X:%s ' % dt.strftime('%X'))
print('今天是这周的第 %s 天 ' % dt.strftime('%w'))
print('今天是今年的第 %s 天 ' % dt.strftime('%j'))
print('这周是今年的第 %s 周 ' % dt.strftime('%U'))
执行结果如下:
当前时间: 2016-09-25 16:15:16.612006
(%Y-%m-%d %H:%M:%S %f): 2016-09-25 16:15:16 612006
(%Y-%m-%d %H:%M:%S %p): 16-09-25 04:15:16 PM
%a: Sun
%A: Sunday
%b: Sep
%B: September
日期时间%c: Sun Sep 25 16:15:16 2016
日期%x:09/25/16
时间%X:16:15:16
今天是这周的第 0 天
今天是今年的第 269 天
这周是今年的第 39 周
日历模块
日历(Calendar)模块的函数都与日历相关,如输出某月的字符月历。星期一默认是每周的第一天,星期天是默认的最后一天。更改设置需调用calendar.setfirstweekday()函数,模块包含以下内置函数(日历模块在实际项目中使用并不多,此处不对各个函数做具体示例列举)。
1. calendar.calendar(year,w=2,l=1,c=6)
该函数返回一个多行字符串格式的year年历,3个月一行,间隔距离为c。每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。
2. calendar.firstweekday()
返回当前每周起始日期的设置。默认情况下,首次载入calendar模块时返回0,即星期一。
3. calendar.isleap(year)
如果是闰年就返回True,否则返回False。
4. calendar.leapdays(y1,y2)
返回在y1、y2两年之间的闰年总数。
5. calendar.month(year,month,w=2,l=1)
返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行长度为7* w+6。l是每星期的行数。
6. calendar.monthcalendar(year,month)
返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。year年month月外的日期都设为0;范围内的日期由该月第几日表示,从1开始。
7. calendar.monthrange(year,month)
返回两个整数。第一个是该月星期几的日期码,第二个是该月的日期码。日从0(星期一)到6(星期日),月从1到12。
8. calendar.prcal(year,w=2,l=1,c=6)
相当于print(calendar.calendar(year,w,l,c))。
9. calendar.prmonth(year,month,w=2,l=1)
相当于print(calendar.calendar(year, w, l, c))。
10. calendar.setfirstweekday(weekday)
设置每周的起始日期码,0(星期一)到6(星期日)。
11. calendar.timegm(tupletime)
和time.gmtime相反,接收一个时间元组形式,返回该时刻的时间戳。
12. calendar.weekday(year,month,day)
返回给定日期的日期码,0(星期一)到6(星期日)。月份为1(1月)到12(12月)。