apppublic/aidocs/timeUtils.md
2025-10-05 11:23:33 +08:00

12 KiB
Raw Blame History

日期与时间处理工具库技术文档

本模块提供了一系列用于日期、时间处理和格式转换的实用函数,支持日期计算、字符串与时间对象互转、模式匹配等功能,适用于数据分析、任务调度、日志处理等场景。


目录


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)

对日期字符串进行加减操作并返回新字符串。

参数

支持同时添加天、月、年。

执行顺序

  1. days
  2. months
  3. 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 标准 %Uisocalendar()


3.24 date_season(date_str)

根据月份划分季节:

月份 季度
13 1
46 2
79 3
1012 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: strdate 对象

方法

+1天后看月份是否改变。


3.27 is_match_pattern(pattern, strdate)

判断某日期是否符合特定调度模式。

支持的模式

模式 含义 示例
'D' 每日触发 'D'
'W[0-6]' 每周星期X0=周一...6=周日) 'W0'=每周一
'M0' 每月最后一天 'M0'
'Mdd' 每月第dd天 'M15'=每月15日
'Sx-dd' 每季度第x月第dd天 'S1-01'=季初第一天
'Ym-dd' 每年m月dd日 'Y12-25'=每年12月25日

返回值

  • bool:是否匹配

注意事项

  • Sx-ddx %= 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