Python 日期处理实战:datetime、time 与 calendar 模块详解
本文系统梳理 Python 中处理日期的核心库,重点解析 datetime 模块中 date、time、datetime 及 timedelta 类的创建、解析、格式化与比较方法。同时介绍 time 模块获取 Unix 时间戳及线程暂停功能,并指出 date/time 在格式化输出时的常见陷阱,帮助开发者高效处理时间相关逻辑。
Python 日期处理核心库概述
本文整理 Python 中常用的日期处理库与函数,主要涵盖 Python 内置的 datetime、time 和 calendar 模块,以及第三方库 dateutil。日期处理涉及的核心概念包括 date、time、datetime、timezone、calendar,以及时间的比较、差值计算、字符串解析与格式化显示等。
datetime 模块类继承关系
在 datetime 模块中,各类之间的继承关系如下所示:
object ├── date │ └── datetime ├── time ├── timedelta └── tzinfo └── timezone
本文重点介绍上述继承结构中加粗显示的 datetime、date、time 和 timedelta 对象。虽然 timezone 同样重要,但在某些场景下,我们可能仅需处理本地时间。
创建 datetime、date 和 time 实例
datetime、date 和 time 实例的创建方式
可以通过调用各自的构造函数并提供必要参数来创建实例,以下是它们的构造函数定义:
datetime:
def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
microsecond=0, tzinfo=None, *, fold=0)
date:
def __new__(cls, year, month=None, day=None)
time:
def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
例如:
from datetime import datetime, date, time, timedelta
today = date(2019, 4, 24) # 2019-04-24
获取当前日期或时间
date.today() #2019-04-24
datetime.now() # 2019-04-24 21:41:40.226300
datetime.today() # 2019-04-24 21:41:50.336293
datetime.today().date() #2019-04-24
datetime.today().time() #21:41:50.336303
datetime.now().date()
datetime.now().time()
从语义角度,应分别调用 date.today() 和 datetime.now()。datetime.today() 实际上是 datetime 从 date 继承而来的方法。
time 类型没有 today() 或 now() 方法,因此只能通过 datetime.now() 来获取对应的 time 或 datetime 对象。由于 datetime 同时包含 date 和 time 信息,因此始终可以通过 datetime 实例获取相应的 date 和 time。
解析字符串与 ISO 格式规范
通过解析字符串创建实例
date.fromisoformat('2019-04-24') # 2019-04-24
datetime.fromisoformat('2019-04-24T13:12:23') # 2019-04-24 13:12:23
datetime.strptime('04/24/2019', '%m/%d/%Y') # 2019-04-24 00:00:00
time.fromisoformat('12:12:24+06:00') #12:12:24+06:00
datetime、date 和 time 均提供了 fromisoformat() 方法,使用时需了解它们各自的 ISO 表示格式。若需指定特定格式来解析字符串,仅 datetime 提供了 strptime() 方法。一旦拥有 datetime,即可相应地提取 date 与 time。
date、datetime 与 time 对应的 ISO 格式定义如下:
- date ISO format: YYYY-MM-DD
- datetime ISO format: YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]
- time ISO format: HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]
能够自由解析字符串的方法为 datetime.strptime(str, fmt)。Python 借鉴了标准 C 语言的日期格式定义字符串,具体参考 strftime() and strptime() Behavior。后续的 strftime() 函数也采用相同的格式定义方式。
注:strftime() 和 strptime() 中的 f 和 p 分别对应 format(格式)和 parse(解析)的首字母。
基于时间戳创建实例与格式化输出
基于 Timestamp 创建实例
Python 本身没有名为 Timestamp 的类型,此处的 timestamp 指由浮点数表示的时间戳。
ts = datetime.today().timestamp() # 1556161777.38553
date.fromtimestamp(ts) # 2019-04-24
datetime.fromtimestamp(ts) # 2019-04-24 22:09:37.385530
time 类型没有 fromtimestamp() 方法。
格式化输出
date、datetime 和 time 均提供 isoformat() 和 strftime(fmt) 函数,格式字符串请参考 strftime() and strptime() Behavior。
date.today().strftime('%a %b %d, %Y') # Wed Apr 24, 2019
datetime.today().isoformat() # 2019-04-24T22:21:38.747318
datetime.today().time().strftime('%Y') # 1900
date.today().strftime('%S') # 00
以上为几个示例。需注意,在 Python 中,若 time 类型不含年月日信息,格式化时尝试输出年份会得到非预期结果,但不会像 Java 那样抛出异常。例如以下 Java 代码:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate.now().format(formatter); //2019-04-24
LocalTime.now().format(formatter); //Exception java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
由于 LocalTime.now() 不含年月日信息,因此无法格式化为 yyyy-MM-dd。
时间比较与 timedelta 运算
时间与日期的比较及 timedelta 运算
- date、datetime 和 time 均定义了 __lt__、__le__、__ne__、__gt__、__ge__ 和 __eq__ 函数,因此相同类型的实例之间可以进行时间先后的比较。
- 此外,date 和 datetime 还定义了 __sub__ 和 __rsub__ 函数,因此两个 date 或两个 datetime 实例相减将得到 timedelta 实例。
- 另外,date 和 datetime 也定义了 __add__ 和 __radd__ 函数,date 或 datetime 可以加减一个 timedelta 来生成新的实例。
以下展示几个简单示例:
d1 = datetime.today() # 2019-04-24 23:00:31.672769
delta = timedelta(days=2, weeks=1, seconds=-3) # 8 days, 23:59:57
d2 = d1 + delta # 2019-05-03 23:00:28.672769
d3 = d1 - delta # 2019-04-15 23:00:34.672769
d2 - d1 # 8 days, 23:59:57
d2 > d1 # True
d1 < d3 # False
datetime.today().date() + delta) # 2019-05-02
注意,不同类型之间不能直接相减,例如用 date 减去 datetime 是非法操作。d1 + delta、d1 - delta 和 delta + d1 均可正常执行,但 delta - d1 则不可行。
timedelta 表示两个时间的差值,用于推算另一个实例时不包含日历信息。若需在日历维度进行推演,需借助 calendar 模块。
time 模块常用功能
不可忽视的 time 模块
前文所述为 datetime 模块中的 time 类型。Python 还内置了 time 模块,通过 import time 引入,它提供了一些实用功能。
- time 模块包含完整的日期时间信息,这与 datetime 模块中不含年月日信息的 time 类型不同。
- locatime()、strptime()、gmtime()、asctime() 和 mktime() 用于构造 time 实例。
- strftime() 可用于格式化输出。
- time.time() 用于获取当前的 Unix 时间戳。
- time.sleep(sec) 用于暂停当前线程若干秒。
关于 calendar 和 dateutil 的内容将在后续文章中介绍。
以上就是 Python 日期处理的详细内容,更多关于 Python 日期处理的资料请关注本站其他相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









