在本教程中,您将通过示例掌握在 Python 中处理日期和时间的方法。您将了解用于操作日期和时间的不同模块、如何以特定格式读取和打印时间等。
在深入研究日期和时间的工作原理之前,让我们先回顾一下过去,了解计算机是如何计算时间的。事实上,几乎所有计算机都基于 Unix 纪元时间来计算时间,即 1970 年 1 月 1 日 00:00:00 UTC。UTC(协调世界时),通常称为 GMT(格林尼治标准时间),指的是经度 0° 的时间。
与其他编程语言一样,Python 也采用了 Unix 时间的概念,其标准库包含一个名为 time 的常用模块。time 模块有一个名为 time() 的函数,它输出自 Unix 纪元时间以来的秒数。
>>> import time
>>> time.time()
1599329118.616698
这种 Unix 时间表示法对人类来说极难解析,因此需要另一种方式向用户传达时间。这可以通过将 Unix 时间转换为 UTC,再借助时区偏移将其转换为本地时间来实现。所有时区偏移值的数据库由互联网号码分配局(简称 IANA)维护。
由于人类难以确定以秒为单位的时间,时间格式便以年、月、日、小时等方式计算。我们生活的世界在地理、语言、文化等各个方面都充满了多样性,因此有必要对时间格式进行标准化,以避免所有不必要的复杂性和沟通错误。国际标准化组织提出了 ISO-8601,规定日期格式应按从最重要到最不重要的数据顺序排列。明确地说,标准化的日期格式如下
YYYY-MM-DD HH:MM:SS
其中 YYYY 表示四位数的年份,MM 和 DD 表示两位数的月份和日期。同样,HH、MM 和 SS 表示两位数的小时、分钟和秒。
这样做的主要好处是避免了日期格式的模糊性。例如,当月份的值是一个有效的数字时,MM-DD-YYYY 或 DD-MM-YYYY 常常会被误解。
Python 提供了三个不同的模块来处理日期和时间。它们如下所列:
让我们从 datetime 模块开始学习,它有助于在 Python 中操作日期和时间。
可以使用 datetime 模块中的两个常量 MINYEAR 和 MAXYEAR 导出系统中可表示的最小和最大年份。
MINYEAR 返回日期和日期时间对象中允许的最小年份数,即 1,而 MAXYEAR 给出日期和日期时间对象中允许的最大年份数表示,即 9999。
import datetime
#constants in datetime Module
import datetime
print(datetime.MINYEAR)
print(datetime.MAXYEAR)
1 9999
为了操作日期和时间,Python 的 datetime 模块包含以下类,如下表所示。
| 类 | 返回或描述 | 属性 |
|---|---|---|
| datetime.date | 一个理想化的日期 | 年、月、日 |
| datetime.time | 一个理想化的时间 | 小时、分钟、秒、微秒和 tzinfo |
| datetime.datetime | 日期和时间的组合 | 年、月、日、小时、分钟、秒、微秒和 tzinfo |
| datetime.timedelta | 两个实例之间的持续时间 | 周、天、小时、分钟、秒、微秒、毫秒 |
| datetime.tzinfo | 时区信息 | 无 |
| datetime.timezone | 实现 tzinfo 抽象基类 | 无 |
date、time、datetime 和 timezone 类的对象是不可变的,因此是可哈希的。所以这些对象可以用作字典的键。
Python 中的 Date 对象在一个理想化的格里高利历中处理日期。它以标准形式 YYYY-MM-DD 表示日期。
datetime.date(year,month,day)
这里的参数必须是整数,并且在其规定的范围内,如下所示:
如果任何参数不满足这些范围规范,则会遇到 ValueError。
方法 today() 用于获取当前本地日期。在此示例中,我们导入了 datetime 模块,并为 datetime.date 类创建了一个对象 d_ob,该对象调用了 today() 方法。
import datetime
#Current date
d_ob = datetime.date.today()
print(d_ob)
2020-09-06
结果为您提供当前的本地日期。
Unix 时间戳是以特定日期和 1970 年 1 月 1 日之间的秒数表示的时间。例如,1599468233 是一个时间戳。可以借助名为 fromtimestamp() 的方法将时间戳转换为实际日期。
from datetime import date
ts = date.fromtimestamp(1599468233)
print('Date from Timestamp is',ts)
Date from Timestamp is 2020-09-07
可以使用 fromisoformat() 方法将以字符串形式给出的日期转换为标准格式。这是一个非常酷的方法,它总是以 YYYY-MM-DD 的格式输出日期。
from datetime import date
str = date.fromisoformat('2020-02-14')
print(str)
2020-02-14
当将年、周和日作为参数传递时,fromisocalendar 方法会给出日期。
from datetime import date
cal_date = date.fromisocalendar(year=2020,week=20,day=5)
print(cal_date)
2020-05-15
现在假设您想获取当前日期和时间,您可以使用 datetime 模块中的另一个类,即 datetime.datetime。datetime 对象是一个单独的对象,它处理日期对象和时间对象。
datetime.datetime(year,month,day,hour=0,minute = 0,sec = 0,tzinfo = None)
常用的方法如下所列
import datetime
#Current date
dt_ob = datetime.datetime.now()
print(dt_ob)
2020-09-06 15:39:27.272038
import datetime
#Current date
dt_ob = datetime.datetime.today()
print(dt_ob)
2020-09-06 15:39:27.272038
您也可以通过传递关键字参数来实例化 datetime 类,如示例所示:唯一的区别是这里我们没有调用任何特定的方法,而是提供了日期和时间。
from datetime import datetime
dt_ob3 = datetime(year = 2020,m = 29,hour = 6,minute = 30,sec
print(dt_ob3)
2020-10-29 06:30:45
也可以单独检索实体,如仅年份、仅月份或仅小时。这可以通过点表示法来完成。
from datetime import datetime
dt_ob = datetime(year = 2020,m = 29,hour = 6,minute = 30,sec
print('Current Year is',dt_ob.year)
print('Current time is ',dt_ob.hour)
print('Timestamp of the date is',dt_ob.timestamp())
Current Year is 2020 Current Minute is 6 Timestamp of the date is 1603938645.0
from datetime import datetime
ts = datetime.fromtimestamp(1599468233)
print('Date from Timestamp is',ts)
Date from Timestamp is 2020-09-07 12:43:53
Timedelta 类是 datetime 模块中与上述类一起常用的类,用于查找两个日期或时间的差值,即持续时间。在下面的示例中,我们创建了两个日期对象 d1 和 d2,它们的差值存储在 d3 中。这里,d3 属于 timedelta 类。类似地,两个 datetime 对象的差值会得到一个 timedelta 对象。
from datetime import date,time,datetime
from datetime import date,time,datetime
d1= date(2020,9,2)
d2=date(2019,9,7)
d3 =d1-d2
print('Difference is ',d3)
print("Type is ",type(d3))
t1=datetime(2020,9,2,11,45,30)
t2=datetime(2018,9,7,10,50,40)
print('time Difference is ',(t1-t2))
输出
Difference is 361 days, 0:00:00 Type is <class 'datetime.timedelta'> time Difference is 726 days, 0:54:50
要操作 timedelta 对象,我们首先需要从 datetime 模块中导入 timedelta 类。
#timedelta objects difference
from datetime import timedelta
td1 = timedelta(weeks=2,days=3)
td2 = timedelta(weeks=1,days=5)
td3 = td1-td2
print(td3)
5 days, 0:00:00
#timedelta objects difference
from datetime import timedelta td5 = timedelta(sec
td = timedelta(sec
td7 = td5-td6
print(td7)
print(abs(td7))
-1 day, 23:59:30
要以秒为单位获取 timedelta 对象,我们可以使用名为 total_seconds() 的方法,它以秒表示持续时间。
from datetime import timedelta
td1 = timedelta(weeks=2,days=3)
print(td1.total_seconds())
1468800.0
我们之前讨论过,不同国家的日期和时间格式不同。例如,在美国,他们依赖的常见日期格式是 MM-DD-YYYY,而在英国,格式是 DD-MM-YYYY。如果月份是一个有效的数字,这就会产生歧义。因此,在 python 中需要一种处理这种歧义的措施,于是就有了两种格式化方法
Strftime 方法() 是在所有三个类(date、time、datetime)中定义的格式化方法,用于将给定的日期、时间和日期时间表示为可读的字符串。它只包含一个名为 format 的参数,我们在这里指定所需的日期格式。
下面的可视化图表能让您更清晰地理解这个概念。

from datetime import datetime
t = datetime.today()
print(t)
f1 = t.strftime("%m/%d/%Y, %H:%M:%S")
# MM/DD/YYYY H:M:S format
print("Format 1:", f1)
f2 = t.strftime("%d/%m/%Y, %H:%M:%S")
# DD/MM/YYYY H:M:S format
print("Format 2:", f2)
输出
2020-09-27 16:15:36.913768 Format 1: 09/27/2020, 16:15:36 Format 2: 27/09/2020, 16:15:36
这是另一种格式化方法,仅由 datetime 对象支持,与 strftime() 方法正好相反。这里,datetime 对象是根据给定的字符串创建的。它包含两个参数:
根据以上两个参数,它会产生一个 datetime 对象作为结果。下面的可视化图表阐明了这个概念。

from datetime import datetime
Str = "June 5,2020"
print(Str)
dt_ob=datetime.strptime(Str,"%B %d,%Y")
print(dt_ob)
输出
June 5,2020 2020-06-05 00:00:00
当传递给 strptime() 方法的字符串和格式代码不匹配时,Python 会引发 ValueError。例如,
from datetime import datetime
Str = "June 5,2020"
dt_ob=datetime.strptime(Str,"%d %B ,%Y")
print(dt_ob)
输出
ValueError: time data 'June 5,2020' does not match format '%d %B ,%Y'
| 指令 | 含义 | 示例 |
|---|---|---|
| %a | 星期的缩写版本。 | Sun, Mon, …, Sat (周日, 周一, ..., 周六) |
| %A | 星期的完整版本。 | Sunday, Monday, …, Saturday (星期日, 星期一, ..., 星期六) |
| %w | 星期几,以十进制数表示,其中 0 是星期日,1 是星期一,6 是星期六。 | 0, 1, …, 6 |
| %d | 月份中的第几天,以零填充的十进制数表示。 | 01, 02, …, 31 |
| %b | 月份的缩写版本 | Jan, Feb, …, Dec (一月, 二月, ..., 十二月) |
| %B | 月份的完整版本 | January, February, …, December (一月, 二月, ..., 十二月) |
| %m | 月份,以零填充的十进制数表示。 | 01, 02, …, 12 |
| %y | 年份的简写版本,不含世纪 | 00, 01, …, 99 |
| %Y | 年份的完整版本,包含世纪 | 0001, 0002, …, 2013, 2014, …, 9998, 9999 |
| %H | 小时,以零填充的十进制数表示 - 24 小时制 | 00, 01, …, 23 |
| %I | 小时,以零填充的十进制数表示 - 12 小时制 | 01, 02, …, 12 |
| %p | AM 或 PM。 | AM, PM (上午, 下午) |
| %M | 分钟,以零填充的十进制数表示。 | 00, 01, …, 59 |
| %S | 秒,以零填充的十进制数表示。 | 00, 01, …, 59 |
| %f | 微秒,以十进制数表示,左侧零填充。 | 000000, 000001, …, 999999 |
| %z | UTC 偏移量,格式为 ±HHMM[SS[.ffffff]] | (空), +0000, -0400, +1030, +063415, -030712.345216 |
| %Z | 时区名称 | (空), UTC, EST, CST |
| %j | 一年中的第几天,以零填充的十进制数表示。 | 001, 002, …, 366 |
| %U | 一年中的周数(星期日为一周的第一天),以零填充的十进制数表示。 | 00, 01, …, 53 |
| %W | 一年中的周数(星期一为一周的第一天),以十进制数表示。 | 00, 01, …, 53 |
| %c | 日期和时间的本地表示。 | Tue Aug 16 21:30:00 1988 |
| %x | 日期的本地表示。 | 08/16/88 (无); 08/16/1988 (en_US) |
| %X | 时间的本地表示。 | 21:30:00 |
| %% | 一个字面上的 '%' 字符。 | % |