一、开篇:时间处理的“隐形炸弹”
你有没有遇到过这样的情况:凌晨 2 点设置定时任务,结果莫名其妙跑出一个小时?或者从数据库读出来的时间总感觉差了几小时?
这都是 Python 原生 datetime 埋下的坑。今天我们要聊的 whenever,就是专门来拆弹的。
二、实战:三组代码带你快速上手
🧪 场景1:夏令时自动适配(核心痛点)
先看原生 datetime 有多坑。在巴黎,2023 年 3 月 26 日凌晨 2 点时钟会直接跳到 3 点,因为夏令时开始了。如果你用原生代码加 8 小时:
from datetime import datetime, timedeltafrom zoneinfo import ZoneInfobedtime = datetime(2023, 3, 25, 22, tzinfo=ZoneInfo("Europe/Paris"))full_rest = bedtime + timedelta(hours=8)print(full_rest)
2023-03-26 06:00:00+02:00 # 本应是 7 点,凭空少了一小时!
而 whenever 会自动识别并补偿这消失的一小时 :
from whenever import ZonedDateTimebedtime = ZonedDateTime(2023, 3, 25, 22, tz="Europe/Paris")full_rest = bedtime.add(hours=8)print(full_rest)
2023-03-26T07:00:00+02:00[Europe/Paris] # 这才是正确的起床时间
🧪 场景2:类型安全防“误伤”
原生 datetime 不分“有时区”和“无时区”,传参全靠注释提醒。而 whenever 把时间细分为 6 种显式类型,混用直接报错 :
from whenever import PlainDateTime, ZonedDateTimelocal = PlainDateTime(2024, 12, 25, 10, 0) # 无时区的圣诞节zoned = ZonedDateTime(2024, 12, 25, 10, 0, tz="Asia/Shanghai") # 有时区result = local > zoned # 类型检查器直接报错
类型错误:PlainDateTime 与 ZonedDateTime 不可比较
🧪 场景3:时区转换与比较
跨时区协作时,whenever 能确保比较逻辑完全正确 :
from whenever import Instantnow = Instant.now()ny_time = now.to_tz("America/New_York")sh_time = now.to_tz("Asia/Shanghai")print(ny_time < sh_time)
True # 纽约时间总是晚于上海,逻辑正确
三、优势对比:为什么选它?
相比原生 datetime 和 Pendulum、Arrow 等库,whenever 的核心优势在于:类型安全 + DST 安全 + 高性能(Rust 加速) 。
不足是 API 仍在 1.0 前,偶尔有微调,建议在生产环境中锁定版本。
四、结尾
时间处理无小事,一个小时的偏差足以让整个数据报表报废。
whenever 通过强类型和 DST 自动补偿,把隐患消灭在 IDE 里。如果你被时区问题折磨过,不妨 pip install whenever 试试。
你在项目中遇到过哪些离谱的时间 bug?欢迎在评论区分享你的“血泪史”~