Python 获取昨天日期(手把手讲解)

Python 获取昨天日期的实用指南

在日常开发中,我们经常需要处理时间相关的逻辑,比如生成报表、分析日志、定时任务等。其中,“获取昨天的日期”是一个非常常见但又容易被忽视的需求。你可能会想:“不就是减一天吗?” 但真正写起来,却可能因为时间格式、时区、闰年等问题踩坑。

本文将手把手带你掌握 Python 获取昨天日期的完整方案,从最基础的 datetime 模块用法,到实战中的各种边界情况处理,确保你无论在什么场景下都能准确无误地获取到昨天的日期。


为什么不能直接用字符串相减?

初学者最容易犯的一个错误是:尝试用字符串操作来实现“昨天”这个概念。

比如:

yesterday_str = "2024-04-05" - 1

这行代码会直接报错,因为 Python 不允许对字符串进行数学运算。你得先把它变成时间对象,再进行操作。

这就像是你不能直接把“明天”这个概念当成一个数字去加减,而是得先知道今天是几号,才能推算出明天是哪一天。

所以,正确的路径是:先把日期转成时间对象 → 然后进行时间运算 → 再格式化输出成你想要的格式


使用 datetime 模块获取昨天日期

Python 内置的 datetime 模块是处理日期时间的核心工具。我们首先从最标准的方法开始。

基本语法:使用 timedelta 减去一天

from datetime import datetime, timedelta

now = datetime.now()

yesterday = now - timedelta(days=1)

print(yesterday)

代码解释:

  • datetime.now():获取当前的本地时间,包含年月日时分秒和微秒。
  • timedelta(days=1):表示“1天”的时间差,是 datetime 模块中的时间间隔对象。
  • now - timedelta(days=1):时间减法,返回一个更早的时间对象,即昨天的时间。
  • 这个结果仍然是一个 datetime 类型,可以继续用于后续计算或格式化。

✅ 小贴士:timedelta 支持多种单位,比如 hours=1minutes=30,但这里我们只关心“一天”,所以用 days=1


将昨天的日期格式化为字符串

通常我们不会直接打印完整的 datetime 对象,而是希望输出为“2024-04-04”这样的格式。

使用 strftime 方法格式化日期

from datetime import datetime, timedelta

yesterday = datetime.now() - timedelta(days=1)

yesterday_str = yesterday.strftime("%Y-%m-%d")

print(yesterday_str)

代码解释:

  • strftime("%Y-%m-%d"):将 datetime 对象按指定格式转换为字符串。
  • %Y:四位数年份(如 2024)
  • %m:两位数月份(01 到 12)
  • %d:两位数日期(01 到 31)
  • 这种格式是 ISO 8601 标准,广泛用于数据库、日志、接口传输。

📌 你也可以改成其他格式,比如:

  • "%Y/%m/%d" → 2024/04/04
  • "%B %d, %Y" → April 04, 2024(英文月份名)

处理时区问题:避免时区错乱

如果你的应用部署在不同地区,或者需要和服务器时间同步,那么时区问题就变得非常重要。

使用 timezone 模块处理时区

from datetime import datetime, timedelta, timezone

utc_now = datetime.now(timezone.utc)

utc_yesterday = utc_now - timedelta(days=1)

utc_yesterday_str = utc_yesterday.strftime("%Y-%m-%d %H:%M:%S UTC")
print(utc_yesterday_str)

代码解释:

  • datetime.now(timezone.utc):显式获取 UTC 时间,避免系统本地时区影响。
  • timezone.utc 是 Python 内置的 UTC 时区对象。
  • 即使你在东八区(中国),这个方法也能保证你得到的是“世界标准时间”的昨天。

⚠️ 常见错误:只用 datetime.now(),在跨时区场景下可能导致“昨天”在不同地区时间不一致。


实战案例:生成昨日日志文件名

假设你要每天生成一个日志文件,文件名包含昨天的日期。

自动命名日志文件

from datetime import datetime, timedelta

def get_yesterday_filename():
    # 获取昨天的日期
    yesterday = datetime.now() - timedelta(days=1)
    
    # 格式化为文件名格式
    filename = f"app_log_{yesterday.strftime('%Y%m%d')}.txt"
    
    return filename

log_file = get_yesterday_filename()
print(log_file)

代码解释:

  • yesterday.strftime('%Y%m%d'):去掉连字符,生成纯数字格式的日期,适合文件命名。
  • f-string:格式化字符串,让代码更简洁。
  • 这个函数可以集成到日志系统中,实现自动按天生成日志。

💡 扩展建议:你可以配合 os 模块检查文件是否存在,或者用 pathlib 处理路径。


特殊情况处理:闰年与跨月/跨年

你可能会担心:如果今天是 3 月 1 日,减去一天是不是会变成 2 月 31 日?这显然是错误的。

但 Python 的 datetime 模块已经帮你处理好了这些边界情况。

验证跨月与跨年的情况

from datetime import datetime, timedelta

test_date = datetime(2024, 3, 1)
yesterday = test_date - timedelta(days=1)
print(yesterday.strftime("%Y-%m-%d"))

test_date = datetime(2024, 1, 1)
yesterday = test_date - timedelta(days=1)
print(yesterday.strftime("%Y-%m-%d"))

结果分析:

  • 2024 年是闰年,2 月有 29 天,所以 3 月 1 日的前一天是 2 月 29 日,正确。
  • 1 月 1 日的前一天是 12 月 31 日,自动处理跨年。

🌟 这正是 datetime 模块的强大之处:它内部实现了完整的日期计算逻辑,包括闰年、月份天数、跨年等复杂规则。


总结与最佳实践建议

通过本文的学习,你已经掌握了 Python 获取昨天日期的多种方式。现在我们来总结几个关键点:

  1. 不要直接操作字符串,必须先转为 datetime 对象;
  2. 使用 timedelta(days=1) 减去一天,是最安全、最清晰的方式;
  3. 使用 strftime 格式化输出,满足不同场景需求;
  4. 涉及多时区时,优先使用 timezone.utc,避免时间错乱;
  5. 边界情况(如闰年、跨月)由 datetime 自动处理,无需手动判断。

最佳代码模板(推荐收藏)

from datetime import datetime, timedelta

def get_yesterday():
    # 获取当前时间
    now = datetime.now()
    # 减去一天
    yesterday = now - timedelta(days=1)
    # 返回格式化字符串
    return yesterday.strftime("%Y-%m-%d")

print(get_yesterday())

这个函数简洁、可复用,适合嵌入到项目中。


结语

Python 获取昨天日期,看似简单,实则蕴含了时间处理的核心思想:先转换,再运算,最后格式化。掌握这个流程,不仅能解决“昨天”的问题,也能应对“前天”“未来三天”“上周一”等复杂需求。

无论你是初学者还是中级开发者,只要理解了 datetimetimedelta 的协作机制,就能轻松应对绝大多数时间操作场景。

下次当你需要处理日期逻辑时,别再手动计算,让 Python 帮你搞定。记住:时间是精确的,代码也该如此