12 KiB
日期与时间处理工具库技术文档
本模块提供了一系列用于日期、时间处理和格式转换的实用函数,支持日期计算、字符串与时间对象互转、模式匹配等功能,适用于数据分析、任务调度、日志处理等场景。
目录
1. 导入依赖
import os, sys
import time
from datetime import date, timedelta, datetime
说明:
os,sys:保留接口扩展性。time:用于时间戳和结构化时间处理。datetime:核心日期时间处理模块。
2. 全局变量
leapMonthDays, unleapMonthDays
leapMonthDays = [0,31,29,31,30,31,30,31,31,30,31,30,31] # 闰年各月天数(索引从1开始)
unleapMonthDays = [0,31,28,31,30,31,30,31,31,30,31,30,31] # 平年各月天数
用途:快速查询某月最大天数,结合
isLeapYear()使用。
3. 核心功能函数
3.1 days_between(date_str1, date_str2)
计算两个日期字符串之间的天数差(绝对值)。
参数
| 参数 | 类型 | 描述 |
|---|---|---|
date_str1 |
str | 起始日期,格式 'YYYY-MM-DD' |
date_str2 |
str | 结束日期,格式 'YYYY-MM-DD' |
返回值
int:相差的天数(非负整数)
示例
days_between("2023-01-01", "2023-01-10") # 返回 9
3.2 monthfirstday()
获取当前月份的第一天。
返回值
str:格式为'YYYY-MM-01'
示例
monthfirstday() # 如 '2025-04-01'
3.3 curDatetime()
获取当前精确时间的 datetime 对象。
返回值
datetime.datetime:当前系统时间
3.4 curDateString()
获取当前日期字符串。
返回值
str:格式'YYYY-MM-DD'
3.5 curTimeString()
获取当前时间字符串(时分秒)。
返回值
str:格式'HH:MM:SS'
3.6 timestampstr()
生成带毫秒的完整时间戳字符串。
返回值
str:格式'YYYY-MM-DD HH:MM:SS.fff'
示例
timestampstr() # 如 '2025-04-05 14:30:22.123'
3.7 isMonthLastDay(d)
判断给定 datetime 是否是当月最后一天。
参数
| 参数 | 类型 | 描述 |
|---|---|---|
d |
datetime |
待判断的时间对象 |
返回值
bool:若是月末返回True
原理
通过加一天后判断月份是否变化。
3.8 isLeapYear(year)
判断是否为闰年。
⚠️ 注意:原代码逻辑有误!
错误分析
if year % 4 == 0 and year % 100 == 0 and not (year % 400 == 0):
此条件仅在“能被100整除但不能被400整除”时返回 True,即把平年判为闰年。
正确应为:
def isLeapYear(year):
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
✅ 建议修复该函数!
3.9 timestamp(dt) 和 timeStampSecond(dt)
将 datetime 转换为 Unix 时间戳。
| 函数名 | 精度 | 说明 |
|---|---|---|
timestamp(dt) |
微秒级 | 包含 .microsecond |
timeStampSecond(dt) |
秒级 | 忽略微秒部分 |
参数
dt:datetime对象
返回值
int:自 1970-01-01 UTC 起的秒数
3.10 addSeconds(dt, s)
给时间对象增加若干秒。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
dt |
datetime |
原始时间 |
s |
int |
要增加的秒数 |
返回值
datetime:新的时间对象
3.11 monthMaxDay(y, m)
获取指定年份某月的最大天数(考虑闰年)。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
y |
int | 年份 |
m |
int | 月份(1~12) |
返回值
int:该月最多多少天
3.12 date2str(dt=None)
将 datetime 转为 'YYYY-MM-DD' 字符串。
参数
dt: 可选datetime对象;若未传则使用当前时间
返回值
str:格式化日期字符串
3.13 time2str(dt)
⚠️ 存在 Bug
return '%02d:%02d:%02d' % (dt.hour, dt, minute, dt.second)
错误使用了 dt,minute(语法错误),应为 dt.minute。
修正版本
def time2str(dt):
return '%02d:%02d:%02d' % (dt.hour, dt.minute, dt.second)
3.14 str2Date(dstr) 和 str2Datetime(dstr)
str2Date(dstr)
尝试解析形如 'YYYY-MM-DD [HH:MM:SS]' 的字符串为 datetime 对象。
警告:内部调用了不存在的
ymdDate(...)函数前就执行拆分,且异常处理打印但不中断。
改进建议:
- 统一使用标准库
datetime.strptime - 移除冗余中间步骤
str2Datetime(dstr)
更稳健的实现,推荐使用。
支持格式
'YYYY-MM-DD''YYYY-MM-DD HH:MM:SS'
返回值
datetime对象
3.15 ymdDate(y, m, d, H=0, M=0, S=0)
构造 datetime 实例的快捷方式。
参数
年、月、日、时、分、秒均可指定,默认为0。
示例
ymdDate(2025, 4, 5, 10, 30) # 2025-04-05 10:30:00
3.16 strdate_add(date_str, days=0, months=0, years=0)
对日期字符串进行加减操作并返回新字符串。
参数
支持同时添加天、月、年。
执行顺序
- 加
days - 加
months - 加
years
自动处理跨月/跨年边界,并确保不会出现非法日期(如 2月30日)
示例
strdate_add("2024-01-31", months=1) # 返回 "2024-02-29"(自动调整到月底)
3.17 addMonths(dt, months) 和 addYears(dt, years)
addMonths(dt, months)
安全地增加月份,自动修正超出范围的日期(如 1月31日 +1月 → 2月29日或28日)
addYears(dt, years)
同理,考虑闰年导致2月可能只有28天。
3.18 dateAdd(dt, days=0, months=0, years=0)
综合日期加法入口函数,按顺序应用增量。
3.19 firstSunday(dt)
返回大于等于输入日期的第一个周日。
注意:Python 中
weekday()返回 0~6 表示周一至周日。
因此(7 - weekday()) % 7更准确。
当前实现假设 weekday()==6 是周六?实际应为周日。
存疑逻辑
f = dt.weekday()
if f < 6:
return dt + timedelta(7 - f)
else:
return dt
这表示:
- 若不是周日(即 0~5),则加
(7-f)天 - 若是周日(6),直接返回
✅ 实际上这是正确的:weekday() 返回 0=周一 ... 6=周日
所以当 f=6(周日)时无需移动。
✔️ 此函数逻辑正确。
3.20 时间格式常量与函数
DTFORMAT = '%Y%m%d %H%M%S'
getCurrentTimeStamp()
获取当前时间按 DTFORMAT 格式的字符串。
TimeStamp(t)
将 struct_time 格式化为上述格式。
timestampAdd(ts1, ts2)
将两个时间字符串相加(ts2 可为秒数或时间字符串)
❌ 存在类型判断错误:
if type(ts2)=='' :
应改为:
if isinstance(ts2, str):
否则会出错。
timestampSub(ts1, ts2)
计算两个 DTFORMAT 时间之间的秒数差。
3.21 StepedTimestamp(baseTs, ts, step)
将时间 ts 对齐到以 baseTs 为起点、步长为 step 秒的时间网格。
应用场景
- 数据采样对齐
- 定时任务触发点归一化
参数
| 参数 | 类型 | 说明 |
|---|---|---|
baseTs |
str | 基准时间(DTFORMAT) |
ts |
str | 当前时间 |
step |
int | 步长(秒) |
返回值
- 最近的对齐时间点(向上或向下取整)
3.22 timestamp2dt(t)
将 Unix 时间戳(秒)转为 datetime 对象。
3.23 date_weekinyear(date_str)
获取日期所在年的第几周(ISO 周编号)。
返回值
str:'YYYY-W'形式,其中W为两位周数
使用
%W(基于周一开始的周),而非 ISO 标准%U或isocalendar()
3.24 date_season(date_str)
根据月份划分季节:
| 月份 | 季度 |
|---|---|
| 1–3 | 1 |
| 4–6 | 2 |
| 7–9 | 3 |
| 10–12 | 4 |
返回值
str:'YYYYQ',如'20251'表示2025年第1季度
3.25 str2date(sd)
将 'YYYY-MM-DD' 字符串转为 date 对象。
示例
str2date("2025-04-05") # 返回 date(2025, 4, 5)
3.26 is_monthend(dt)
判断日期是否为月末。
参数
dt:str或date对象
方法
+1天后看月份是否改变。
3.27 is_match_pattern(pattern, strdate)
判断某日期是否符合特定调度模式。
支持的模式
| 模式 | 含义 | 示例 |
|---|---|---|
'D' |
每日触发 | 'D' |
'W[0-6]' |
每周星期X(0=周一...6=周日) | 'W0'=每周一 |
'M0' |
每月最后一天 | 'M0' |
'Mdd' |
每月第dd天 | 'M15'=每月15日 |
'Sx-dd' |
每季度第x月第dd天 | 'S1-01'=季初第一天 |
'Ym-dd' |
每年m月dd日 | 'Y12-25'=每年12月25日 |
返回值
bool:是否匹配
注意事项
Sx-dd中x %= 4,即循环每4个月视为一个季度- 调试信息
print(f'{m=}-{d=}, ...')建议移除生产环境
4. 已知问题汇总(建议修复)
| 函数名 | 问题描述 | 建议修改 |
|---|---|---|
isLeapYear |
条件反向,导致逻辑错误 | ✅ 重写 |
time2str |
引用 dt,minute 报语法错误 |
✅ 修复拼写 |
timestampAdd |
type(ts2)=='' 永远为假 |
✅ 改为 isinstance(ts2, str) |
str2Date |
使用未定义函数 ymdDate 在 try 外部可能发生错误 |
✅ 重构或删除冗余逻辑 |
str2Datetime |
不支持毫秒 | ✅ 可拓展支持 |
5. 使用示例
# 计算间隔
print(days_between("2023-01-01", "2023-12-31")) # 364
# 获取今天
print(curDateString()) # 2025-04-05
# 加一个月
print(strdate_add("2024-01-31", months=1)) # 2024-02-29
# 判断是否为月末
print(is_monthend("2025-04-30")) # True
# 匹配每周五
print(is_match_pattern("W4", "2025-04-11")) # True(假设是周五)
6. 总结
本工具包提供了丰富的日期时间操作能力,适合嵌入数据处理流水线或定时任务系统中。尽管存在少量 bug 和可优化空间,整体设计清晰、功能完整。
📌 推荐在正式使用前进行单元测试,并优先修复已知缺陷。
版本: v1.0
作者: Auto-generated Documentation
更新时间: 2025-04-05