Python3 日期和时间详解
Python3 中处理日期和时间主要依赖内置的
datetime
、time
模块,以及第三方库(如处理时区的 pytz
)。这些工具能轻松实现获取当前时间、日期计算、格式转换等功能。本文从基础到实战,详解日期时间的核心操作。
一、核心模块与概念
处理日期时间的核心模块及功能:
模块 / 类 | 作用 | 核心功能 |
---|---|---|
datetime 模块 |
最常用的日期时间处理模块 | 提供 date (日期)、time (时间)、datetime (日期 + 时间)、timedelta (时间差)类 |
time 模块 |
偏底层的时间处理(如时间戳) | 获取时间戳、时间戳与结构化时间的转换 |
calendar 模块 |
日历相关操作(如月份日历、闰年判断) | 生成日历、判断闰年等 |
二、datetime 模块:日期时间处理的 “主力军”
datetime
模块提供了 4 个核心类,覆盖绝大多数日期时间场景:类名 | 功能描述 | 包含信息 |
---|---|---|
date |
仅处理日期(年、月、日) | year , month , day |
time |
仅处理时间(时、分、秒、微秒) | hour , minute , second , microsecond |
datetime |
同时处理日期和时间 | 包含 date 和 time 的所有信息 |
timedelta |
处理时间差(如 “2 天 3 小时”) | 用于日期时间的加减运算 |
1. 获取当前日期时间
from datetime import date, time, datetime
# 获取当前日期(date对象)
today = date.today()
print(today) # 输出:2023-10-05(格式:年-月-日)
print(f"年:{today.year},月:{today.month},日:{today.day}")
# 获取当前时间(datetime对象,包含日期+时间)
now = datetime.now()
print(now) # 输出:2023-10-05 15:30:45.123456(精确到微秒)
print(f"时:{now.hour},分:{now.minute},秒:{now.second}")
2. 创建指定的日期时间对象
通过构造函数手动指定日期时间:
from datetime import date, time, datetime
# 创建指定日期(年, 月, 日)
my_date = date(2023, 12, 31) # 2023年12月31日
print(my_date) # 2023-12-31
# 创建指定时间(时, 分, 秒, 微秒)
my_time = time(23, 59, 59, 999999) # 23时59分59秒999999微秒
print(my_time) # 23:59:59.999999
# 创建指定日期+时间(年, 月, 日, 时, 分, 秒)
my_datetime = datetime(2023, 10, 1, 8, 0, 0) # 2023年10月1日8点0分0秒
print(my_datetime) # 2023-10-01 08:00:00
注意:月份和日期不能超出范围(如月份不能是 13,2 月不能有 30 日),否则会报错。
3. 日期时间格式化(转为字符串)
用
strftime()
方法将日期时间对象转为自定义格式的字符串(核心!日常开发高频使用)。常用格式化指令(大小写敏感):
指令 | 含义 | 示例 |
---|---|---|
%Y |
四位数年份 | 2023 |
%m |
两位数月份(01-12) | 10 |
%d |
两位数日期(01-31) | 05 |
%H |
24 小时制小时(00-23) | 15 |
%M |
两位数分钟(00-59) | 30 |
%S |
两位数秒(00-59) | 45 |
%w |
星期(0-6,0 是周日) | 4(周四) |
%B |
完整月份名 | October |
%b |
缩写月份名 | Oct |
%A |
完整星期名 | Thursday |
%a |
缩写星期名 | Thu |
示例:
from datetime import datetime
now = datetime(2023, 10, 5, 15, 30, 45)
# 转为"年-月-日 时:分:秒"格式
str1 = now.strftime("%Y-%m-%d %H:%M:%S")
print(str1) # 2023-10-05 15:30:45
# 转为"月/日/年 上/下午 时:分"格式
str2 = now.strftime("%m/%d/%Y %p %I:%M") # %p是AM/PM,%I是12小时制
print(str2) # 10/05/2023 PM 03:30
# 带星期的格式
str3 = now.strftime("%Y年%m月%d日 %A")
print(str3) # 2023年10月05日 Thursday
4. 解析字符串为日期时间对象
用
strptime()
方法将字符串按指定格式转为日期时间对象(与 strftime()
互为逆操作)。示例:
from datetime import datetime
# 解析"年-月-日 时:分:秒"格式的字符串
str_time = "2023-12-31 23:59:59"
dt = datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
print(dt) # 2023-12-31 23:59:59
print(type(dt)) # <class 'datetime.datetime'>
# 解析其他格式
str_date = "10/01/2023" # 月/日/年
dt2 = datetime.strptime(str_date, "%m/%d/%Y")
print(dt2) # 2023-10-01 00:00:00
注意:字符串格式必须与指定的指令完全匹配,否则会报错(如月份用
%m
时,字符串必须是两位数,如 “09” 不能是 “9”)。5. 时间差计算(timedelta)
timedelta
用于表示两个日期时间之间的差值,可直接与 datetime
对象进行加减运算,实现 “n 天后”“n 小时前” 等计算。timedelta
常用参数:days
(天)、hours
(小时)、minutes
(分钟)、seconds
(秒)、weeks
(周)。示例:
from datetime import datetime, timedelta
now = datetime(2023, 10, 5, 15, 30)
# 计算3天后的时间
future = now + timedelta(days=3)
print(future) # 2023-10-08 15:30:00
# 计算1小时30分钟前的时间
past = now - timedelta(hours=1, minutes=30)
print(past) # 2023-10-05 14:00:00
# 计算两个日期的差值
dt1 = datetime(2023, 12, 31)
dt2 = datetime(2023, 10, 1)
diff = dt1 - dt2
print(diff) # 91 days, 0:00:00(相差91天)
print(f"相差{diff.days}天") # 相差91天
三、time 模块:时间戳与底层时间操作
time
模块更偏向底层,核心是 “时间戳”—— 自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数(浮点数,包含小数秒)。1. 获取时间戳
import time
# 获取当前时间戳(秒数,含小数)
timestamp = time.time()
print(timestamp) # 例如:1696500645.123456
2. 时间戳与结构化时间的转换
localtime()
:时间戳 → 本地结构化时间(包含年、月、日、时、分等字段的元组)。gmtime()
:时间戳 → UTC 结构化时间(世界协调时间)。mktime()
:结构化时间 → 时间戳。
示例:
import time
timestamp = 1696500645.123456
# 时间戳转本地结构化时间
local_struct = time.localtime(timestamp)
print(local_struct)
# 输出:time.struct_time(tm_year=2023, tm_mon=10, tm_mday=5, ..., tm_sec=45)
print(f"本地时间:{local_struct.tm_year}年{local_struct.tm_mon}月")
# 结构化时间转时间戳
timestamp2 = time.mktime(local_struct)
print(timestamp2) # 1696500645.0(与原时间戳基本一致)
3. 程序运行时间计算
用时间戳可轻松计算程序执行耗时:
import time
start = time.time() # 记录开始时间
# 模拟耗时操作
total = 0
for i in range(10**6):
total += i
end = time.time() # 记录结束时间
print(f"程序耗时:{end - start:.4f}秒") # 例如:0.0523秒
四、calendar 模块:日历相关操作
calendar
模块用于生成日历、判断闰年等场景。示例:
import calendar
# 判断是否为闰年
print(calendar.isleap(2024)) # True(2024是闰年)
print(calendar.isleap(2023)) # False
# 获取某年的总天数
print(calendar.yeardays2calendar(2023, 1)) # 复杂结构,包含全年日历
# 简单打印某年某月的日历
print(calendar.month(2023, 10)) # 打印2023年10月的日历
输出 2023 年 10 月的日历:
October 2023
Mo Tu We Th Fr Sa Su
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
五、时区处理(进阶)
Python 原生
datetime
对象默认是 “naive”(无时区信息),若需处理时区(如北京时间与 UTC 时间转换),推荐使用:- Python3.9+ 内置的
zoneinfo
模块; - 第三方库
pytz
(兼容旧版本)。
示例(用
zoneinfo
处理时区转换):from datetime import datetime
from zoneinfo import ZoneInfo # Python3.9+
# 创建带时区的datetime对象(北京时间,UTC+8)
beijing_tz = ZoneInfo("Asia/Shanghai")
beijing_time = datetime(2023, 10, 5, 15, 30, tzinfo=beijing_tz)
print(beijing_time) # 2023-10-05 15:30:00+08:00
# 转换为UTC时间(UTC+0)
utc_time = beijing_time.astimezone(ZoneInfo("UTC"))
print(utc_time) # 2023-10-05 07:30:00+00:00(北京时间减8小时)
六、常见问题与避坑指南
-
格式化指令记错:
区分%Y
(四位数年份)和%y
(两位数年份,如 23)、%m
(月份)和%M
(分钟),记错会导致格式错误。 -
字符串解析格式不匹配:
例如用%Y-%m-%d
解析"2023/10/05"
会报错,需用%Y/%m/%d
对应。 -
时区混乱:
处理跨时区时间时,务必为datetime
对象添加时区信息(tzinfo
),否则会出现 “本地时间与 UTC 时间混淆” 的问题。 -
日期比较:
datetime
对象可直接比较(>
、<
、==
),但需注意时区是否一致(不同时区的时间不能直接比较)。
总结
Python 处理日期时间的核心工具是
datetime
模块:date
/time
/datetime
类用于表示日期、时间、日期 + 时间;strftime()
/strptime()
实现 “对象→字符串”“字符串→对象” 的转换;timedelta
用于时间差计算;time
模块适合时间戳和程序耗时计算;- 时区处理需用
zoneinfo
或pytz
。
掌握这些工具,能轻松应对日志记录、日程计算、数据时间戳等开发场景。