python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python datetime日期格式化与解析

Python datetime模块的日期的格式化与解析全攻略

作者:知远漫谈

在现代编程中,时间与日期处理是几乎每个项目都会涉及的基础功能,今天,我们就来深入探讨 datetime 模块中关于 日期格式化(Formatting)与解析(Parsing) 的高级用法吧

在现代编程中,时间与日期处理是几乎每个项目都会涉及的基础功能。无论是日志记录、用户行为分析、数据定时任务,还是金融系统中的交易时间戳,datetime 模块都是 Python 中最核心、最实用的标准库之一。它不仅提供了对日期和时间的精确操作,还支持灵活的格式化与解析功能,让开发者能够轻松应对各种时间相关的业务需求。

今天,我们就深入探讨 datetime 模块中关于 日期格式化(Formatting)与解析(Parsing) 的高级用法。通过大量实战代码示例、可视化图表以及真实场景的应用分析,带你从“会用”走向“精通”。

一、为什么需要掌握datetime模块?

想象一下:你正在开发一个全球化的电商系统,用户来自不同国家,时区各异。订单时间必须准确记录,并且要根据用户的本地时区显示。同时,你需要将用户提交的“2025-04-05 14:30”这种字符串转换为可计算的时间对象。

这时候,如果你只会用 strptimestrftime 这两个基础函数,可能只能应付简单场景。但一旦遇到复杂格式、多时区、闰年、夏令时等问题,就会手足无措。

正确使用 datetime 模块,不仅能让你写出更健壮的代码,还能避免因时间错误导致的严重生产事故。

学习目标

二、核心类详解:date,time,datetime,timedelta

1.date—— 只处理日期

from datetime import date

# 创建一个具体日期
today = date(2025, 4, 5)
print(today)  # 2025-04-05
print(type(today))  # <class 'datetime.date'>

# 获取当前日期
today = date.today()
print(f"今天是:{today}")

# 日期属性
print(f"年份:{today.year}")
print(f"月份:{today.month}")
print(f"日:{today.day}")

提示:date 只包含年月日,不包含时间信息,适合用于生日、合同签订日等场景。

2.time—— 只处理时间

from datetime import time

meeting_time = time(14, 30, 0)  # 14:30:00
print(meeting_time)  # 14:30:00

# 时间属性
print(f"小时:{meeting_time.hour}")
print(f"分钟:{meeting_time.minute}")
print(f"秒:{meeting_time.second}")

注意:time 类不能单独表示“某个时刻”,它只代表一天中的某个时间点,常配合 date 一起使用。

3.datetime—— 完整的时间戳

from datetime import datetime

now = datetime.now()
print(now)  # 2025-04-05 15:23:47.123456

# 手动创建
event_time = datetime(2025, 4, 5, 14, 30, 0)
print(event_time)  # 2025-04-05 14:30:00

# 属性访问
print(f"年份:{event_time.year}")
print(f"时区:{event_time.tzinfo}")  # None(未设置时区)

datetime 是最常用的类型,尤其适合记录事件发生时间、数据库字段存储等。

4.timedelta—— 时间差量

from datetime import datetime, timedelta

# 创建一个时间差:3天
three_days = timedelta(days=3)

# 当前时间 + 3天
future = datetime.now() + three_days
print(f"3天后是:{future}")

# 减去1小时
one_hour_ago = datetime.now() - timedelta(hours=1)
print(f"1小时前是:{one_hour_ago}")

# 复杂组合
duration = timedelta(
    days=2,
    hours=5,
    minutes=30,
    seconds=15
)
print(f"持续时间:{duration}")  # 2 days, 5:30:15

timedelta 是进行时间运算的关键工具,比如计算到期日、倒计时、数据窗口滑动等。

三、格式化输出:strftime()详解

strftime() 方法将 datetime 对象转换为指定格式的字符串。这是最常见的输出方式,如日志打印、页面展示。

常见格式码一览表

格式符含义示例
%Y四位年份2025
%y两位年份25
%m月份(01-12)04
%B完整月份名April
%b缩写月份名Apr
%d日期(01-31)05
%H小时(00-23)14
%I小时(01-12)02
%M分钟(00-59)30
%S秒(00-59)00
%pAM/PMPM
%j年中的第几天(001-366)095
%U / %W周数(周日/周一为第一周)14

实战示例:多种格式输出

from datetime import datetime

dt = datetime(2025, 4, 5, 14, 30, 0)

# 1. ISO 标准格式(推荐用于接口传输)
iso_format = dt.strftime("%Y-%m-%d %H:%M:%S")
print(f"ISO格式:{iso_format}")  # 2025-04-05 14:30:00

# 2. 中文友好格式
chinese_format = dt.strftime("今天是%Y年%m月%d日,%H点%M分")
print(f"中文格式:{chinese_format}")  # 今天是2025年04月05日,14点30分

# 3. 英文全称格式
english_full = dt.strftime("%A, %B %d, %Y at %I:%M %p")
print(f"英文全称:{english_full}")  # Friday, April 05, 2025 at 02:30 PM

# 4. 仅日期部分
only_date = dt.strftime("%Y/%m/%d")
print(f"斜杠分隔:{only_date}")  # 2025/04/05

# 5. 日期+星期
with_weekday = dt.strftime("%Y-%m-%d (%a)")
print(f"带星期:{with_weekday}")  # 2025-04-05 (Fri)

小贴士:建议优先使用 ISO 8601 标准格式YYYY-MM-DD HH:MM:SS),因为其无歧义、机器可读性强,广泛用于 API 接口、日志系统。

四、解析输入:strptime()详解

strptime() 方法的作用是将字符串按指定格式解析为 datetime 对象。它是 strftime() 的逆过程。

基本语法

datetime.strptime(string, format)

实际案例:常见格式解析

案例1:标准日期时间字符串

from datetime import datetime

input_str = "2025-04-05 14:30:00"
parsed_dt = datetime.strptime(input_str, "%Y-%m-%d %H:%M:%S")
print(parsed_dt)  # 2025-04-05 14:30:00
print(type(parsed_dt))  # <class 'datetime.datetime'>

案例2:带毫秒的字符串

input_with_ms = "2025-04-05 14:30:00.123456"
try:
    parsed = datetime.strptime(input_with_ms, "%Y-%m-%d %H:%M:%S.%f")
    print(f"毫秒解析成功:{parsed}")
except ValueError as e:
    print(f"解析失败:{e}")

特别注意:.f 表示微秒(6位),若字符串中没有毫秒,则不能使用 %f,否则会抛出 ValueError

案例3:中文日期格式

chinese_date = "2025年4月5日 14点30分"
try:
    dt = datetime.strptime(chinese_date, "%Y年%m月%d日 %H点%M分")
    print(f"中文解析成功:{dt}")
except ValueError as e:
    print(f"解析失败:{e}")

案例4:混合格式(带 AM/PM)

am_pm_str = "April 5, 2025 at 2:30 PM"
try:
    dt = datetime.strptime(am_pm_str, "%B %d, %Y at %I:%M %p")
    print(f"AM/PM解析成功:{dt}")
except ValueError as e:
    print(f"解析失败:{e}")

高级技巧:如何应对不确定格式?

现实世界中,用户输入千奇百怪。我们不可能预知所有格式。这时可以采用“尝试多个格式”策略:

from datetime import datetime

def parse_datetime_string(s):
    formats = [
        "%Y-%m-%d %H:%M:%S",
        "%Y-%m-%d %H:%M:%S.%f",
        "%Y/%m/%d %H:%M:%S",
        "%B %d, %Y at %I:%M %p",
        "%Y年%m月%d日 %H点%M分",
        "%d-%m-%Y %H:%M",
    ]
    
    for fmt in formats:
        try:
            return datetime.strptime(s, fmt)
        except ValueError:
            continue
    
    raise ValueError(f"无法解析时间字符串:{s}")

# 测试
test_cases = [
    "2025-04-05 14:30:00",
    "2025/04/05 14:30:00",
    "April 5, 2025 at 2:30 PM",
    "2025年4月5日 14点30分"
]

for case in test_cases:
    try:
        result = parse_datetime_string(case)
        print(f"✅ {case} → {result}")
    except Exception as e:
        print(f"❌ {case} → {e}")

这种方法虽然性能略低,但在处理非结构化输入时非常实用,例如用户表单、CSV 文件导入等。

五、时区处理:zoneinfo模块(Python 3.9+)

以前使用 pytz,现在推荐使用内置的 zoneinfo 模块!

什么是时区?

时区是地理区域的时间标准。例如:

正确做法:使用zoneinfo+datetime带时区

from datetime import datetime, timezone
from zoneinfo import ZoneInfo

# 明确指定时区
shanghai_time = datetime(2025, 4, 5, 14, 30, 0, tzinfo=ZoneInfo("Asia/Shanghai"))
print(shanghai_time)  # 2025-04-05 14:30:00+08:00

new_york_time = datetime(2025, 4, 5, 6, 30, 0, tzinfo=ZoneInfo("America/New_York"))
print(new_york_time)  # 2025-04-05 06:30:00-04:00

时区转换:跨时区比较

from datetime import datetime, timezone
from zoneinfo import ZoneInfo

# 从上海时间转换为纽约时间
shanghai = datetime(2025, 4, 5, 14, 30, 0, tzinfo=ZoneInfo("Asia/Shanghai"))

# 转换到纽约
ny_time = shanghai.astimezone(ZoneInfo("America/New_York"))
print(f"上海时间 {shanghai} → 纽约时间 {ny_time}")
# 输出:上海时间 2025-04-05 14:30:00+08:00 → 纽约时间 2025-04-05 06:30:00-04:00

重点:astimezone() 只能用于带时区的 datetime,否则会报错!

六、实战项目:构建一个时间管理工具

我们来做一个小型时间管理系统,包含以下功能:

from datetime import datetime
from zoneinfo import ZoneInfo

class TimeManager:
    def __init__(self):
        self.formats = [
            "%Y-%m-%d %H:%M:%S",
            "%Y-%m-%d %H:%M:%S.%f",
            "%Y/%m/%d %H:%M:%S",
            "%B %d, %Y at %I:%M %p",
            "%Y年%m月%d日 %H点%M分",
            "%d-%m-%Y %H:%M",
        ]

    def parse(self, input_str):
        for fmt in self.formats:
            try:
                dt = datetime.strptime(input_str, fmt)
                return dt.replace(tzinfo=ZoneInfo("UTC"))  # 统一为UTC
            except ValueError:
                continue
        raise ValueError(f"无法解析时间:{input_str}")

    def convert_to_zones(self, dt_utc, zones):
        results = {}
        for zone in zones:
            try:
                converted = dt_utc.astimezone(ZoneInfo(zone))
                results[zone] = converted.strftime("%Y-%m-%d %H:%M:%S %Z")
            except Exception as e:
                results[zone] = f"❌ 错误:{e}"
        return results

    def calculate_duration(self, start_str, end_str):
        start = self.parse(start_str)
        end = self.parse(end_str)
        diff = end - start
        return diff.total_seconds()

# 使用示例
manager = TimeManager()

# 测试输入
inputs = [
    "2025-04-05 14:30:00",
    "April 5, 2025 at 2:30 PM",
    "2025年4月5日 14点30分"
]

for inp in inputs:
    try:
        dt = manager.parse(inp)
        print(f"✅ 解析成功:{dt}")
        
        # 转换到多个时区
        zones = ["Asia/Shanghai", "America/New_York", "Europe/London"]
        conversions = manager.convert_to_zones(dt, zones)
        for zone, time_str in conversions.items():
            print(f"   → {zone}: {time_str}")
            
        # 计算持续时间
        duration = manager.calculate_duration(inp, "2025-04-05 16:00:00")
        print(f"   → 时长:{duration / 3600:.2f} 小时")
        
    except Exception as e:
        print(f"❌ {inp} → {e}")

这个工具可用于:

七、最佳实践总结

场景推荐做法
存储时间统一使用 UTC + datetime 带时区
用户展示根据用户偏好转换为本地时区
API 传输采用 ISO 8601 格式(YYYY-MM-DD HH:MM:SS
输入解析尝试多种格式,避免硬编码
时间计算优先使用 timedelta,避免手动加减
时区处理强烈推荐 zoneinfo(Python 3.9+)

结语

掌握了 datetime 模块的格式化与解析,你就等于拥有了掌控时间的能力。无论是在后端服务中精确记录事件,还是在前端展示用户友好的时间,都能游刃有余。

记住:时间不是字符串,而是对象;格式化不是死记硬背,而是理解规则。

以上就是Python datetime模块的日期的格式化与解析全攻略的详细内容,更多关于Python datetime日期格式化与解析的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文