Python datetime模块完全攻略
顾名思义,datetime 模块是 Python 处理日期和时间的标准库,它就是 date 和 time 模块的结合。该模块提供了多种操作日期和时间的类,在支持日期、时间数学运算的同时,重点聚焦于如何能够更高效地支持日期的格式化输出。
对于 In [1] 处的代码,需要注意的是,datetime 是模块,datetime 模块中还包含一个同名的 datetime 类,我们通过 from datetime import datetime 导入的才是 datetime 这个类。
如果仅导入 datetime 类,则必须引用全名 datetime.datetime。如果这样的话,上述 In [2] 处的代码需要修改为如下形式。
可以通过 type( ) 函数来验证 now 这个对象的身份,见 Out[4] 处,可以发现 datetime.now( ) 返回的是当前的日期和时间,其类型是 datetime。
如果要返回特定日期和时间的对象,可以直接用 datetime 的构造方法来生成这样的对象,方法如下。
我们还可以利用 datetime 类的属性 year、month、day、hour 和 minute 分别输出 datetime 对象的年、月、日、小时和分钟,示例如下。
我们当前的时间就是相对于纪元时间流逝的秒数,称为 timestamp(时间戳)。有了这个时间戳,计算机可以很容易地比较时间的先后。这个时间是机器可读的,但对人而言,理解起来比较困难,因此通常需要转换。
通过如下代码可以方便地查看当前实际的时间戳。
孔夫子有句名言:“逝者如斯夫,不舍昼夜。”这句话形容时间像流水一样不停地流逝。因此当运行 In [3] 处的代码时,得到的运行结果(时间戳)永远会不一样,因为时间戳永远会单向递增。另外,还需要注意的是,Python 中的时间戳是一个浮点数。如果有小数位,小数位表示毫秒。
有时,用户输入的日期和时间是字符串,要处理这样的日期和时间,首先必须把字符串转换为 datetime。转换方法并不复杂,可通过 datetime.strptime( ) 实现,并需要制定一个日期和时间的格式化字符串,代码如下:
strptime( ) 的第 1 个参数是日期字符串,很容易理解。这里,最复杂的部分莫过于该函数的第 2 个参数——变化多端的格式化参数。若格式标记出错,strptime( ) 就难以解析出正确的日期。常见的日期格式如表 1 所示。
Python 提供了很多“语法糖”,对 datetime 的加减,可以直接用加
有了前面知识的铺垫,当我们想计算两个日期相隔多少时,利用时间差类 timedelta 就比较容易了,参见例 1。
【例 1】计算两个日期之间相隔的天数(gap-days.py)
datetime获取当前时间
我们先来看看如何获取当前日期和时间。In [1]: from datetime import datetime #导入日期类 In [2]: now = datetime.now() In [3]: print(now) 2020-01-31 20:45:39.535529
对于 In [1] 处的代码,需要注意的是,datetime 是模块,datetime 模块中还包含一个同名的 datetime 类,我们通过 from datetime import datetime 导入的才是 datetime 这个类。
如果仅导入 datetime 类,则必须引用全名 datetime.datetime。如果这样的话,上述 In [2] 处的代码需要修改为如下形式。
now = datetime.datetime.now()
可以通过 type( ) 函数来验证 now 这个对象的身份,见 Out[4] 处,可以发现 datetime.now( ) 返回的是当前的日期和时间,其类型是 datetime。
In [4]: type(now) Out[4]: datetime.datetime
如果要返回特定日期和时间的对象,可以直接用 datetime 的构造方法来生成这样的对象,方法如下。
In [5]: from datetime import datetime In [6]: date = datetime(2020, 10, 31, 12, 59) In [7]: print(date) 2020-10-31 12:59:00
我们还可以利用 datetime 类的属性 year、month、day、hour 和 minute 分别输出 datetime 对象的年、月、日、小时和分钟,示例如下。
In [8]: date.year Out[8]: 2020 In [9]: date.month Out[9]: 10 In [10]: date.day Out[10]: 31 In [11]: date.hour Out[11]: 12 In [12]: date.minute Out[12]: 59
datetime转换为timestamp
在计算机中,时间实际上是用整型数字表示的。我们把 1970 年 1 月 1 日 00:00:00 UTC+00:00 时区的时刻称为 epoch time(纪元时间),记为 0。1970 年以前的时间为负数。我们当前的时间就是相对于纪元时间流逝的秒数,称为 timestamp(时间戳)。有了这个时间戳,计算机可以很容易地比较时间的先后。这个时间是机器可读的,但对人而言,理解起来比较困难,因此通常需要转换。
通过如下代码可以方便地查看当前实际的时间戳。
In [1]: from datetime import datetime In [2]: dt = datetime.now() In [3]: dt.timestamp() Out[3]: 1567999546.724838
孔夫子有句名言:“逝者如斯夫,不舍昼夜。”这句话形容时间像流水一样不停地流逝。因此当运行 In [3] 处的代码时,得到的运行结果(时间戳)永远会不一样,因为时间戳永远会单向递增。另外,还需要注意的是,Python 中的时间戳是一个浮点数。如果有小数位,小数位表示毫秒。
有时,用户输入的日期和时间是字符串,要处理这样的日期和时间,首先必须把字符串转换为 datetime。转换方法并不复杂,可通过 datetime.strptime( ) 实现,并需要制定一个日期和时间的格式化字符串,代码如下:
In [4]: from datetime import datetime In [5] : cday = datetime.strptime('2020-10-30 11:00:30', '%Y-%m-%d %H:%M:%S') In [6]: print(cday) 2020-10-30 11:00:30
strptime( ) 的第 1 个参数是日期字符串,很容易理解。这里,最复杂的部分莫过于该函数的第 2 个参数——变化多端的格式化参数。若格式标记出错,strptime( ) 就难以解析出正确的日期。常见的日期格式如表 1 所示。
格式符 | 格式说明 |
---|---|
%a | 星期的英文单词缩写,如星期一返回 Mon |
%A | 星期的英文单词全称,如星期一返回 Monday |
%b | 月份的英文单词缩写,如一月返回Jan |
%B | 月份的英文单词全称,如一月返回January |
%c | 返回区域设置的适当日期和时间表示。不同的国家格式可能不同,如 2020/08/16 20:01:27 (中国)、Tue Aug 16 20:01:27 2020(美国)、Di 16 Aug 20:01:27 2020(德国) |
%d |
返回当前日期是当前月的第几天
|
%f | 表示微秒(Microsecond ),范围 [0,999999] |
%I |
以12小时制表示当前小时数,范围 [1,12],如 01, 02,…,12
|
%J | 返回当天是当年的第几天,范围 [001,366],如001, 002, …,366 |
%m | 返回左侧 0 值填充的月份,范围 [0,12],如 01, 02,…,12 |
%M | 返回左侧 0 值填充的分钟数,范围 [0,59],如 01, 02,.…,59 |
%P |
返回上午(AM )或下午(PM )
|
%S |
返回左侧 0 值填充的秒数,范围 [0,59].如 01, 02,.…,59
|
%U |
返回当周是当年的第几周,以周日为第一天,如00, 01,.…,53
|
%W | 返回当周是当年的第几周,以周一为第一天,如00, 01,.…,53 |
%w | 返回当天是当周的第几天,范围 [0, 6], 6 表示星期天 |
%x | 日期的字符串表示,如 07/10/2020,显小格式和区域设置有关 |
%X |
时间的字符串表示,如 20:22:08
|
%y |
用两个数字表示的年份,如 20
|
%Y |
用四个数字表示的年份,如 2020
|
%z |
表示与 UTC 时间的间隔,如果是本地时间,返回空字符串
|
%Z |
表示时区名称.如果是本地时间.返回空字符串
|
datetime转换为字符串
如果已经有了 datetime 对象,我们要把它格式化为字符串显示给用户,转换是通过另外一个函数 strftime( ) 实现的。这里,同样需要格式化日期和时间字符串,因此,同样要用到表 1 中列举的格式。In [1]: from datetime import datetime In [2]: now = datetime.now() #获取当前的时间和日期 In [3]: now.strftime("%Y") Out [3]: '2020' In [4]: now.strftime("%y") Out [4]: '20'
datetime加减
有时候,我们需要计算某两个时间或日期的差值,比如说相隔多少个小时,相差多少天等。这时,可以对日期和时间进行加减。这种操作实际上就是向前或向后计算 datetime,得到一个新的 datetime。Python 提供了很多“语法糖”,对 datetime 的加减,可以直接用加
+
和减-
运算符操作。不过,这时需要引入一个特殊的类——时间差类 timedelta,示例代码如下。
In [1]: from datetime import datetime , timedelta In [2]: now = datetime.now() In [3]: print(now.strftime("%Y-%m-%d %H:%M")) 2019-09-09 20:58 In [4]: date = now + timedelta(hours = 2) In [5]: print(date.strftime(H%Y-%m-%d %H:%M")) 2019-09-09 22:58 In [6]: date2 = now - timedelta(days = 2, hours = 12) In [7]: print(date2.strftime("%Y-%m-%d %H:%M")) 2019-09-07 08:58
有了前面知识的铺垫,当我们想计算两个日期相隔多少时,利用时间差类 timedelta 就比较容易了,参见例 1。
【例 1】计算两个日期之间相隔的天数(gap-days.py)
from datetime import datetime, timedelta list_1 = ["2020-10-07", '2013-09-01'] day1 = datetime.strptime(list_1[0], '%Y-%m-%d') #将字符串转为datetime对象 day2 = datetime.stuptime(list_1[1], '%Y-%m-%d') #同上 deltadays = day1 - day2 #时间差timedelta对象 print(deltadays.days) #输出timedelta对象程序执行结果为:
2593
有了时间差类 timedelta,我们可以直接输出时间差(如天数 days),而无须考虑闰年或闰月等复杂因素(第 08 行),因为该模块都提前为我们考虑好了。