曦远 (DealiAxy)一份私人的文字刊物

StarBlog
返回文章列表折页手记阅读全文
Python

A Pitfall-Avoidance Guide to Elegantly Handling Date and Time in Modern Python

Still falling into traps with Python time handling? `datetime`, `time`, and `calendar` will make your head spin, and the Naive vs Aware timezone trap is even worse. Still using `pytz` in 2026? The standard library's `ZoneInfo` plus `Pendulum` and `Arrow` is what modern looks like—at least you don't have to write those user-hostile time-string parsers anymore. Store UTC in the database, send ISO 8601 on the frontend—can we keep it simple?

曦远 (DealiAxy)约 12 分钟
目录8 个章节

Introduction

Many Python beginners (and even veterans) have fallen into these pitfalls:

  • Too many modules: You have to deal with three modules at once: datetime, time, and calendar. Want a timestamp? Go to time. Want to add or subtract dates? Back to datetime.
  • Naive vs Aware (the timezone trap): This is the worst of them. By default, Python creates datetime objects without timezone information (Naive). If you compare or add a timezone-aware object with a naive one, the program will throw a TypeError and crash.
  • A fragmented API: To subtract 3 days, you have to import timedelta and write datetime.now() - timedelta(days=3); to parse an ISO string, you have to write a long strptime format string.
  • No support for "human language": You can't directly handle logic like "yesterday" or "in two weeks"; you have to compute timedelta by hand.

By comparison, Go may force you to memorize the magical reference time 2006-01-02 15:04:05, but at least the logic is self-consistent. Python's native experience feels more like endlessly patching things up.

It's 2026. Both the community ecosystem and the Python standard library have evolved. Let's look at these modern approaches to handling time.

LibraryRoleWhy recommend it
ZoneInfoStandard libraryBuilt into Python 3.9+, completely replaces pytz, handles IANA timezones.
PendulumCore logicA subclass of datetime, extremely elegant syntax; "in a few days" and "next Monday" come naturally.
ArrowCollectorA must-have for web scraping. Excellent compatibility with messy strings—one .get() and you're done.

Before Python 3.9, pytz was the only option for timezone handling, but its API design is extremely user-hostile (for example, the infamous localize trap).

Today in 2026, ZoneInfo together with the IANA timezone database is very mature. If you're running on Windows, remember to install the tzdata package; on Linux, it reads the system database directly. This is truly Pythonic.

How to choose?

  • Want "zero dependencies" and only need timezone conversion: Choose ZoneInfo (standard library).
  • Need complex date arithmetic (e.g. "the third Friday of next month"): Choose Pendulum.
  • Writing a scraper and facing all kinds of weird time strings: Choose Arrow.
  • Using Django: Stick with Django's built-in timezone utilities (under the hood it has fully embraced ZoneInfo).

Code examples

Complex timezone conversion and arithmetic (using Pendulum)

import pendulum

# 1. 语义化创建
now = pendulum.now('Asia/Shanghai')
future = now.add(months=2).end_of('week')

# 2. 极简的“人类化”显示
print(future.diff_for_humans()) # "2 months from now"

# 3. 彻底解决时区比对崩溃
dt_utc = pendulum.now('UTC')
if now > dt_utc: # Pendulum 会自动处理比对逻辑
    print("安全比对,不再报错")

Parsing messy timestamps from APIs or scrapers (using Arrow)

import arrow

# 不管是时间戳、ISO 8601 还是特定格式,统统 get
raw_date = "2026-03-24T10:13:35+08:00"
t = arrow.get(raw_date)

# 转换成北京时间并格式化
print(t.to('Asia/Shanghai').format('YYYY-MM-DD HH:mm:60'))

Timezone conversion with the standard library (ZoneInfo)

If you're writing a lightweight script and don't want extra dependencies, you can use the standard library's ZoneInfo directly.

from datetime import datetime
from zoneinfo import ZoneInfo

# 1. 创建一个带时区的 UTC 时间(2026 年的标配起点)
utc_now = datetime.now(ZoneInfo("UTC"))
print(f"UTC 时间: {utc_now}")

# 2. 一行代码转成本地时间(比如北京时间)
# 再也不需要 pytz.timezone('...').localize(...) 这种阴间操作了
beijing_time = utc_now.astimezone(ZoneInfo("Asia/Shanghai"))
print(f"北京时间: {beijing_time}")

# 3. 甚至可以处理极其冷门的时区,比如你想看看纽约的开发者在干嘛
ny_time = beijing_time.astimezone(ZoneInfo("America/New_York"))
print(f"纽约时间: {ny_time}")

# 4. 获取简写的时区名称(如 CST, EST)
print(f"当前时区缩写: {ny_time.tzname()}")

Wrapping Up

Never use datetime.now(): Get into the habit of using datetime.now(ZoneInfo("UTC")) or pendulum.now().

Always store UTC in the database: No matter where the user is, what you store in the database must be UTC.

Deliver ISO 8601 to the frontend: Don't send timestamps; send a standard string like 2026-03-25T11:30:00Z. That's the least painful for the frontend to parse.

_EOF_

A Pitfall-Avoidance Guide to Elegantly Handling Date and Time in Modern Python

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

Python接入企业微信推送信息到内部群里

前言 之前一篇文章提到了使用wechatpy库来实现企业微信应用登录:Django + Taro 前后端分离项目实现企业微信登录 其实这个库可以实现的功能非常多,基本微信开发涉及到的功能都能实现。 本文介绍一个很常用的场景:实时推送信息到企业微信群里。 安装 首先安装wechatpy库 pip install wechatpy 如果运行的时候提示需要安装其他库(比如加解密相关的)那就按照提示安装,

2022-04-08 · Python · 约 1 分钟

手写核心价值观编码工具-Python实现

前言 今天是五一劳动节,祝各位无产阶级劳动者节日快乐! 然后来整活分享一些有趣的东西~ 这个小工具是我大学时做着玩的,对于各位接班人来说,12个词的核心价值观这东西,大家都非常熟悉了,这工具可以实现将一段话编码为核心价值观实现加密,同时也能将密文解密出来。 为啥要做这个呢,隔太久不太记得了,~~好像是因为游戏里喷队友老是被屏蔽,灵机一动,要是换成和谐的文字不就不会被屏蔽了吗(误~~ 实现原理 简单

2022-05-01 · Python · 约 1 分钟

我用Qt和Python开发了一个视频合并工具

想合并视频,但是却找不到比较好用的工具,很多都要收费,我想着「这破功能还得收费?」,于是决定自己搞一个,一开始用Python做了一个,效果还不错,完美完成了我的视频合并任务,不过没有图形界面,想分享给朋友一起用也没办法,于是昨天用Qt写了个图形界面套上去,中间还是遇到一些问题的,通过这篇文章记录一下。 软件的界面就是这样啦,用Qt Designer随便拖出来的,和VS拖控件也差不了多少。 用起来挺

2021-12-18 · Python · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…