Python日期格式化的核心是掌握strftime和strptime的格式码,以及理解datetime对象与字符串的相互转换规则。
python日期格式化方法对比:strftime与strptime怎么选
初学者最容易混淆的是strftime和strptime,strftime将日期对象格式化为字符串,strptime将字符串解析为日期对象,方向不同,格式码拼写规则一致,但使用场景天差地别。
| 函数 | 方向 | 输入 | 输出 | 典型应用 |
|---|---|---|---|---|
| strftime | 对象→字符串 | datetime对象 + 格式码 | 字符串 | 生成日志文件名、渲染页面时间戳 |
| strptime | 字符串→对象 | 字符串 + 格式码 | datetime对象 | 解析用户输入、读取API返回的日期字符串 |
实操要点:
- strftime常用于写入文件或数据库前,将时间转成可读的固定格式。
- strptime常用于从Excel或日志中提取时间字段,再做运算。
- 两个函数的格式码必须严格匹配源数据的格式,否则抛出ValueError。
举个例子,假设有一个datetime对象now,要转成“2026-03-23 14:30:00”这种字符串,直接调用now.strftime("%Y-%m-%d %H:%M:%S"),反过来,收到一个字符串“2026-03-23 14:30:00”,需要先用datetime.strptime("2026-03-23 14:30:00", "%Y-%m-%d %H:%M:%S")才能得到一个datetime对象,之后才能做日期加减。
业内专家指出,超过八成的Python时间处理bug源于格式码写错,尤其是%Y(四位年份)与%y(两位年份)、%m(月份)与%M(分钟)的混淆。
python strftime用法详解:从入门到实战
格式码速查表
| 格式码 | 含义 | 示例(2026年3月23日 14:30:05) |
|---|---|---|
| %Y | 四位年份 | 2026 |
| %y | 两位年份 | 25 |
| %m | 补齐两位的月份 | 03 |
| %d | 补齐两位的日期 | 23 |
| %H | 24小时制 | 14 |
| %I | 12小时制 | 02 |
| %M | 分钟 | 30 |
| %S | 秒 | 05 |
| %p | AM/PM | PM |
| %A | 完整星期名 | Sunday |
| %a | 缩写星期名 | Sun |
| %B | 完整月份名 | March |
| %b | 缩写月份名 | Mar |
| %j | 年内的第几天 | 082 |
| %W | 年内的第几周(周一始) | 12 |
| %z | UTC偏移 | +0800 |
常见场景的格式化字符串
- 日志文件名带日期:
app_%Y%m%d.log - 数据库时间戳:
%Y-%m-%d %H:%M:%S - 前端展示友好格式:
%Y年%m月%d日 %H:%M - API标准ISO 8601:
%Y-%m-%dT%H:%M:%S%z
实操:生成时间戳并写入文件
import datetime
now = datetime.datetime.now()
log_suffix = now.strftime("%Y%m%d_%H%M%S")
file_name = f"data_{log_suffix}.csv"
print(file_name) # data_20260323_143005.csv
处理多语言环境
strftime的星期名、月份名输出依赖系统locale,如果需要中文星期,先设置locale:
import locale
locale.setlocale(locale.LC_TIME, 'zh_CN.UTF-8')
print(datetime.datetime.now().strftime("%A %B")) # 星期日 三月
行业共识认为,在容器化部署中务必检查系统是否安装了目标locale,否则会回退到默认英文。
python dateformatter第三方库推荐:arrow与pendulum谁更好
原生datetime模块满足了80%的需求,但遇到时区转换、人类友好字符串(如“3分钟前”)或链式操作时,第三方库能显著提升效率。
arrow:链式调用与直观API
arrow把strftime封装得更简洁,内置智能解析和时区感知。
import arrow
now = arrow.now()
print(now.format("YYYY-MM-DD")) # 2018年还是2026?arrow用YYYY表示四位年,区别于原生的%Y
print(now.humanize()) # "3 minutes ago"
print(now.shift(days=-1).format("YYYY-MM-DD")) # 昨天
arrow的格式码与Python原生不同(YYYY vs %Y),初次使用时容易写错,建议先阅读文档 format() tokens一览。
pendulum:更严格的时间对象
pendulum继承了datetime,所以原生strftime仍然可用,它在时区操作和持续时间计算上更精确。
import pendulum now = pendulum.now() print(now.to_datetime_string()) # 类似于strftime print(now.timezone.name) # 输出当前时区名 diff = now - pendulum.datetime(2026, 1, 1) print(diff.in_days()) # 计算相差天数
适用场景对比:
- 做社交平台时间轴(显示“几分钟前”)、快速原型,选arrow。
- 企业级应用要求严格的时区计算、替代datetime对象,选pendulum。
- 只需简单格式化,用原生datetime即可,不必引入依赖。
价格方面,两个库都是免费开源的,无商业授权成本,但在上海等大型互联网公司,开发团队普遍倾向于用pendulum替换原生datetime,因为它的API与datetime兼容度高,迁移成本低。
python时间格式化常见问题与编码注意事项
格式码大小写与顺序陷阱
%y输出两位年(25),%Y输出四位年(2026),从数据库取出年份时,如果用反了,2026会变成20。%m是月份,%M是分钟,一个字母之差,输出结果从“03”变成“30”。- 顺序必须与字符串实际格式一致,解析“2026-03-23”时如果用
%d-%m-%Y会报错或得到错误日期。
时区缺失导致的偏差
datetime对象有naive和aware之分,naive对象不带时区,直接format输出的是系统本地时间,将naive时间传给前端或接口,不同地区用户看到的时间不同。
正确做法:用pytz或zoneinfo(Python 3.9+)为时间添加时区。
from zoneinfo import ZoneInfo
dt_aware = datetime.datetime.now(ZoneInfo("Asia/Shanghai"))
print(dt_aware.strftime("%Y-%m-%d %H:%M:%S %z"))
性能提示:在循环或多线程中反复创建ZoneInfo对象有开销,应全局创建一次后复用。
编码与文件输出
写入带中文的日期字符串到文件时,建议用UTF-8编码,CSV或JSON文件直接存储ISO格式字符串,兼容性最好。
python日期格式化代码示例:完整的生产级函数
import datetime
from zoneinfo import ZoneInfo
def format_timestamp(ts: datetime.datetime, tz_name: str = "Asia/Shanghai") -> str:
"""将任意datetime对象转为上海时区的标准日志格式字符串"""
if ts.tzinfo is None:
ts = ts.replace(tzinfo=ZoneInfo("UTC"))
return ts.astimezone(ZoneInfo(tz_name)).strftime("%Y-%m-%d %H:%M:%S %z")
这个函数可以统一团队内的时间输出格式,避免时区混乱。核心逻辑:先补全时区,再转换目标时区,最后格式化。
Python日期格式化并非奇技淫巧,而是每个数据工程师和后端开发者的基本功。 记牢strftime和strptime的方向,善用格式码速查表,再根据项目规模选择原生方案或arrow/pendulum,就能在日志、API、数据清洗中准确驾驭时间表达。
python dateformatter常见问题解答
Q: python中如何将字符串转换为日期对象?
A: 使用datetime.datetime.strptime(input_string, format_code),例如datetime.strptime("2026-03-23", "%Y-%m-%d"),注意格式码必须与字符串的结构完全一致,否则抛出ValueError,推荐先确定字符串的固定格式,再编写对应的format码。
Q: python strftime可以自定义格式码吗?
A: 不能自定义格式码,但可以使用后接官方定义的字母组合,如果需要输出任意文本,可以将文本直接放在格式字符串中,或使用f-string格式化datetime对象,例如f"{now:%Y-%m-%d}",PEP 498引入的f-string支持在花括号内直接写strftime格式,本质相同但更简洁。
Q: 处理跨时区日期格式化时有什么最佳实践?
A: 统一以UTC存储naive时间,仅在展示层转换为用户时区,Python 3.9以上推荐zoneinfo,旧版本用pytz,在strftime前先用astimezone将datetime对象转换到目标时区,再格式化,第三方库pendulum会自动处理时区链,减少手动转换出错概率。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/496126.html



