qrpa 1.1.39__py3-none-any.whl → 1.1.40__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of qrpa might be problematic. Click here for more details.
- qrpa/temu_lib.py +2 -0
- qrpa/time_utils.py +882 -882
- {qrpa-1.1.39.dist-info → qrpa-1.1.40.dist-info}/METADATA +1 -1
- {qrpa-1.1.39.dist-info → qrpa-1.1.40.dist-info}/RECORD +6 -6
- {qrpa-1.1.39.dist-info → qrpa-1.1.40.dist-info}/WHEEL +0 -0
- {qrpa-1.1.39.dist-info → qrpa-1.1.40.dist-info}/top_level.txt +0 -0
qrpa/time_utils.py
CHANGED
|
@@ -1,882 +1,882 @@
|
|
|
1
|
-
"""
|
|
2
|
-
时间工具模块
|
|
3
|
-
提供各种时间相关的工具函数,包括日期获取、格式化、转换、计算等功能
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
import calendar
|
|
8
|
-
from datetime import date, datetime, timedelta, timezone
|
|
9
|
-
from typing import Optional, Tuple, List, Union
|
|
10
|
-
|
|
11
|
-
class TimeUtils:
|
|
12
|
-
"""时间工具类,提供各种时间相关的静态方法"""
|
|
13
|
-
|
|
14
|
-
# ==================== 当前时间获取 ====================
|
|
15
|
-
|
|
16
|
-
@staticmethod
|
|
17
|
-
def get_current_date() -> str:
|
|
18
|
-
"""获取当前日期,格式为 YYYYMMDD"""
|
|
19
|
-
return datetime.now().strftime('%Y%m%d')
|
|
20
|
-
|
|
21
|
-
@staticmethod
|
|
22
|
-
def get_current_datetime() -> str:
|
|
23
|
-
"""获取当前日期时间,格式为 YYYYMMDDHHMMSS"""
|
|
24
|
-
return datetime.now().strftime('%Y%m%d%H%M%S')
|
|
25
|
-
|
|
26
|
-
@staticmethod
|
|
27
|
-
def current_datetime() -> str:
|
|
28
|
-
"""获取当前日期时间,格式为 YYYY-MM-DD HH:MM:SS"""
|
|
29
|
-
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
30
|
-
|
|
31
|
-
@staticmethod
|
|
32
|
-
def today_date() -> str:
|
|
33
|
-
"""获取今天的日期,格式为 YYYY-MM-DD"""
|
|
34
|
-
return datetime.now().strftime('%Y-%m-%d')
|
|
35
|
-
|
|
36
|
-
@staticmethod
|
|
37
|
-
def today_date_hour() -> str:
|
|
38
|
-
"""获取今天的日期和小时,格式为 YYYY-MM-DD_HH"""
|
|
39
|
-
return datetime.now().strftime('%Y-%m-%d_%H')
|
|
40
|
-
|
|
41
|
-
@staticmethod
|
|
42
|
-
def get_current_year() -> int:
|
|
43
|
-
"""获取当前年份"""
|
|
44
|
-
return datetime.now().year
|
|
45
|
-
|
|
46
|
-
@staticmethod
|
|
47
|
-
def get_current_month() -> int:
|
|
48
|
-
"""获取当前月份(1-12)"""
|
|
49
|
-
return datetime.now().month
|
|
50
|
-
|
|
51
|
-
@staticmethod
|
|
52
|
-
def get_current_year_range() -> Tuple[str, str]:
|
|
53
|
-
"""获取当前年份的开始和结束日期"""
|
|
54
|
-
current_year = datetime.now().year
|
|
55
|
-
start_date = datetime(current_year, 1, 1).strftime('%Y-%m-%d')
|
|
56
|
-
end_date = datetime(current_year, 12, 31).strftime('%Y-%m-%d')
|
|
57
|
-
return start_date, end_date
|
|
58
|
-
|
|
59
|
-
# ==================== 相对日期获取 ====================
|
|
60
|
-
|
|
61
|
-
@staticmethod
|
|
62
|
-
def get_yesterday(dt: Optional[str] = None) -> str:
|
|
63
|
-
"""
|
|
64
|
-
获取昨天的日期
|
|
65
|
-
|
|
66
|
-
Args:
|
|
67
|
-
dt: 可选的基础日期,格式为 YYYYMMDD,默认为今天
|
|
68
|
-
|
|
69
|
-
Returns:
|
|
70
|
-
昨天的日期,格式为 YYYY-MM-DD
|
|
71
|
-
"""
|
|
72
|
-
if dt is None:
|
|
73
|
-
dt = datetime.now()
|
|
74
|
-
else:
|
|
75
|
-
dt = datetime.strptime(dt, "%Y%m%d")
|
|
76
|
-
yesterday = dt - timedelta(days=1)
|
|
77
|
-
return yesterday.strftime("%Y-%m-%d")
|
|
78
|
-
|
|
79
|
-
@staticmethod
|
|
80
|
-
def before_yesterday() -> str:
|
|
81
|
-
"""获取前天的日期"""
|
|
82
|
-
return (datetime.now().date() - timedelta(days=2)).strftime("%Y-%m-%d")
|
|
83
|
-
|
|
84
|
-
@staticmethod
|
|
85
|
-
def tomorrow_date() -> str:
|
|
86
|
-
"""获取明天的日期"""
|
|
87
|
-
return (datetime.now().date() + timedelta(days=1)).strftime("%Y-%m-%d")
|
|
88
|
-
|
|
89
|
-
@staticmethod
|
|
90
|
-
def get_last_month() -> int:
|
|
91
|
-
"""获取上个月的月份"""
|
|
92
|
-
today = datetime.today()
|
|
93
|
-
last_month = today.month - 1 if today.month > 1 else 12
|
|
94
|
-
return last_month
|
|
95
|
-
|
|
96
|
-
@staticmethod
|
|
97
|
-
def get_last_two_month() -> int:
|
|
98
|
-
"""获取上上个月的月份"""
|
|
99
|
-
today = datetime.today()
|
|
100
|
-
# 计算上上个月:当前月份减2
|
|
101
|
-
last_two_month = today.month - 2
|
|
102
|
-
# 处理跨年情况
|
|
103
|
-
if last_two_month < 1:
|
|
104
|
-
last_two_month += 12
|
|
105
|
-
return last_two_month
|
|
106
|
-
|
|
107
|
-
# ==================== 日期范围计算 ====================
|
|
108
|
-
|
|
109
|
-
@staticmethod
|
|
110
|
-
def get_past_7_days_range(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> Tuple[str, str,]:
|
|
111
|
-
"""
|
|
112
|
-
获取过去7天的日期范围(包括结束日,共7天)
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
116
|
-
|
|
117
|
-
Returns:
|
|
118
|
-
(start_date_str, end_date_str) 日期范围元组
|
|
119
|
-
|
|
120
|
-
Example:
|
|
121
|
-
>>> get_past_7_days_range('2025-07-02')
|
|
122
|
-
('2025-06-25', '2025-07-01')
|
|
123
|
-
"""
|
|
124
|
-
if start_from:
|
|
125
|
-
try:
|
|
126
|
-
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
127
|
-
except ValueError:
|
|
128
|
-
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
129
|
-
else:
|
|
130
|
-
base_date = datetime.today()
|
|
131
|
-
|
|
132
|
-
end_date = base_date - timedelta(days=1) # 默认昨天为结束
|
|
133
|
-
start_date = end_date - timedelta(days=6) # 往前推6天为开始
|
|
134
|
-
|
|
135
|
-
return start_date.strftime(format_str), end_date.strftime(format_str)
|
|
136
|
-
|
|
137
|
-
@staticmethod
|
|
138
|
-
def get_past_7_days_range_format(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> Tuple[str, str]:
|
|
139
|
-
"""
|
|
140
|
-
获取过去7天的日期范围(包括结束日,共7天),支持自定义格式
|
|
141
|
-
|
|
142
|
-
Args:
|
|
143
|
-
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
144
|
-
format_str: 日期格式字符串
|
|
145
|
-
|
|
146
|
-
Returns:
|
|
147
|
-
(start_date_str, end_date_str) 日期范围元组
|
|
148
|
-
"""
|
|
149
|
-
if start_from:
|
|
150
|
-
try:
|
|
151
|
-
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
152
|
-
except ValueError:
|
|
153
|
-
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
154
|
-
else:
|
|
155
|
-
base_date = datetime.today()
|
|
156
|
-
|
|
157
|
-
end_date = base_date - timedelta(days=1) # 默认昨天为结束
|
|
158
|
-
start_date = end_date - timedelta(days=6) # 往前推6天为开始
|
|
159
|
-
|
|
160
|
-
return start_date.strftime(format_str), end_date.strftime(format_str)
|
|
161
|
-
|
|
162
|
-
@staticmethod
|
|
163
|
-
def get_month_first_day(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> str:
|
|
164
|
-
"""
|
|
165
|
-
获取某月的第一天
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
start_from: 参考日期,格式为'YYYY-MM-DD',默认使用今天
|
|
169
|
-
format_str: 返回的日期格式,默认是'%Y-%m-%d'
|
|
170
|
-
|
|
171
|
-
Returns:
|
|
172
|
-
指定格式的某月第一天日期字符串
|
|
173
|
-
|
|
174
|
-
Example:
|
|
175
|
-
>>> get_month_first_day('2025-07-02')
|
|
176
|
-
'2025-07-01'
|
|
177
|
-
"""
|
|
178
|
-
if start_from:
|
|
179
|
-
try:
|
|
180
|
-
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
181
|
-
except ValueError:
|
|
182
|
-
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
183
|
-
else:
|
|
184
|
-
base_date = datetime.today()
|
|
185
|
-
|
|
186
|
-
# 获取当月第一天
|
|
187
|
-
first_day = base_date.replace(day=1)
|
|
188
|
-
return first_day.strftime(format_str)
|
|
189
|
-
|
|
190
|
-
@staticmethod
|
|
191
|
-
def get_past_nth_day(n: int, start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> str:
|
|
192
|
-
"""
|
|
193
|
-
获取过去第n天的日期
|
|
194
|
-
|
|
195
|
-
Args:
|
|
196
|
-
n: 获取过去第n天的日期(n=1 表示昨天,n=2 表示前天,以此类推)
|
|
197
|
-
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
198
|
-
|
|
199
|
-
Returns:
|
|
200
|
-
'YYYY-MM-DD' 格式的日期
|
|
201
|
-
|
|
202
|
-
Example:
|
|
203
|
-
>>> get_past_nth_day(29, '2025-07-02')
|
|
204
|
-
'2025-06-03'
|
|
205
|
-
"""
|
|
206
|
-
if start_from:
|
|
207
|
-
try:
|
|
208
|
-
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
209
|
-
except ValueError:
|
|
210
|
-
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
211
|
-
else:
|
|
212
|
-
base_date = datetime.today()
|
|
213
|
-
|
|
214
|
-
past_date = base_date - timedelta(days=n)
|
|
215
|
-
return past_date.strftime(format_str)
|
|
216
|
-
|
|
217
|
-
@staticmethod
|
|
218
|
-
def get_past_n_days_list(n: int, start_from: Optional[str] = None) -> List[str]:
|
|
219
|
-
"""
|
|
220
|
-
获取过去n天的日期列表,从最旧到最近的日期
|
|
221
|
-
|
|
222
|
-
Args:
|
|
223
|
-
n: 获取过去多少天
|
|
224
|
-
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
225
|
-
|
|
226
|
-
Returns:
|
|
227
|
-
['YYYY-MM-DD', ..., 'YYYY-MM-DD'],从旧到新排序
|
|
228
|
-
|
|
229
|
-
Example:
|
|
230
|
-
>>> get_past_n_days_list(7, '2025-07-02')
|
|
231
|
-
['2025-07-01', '2025-06-30', '2025-06-29', '2025-06-28', '2025-06-27', '2025-06-26', '2025-06-25']
|
|
232
|
-
"""
|
|
233
|
-
if start_from:
|
|
234
|
-
try:
|
|
235
|
-
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
236
|
-
except ValueError:
|
|
237
|
-
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
238
|
-
else:
|
|
239
|
-
base_date = datetime.today()
|
|
240
|
-
|
|
241
|
-
return [
|
|
242
|
-
(base_date - timedelta(days=i)).strftime('%Y-%m-%d')
|
|
243
|
-
for i in range(1, n + 1)
|
|
244
|
-
]
|
|
245
|
-
|
|
246
|
-
@staticmethod
|
|
247
|
-
def get_past_7_days_list(start_from: Optional[str] = None) -> List[str]:
|
|
248
|
-
"""
|
|
249
|
-
获取过去7天的日期列表(不包含 start_from 当天),共7天
|
|
250
|
-
|
|
251
|
-
Args:
|
|
252
|
-
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
253
|
-
|
|
254
|
-
Returns:
|
|
255
|
-
['YYYY-MM-DD', ..., 'YYYY-MM-DD'],从旧到新排序
|
|
256
|
-
"""
|
|
257
|
-
if start_from:
|
|
258
|
-
try:
|
|
259
|
-
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
260
|
-
except ValueError:
|
|
261
|
-
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
262
|
-
else:
|
|
263
|
-
base_date = datetime.today()
|
|
264
|
-
|
|
265
|
-
return [
|
|
266
|
-
(base_date - timedelta(days=i)).strftime('%Y-%m-%d')
|
|
267
|
-
for i in range(1, 8)
|
|
268
|
-
]
|
|
269
|
-
|
|
270
|
-
@staticmethod
|
|
271
|
-
def date_range(start_date: str, end_date: str) -> List[str]:
|
|
272
|
-
"""
|
|
273
|
-
生成两个日期之间的日期列表
|
|
274
|
-
|
|
275
|
-
Args:
|
|
276
|
-
start_date: 开始日期,格式为YYYY-MM-DD
|
|
277
|
-
end_date: 结束日期,格式为YYYY-MM-DD
|
|
278
|
-
|
|
279
|
-
Returns:
|
|
280
|
-
包含两个日期之间所有日期的列表,日期格式为YYYY-MM-DD
|
|
281
|
-
|
|
282
|
-
Raises:
|
|
283
|
-
ValueError: 当开始日期大于结束日期时
|
|
284
|
-
"""
|
|
285
|
-
start = datetime.strptime(start_date, "%Y-%m-%d")
|
|
286
|
-
end = datetime.strptime(end_date, "%Y-%m-%d")
|
|
287
|
-
|
|
288
|
-
if start > end:
|
|
289
|
-
raise ValueError("开始日期不能大于结束日期")
|
|
290
|
-
|
|
291
|
-
date_list = []
|
|
292
|
-
current_date = start
|
|
293
|
-
while current_date <= end:
|
|
294
|
-
date_list.append(current_date.strftime("%Y-%m-%d"))
|
|
295
|
-
current_date += timedelta(days=1)
|
|
296
|
-
|
|
297
|
-
return date_list
|
|
298
|
-
|
|
299
|
-
@staticmethod
|
|
300
|
-
def get_dates_from_first_of_month_to_yesterday() -> List[str]:
|
|
301
|
-
"""获取从本月第一天到昨天的日期列表
|
|
302
|
-
如果今天是本月第一天,则返回上个月的日期列表
|
|
303
|
-
"""
|
|
304
|
-
today = datetime.today()
|
|
305
|
-
yesterday = today - timedelta(days=1)
|
|
306
|
-
|
|
307
|
-
# 如果今天是本月第一天,取上个月
|
|
308
|
-
if today.day == 1:
|
|
309
|
-
# 找到上个月最后一天
|
|
310
|
-
last_month_last_day = today - timedelta(days=1)
|
|
311
|
-
# 上个月第一天
|
|
312
|
-
first_day_of_last_month = last_month_last_day.replace(day=1)
|
|
313
|
-
start_date = first_day_of_last_month
|
|
314
|
-
end_date = last_month_last_day
|
|
315
|
-
else:
|
|
316
|
-
start_date = today.replace(day=1)
|
|
317
|
-
end_date = yesterday
|
|
318
|
-
|
|
319
|
-
date_list = []
|
|
320
|
-
current_date = start_date
|
|
321
|
-
while current_date <= end_date:
|
|
322
|
-
date_list.append(current_date.strftime('%Y-%m-%d'))
|
|
323
|
-
current_date += timedelta(days=1)
|
|
324
|
-
|
|
325
|
-
return date_list
|
|
326
|
-
|
|
327
|
-
# ==================== 月份相关 ====================
|
|
328
|
-
|
|
329
|
-
@staticmethod
|
|
330
|
-
def get_last_month_range() -> Tuple[str, str]:
|
|
331
|
-
"""获取上个月的第一天和最后一天"""
|
|
332
|
-
today = datetime.today()
|
|
333
|
-
last_month = today.month - 1 if today.month > 1 else 12
|
|
334
|
-
year = today.year if today.month > 1 else today.year - 1
|
|
335
|
-
|
|
336
|
-
first_day = datetime(year, last_month, 1)
|
|
337
|
-
last_day = datetime(year, last_month, calendar.monthrange(year, last_month)[1])
|
|
338
|
-
|
|
339
|
-
return first_day.strftime("%Y-%m-%d"), last_day.strftime("%Y-%m-%d")
|
|
340
|
-
|
|
341
|
-
@staticmethod
|
|
342
|
-
def get_last_two_month_range() -> Tuple[str, str]:
|
|
343
|
-
"""获取上上个月的第一天和最后一天"""
|
|
344
|
-
today = datetime.today()
|
|
345
|
-
# 计算上上个月
|
|
346
|
-
last_two_month = today.month - 2
|
|
347
|
-
year = today.year
|
|
348
|
-
|
|
349
|
-
# 处理跨年情况
|
|
350
|
-
if last_two_month < 1:
|
|
351
|
-
last_two_month += 12
|
|
352
|
-
year -= 1
|
|
353
|
-
|
|
354
|
-
first_day = datetime(year, last_two_month, 1)
|
|
355
|
-
last_day = datetime(year, last_two_month, calendar.monthrange(year, last_two_month)[1])
|
|
356
|
-
|
|
357
|
-
return first_day.strftime("%Y-%m-%d"), last_day.strftime("%Y-%m-%d")
|
|
358
|
-
|
|
359
|
-
@staticmethod
|
|
360
|
-
def get_last_month_range_time_str() -> Tuple[str, str]:
|
|
361
|
-
"""获取上个月第一天和最后一天的时间字符串"""
|
|
362
|
-
today = datetime.today()
|
|
363
|
-
last_month = today.month - 1 if today.month > 1 else 12
|
|
364
|
-
year = today.year if today.month > 1 else today.year - 1
|
|
365
|
-
|
|
366
|
-
first_day = datetime(year, last_month, 1, 0, 0, 0)
|
|
367
|
-
last_day = datetime(year, last_month, calendar.monthrange(year, last_month)[1], 23, 59, 59)
|
|
368
|
-
|
|
369
|
-
start_time_str = first_day.strftime("%Y-%m-%d %H:%M:%S")
|
|
370
|
-
end_time_str = last_day.strftime("%Y-%m-%d %H:%M:%S")
|
|
371
|
-
|
|
372
|
-
return start_time_str, end_time_str
|
|
373
|
-
|
|
374
|
-
@staticmethod
|
|
375
|
-
def get_last_month_range_time() -> Tuple[int, int]:
|
|
376
|
-
"""获取上个月第一天和最后一天的毫秒级时间戳"""
|
|
377
|
-
today = datetime.today()
|
|
378
|
-
last_month = today.month - 1 if today.month > 1 else 12
|
|
379
|
-
year = today.year if today.month > 1 else today.year - 1
|
|
380
|
-
|
|
381
|
-
first_day = datetime(year, last_month, 1, 0, 0, 0)
|
|
382
|
-
last_day = datetime(year, last_month, calendar.monthrange(year, last_month)[1], 23, 59, 59, 0)
|
|
383
|
-
|
|
384
|
-
start_timestamp = int(first_day.timestamp() * 1000)
|
|
385
|
-
end_timestamp = int(last_day.timestamp() * 1000)
|
|
386
|
-
|
|
387
|
-
return start_timestamp, end_timestamp
|
|
388
|
-
|
|
389
|
-
@staticmethod
|
|
390
|
-
def get_year_range_time(year=2024):
|
|
391
|
-
"""获取某一整年的第一天和最后一天的毫秒级时间戳"""
|
|
392
|
-
first_day = datetime(year, 1, 1, 0, 0, 0)
|
|
393
|
-
last_day = datetime(year, 12, 31, 0, 0, 0, 0)
|
|
394
|
-
|
|
395
|
-
start_timestamp = int(first_day.timestamp() * 1000)
|
|
396
|
-
end_timestamp = int(last_day.timestamp() * 1000)
|
|
397
|
-
|
|
398
|
-
return start_timestamp, end_timestamp
|
|
399
|
-
|
|
400
|
-
@staticmethod
|
|
401
|
-
def is_in_month(time_str: str, month: int, fmt: str = "%Y-%m-%d") -> bool:
|
|
402
|
-
"""
|
|
403
|
-
判断时间字符串是否在指定月份
|
|
404
|
-
|
|
405
|
-
Args:
|
|
406
|
-
time_str: 时间字符串
|
|
407
|
-
month: 月份(1-12)
|
|
408
|
-
fmt: 时间格式
|
|
409
|
-
|
|
410
|
-
Returns:
|
|
411
|
-
如果时间在指定月份返回True,否则返回False
|
|
412
|
-
"""
|
|
413
|
-
try:
|
|
414
|
-
dt = datetime.strptime(time_str, fmt)
|
|
415
|
-
return dt.month == month
|
|
416
|
-
except ValueError:
|
|
417
|
-
return False
|
|
418
|
-
|
|
419
|
-
# ==================== 星期相关 ====================
|
|
420
|
-
|
|
421
|
-
@staticmethod
|
|
422
|
-
def get_week_num() -> int:
|
|
423
|
-
"""获取当前是第几周"""
|
|
424
|
-
today = date.today()
|
|
425
|
-
week_num = today.isocalendar()[1] # 返回 (year, week_num, weekday)
|
|
426
|
-
return week_num
|
|
427
|
-
|
|
428
|
-
@staticmethod
|
|
429
|
-
def get_chinese_weekday(date_str: str) -> str:
|
|
430
|
-
"""
|
|
431
|
-
根据输入的日期字符串返回中文星期几
|
|
432
|
-
|
|
433
|
-
Args:
|
|
434
|
-
date_str: 格式为'YYYY-MM-DD'的日期字符串
|
|
435
|
-
|
|
436
|
-
Returns:
|
|
437
|
-
中文星期几,如'星期一'
|
|
438
|
-
|
|
439
|
-
Example:
|
|
440
|
-
>>> get_chinese_weekday('2025-04-15')
|
|
441
|
-
'星期二'
|
|
442
|
-
"""
|
|
443
|
-
try:
|
|
444
|
-
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
|
|
445
|
-
weekday_num = date_obj.weekday()
|
|
446
|
-
weekday_cn = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
|
|
447
|
-
return weekday_cn[weekday_num]
|
|
448
|
-
except ValueError as e:
|
|
449
|
-
raise ValueError(f"日期格式错误,请输入'YYYY-MM-DD'格式的日期字符串。错误详情: {str(e)}")
|
|
450
|
-
|
|
451
|
-
@staticmethod
|
|
452
|
-
def get_weekday_name(date_str: str) -> str:
|
|
453
|
-
"""获取中文星期名称(简短格式)"""
|
|
454
|
-
weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
|
|
455
|
-
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
|
|
456
|
-
return weekdays[date_obj.weekday()]
|
|
457
|
-
|
|
458
|
-
# ==================== 时间段相关 ====================
|
|
459
|
-
|
|
460
|
-
@staticmethod
|
|
461
|
-
def get_period() -> str:
|
|
462
|
-
"""获取当前时间段(上午/下午/晚上)"""
|
|
463
|
-
hour = datetime.now().hour
|
|
464
|
-
if 5 <= hour < 12:
|
|
465
|
-
return "上午"
|
|
466
|
-
elif 12 <= hour < 18:
|
|
467
|
-
return "下午"
|
|
468
|
-
else:
|
|
469
|
-
return "晚上"
|
|
470
|
-
|
|
471
|
-
@staticmethod
|
|
472
|
-
def get_period2() -> str:
|
|
473
|
-
"""获取当前时间段(AM/PM)"""
|
|
474
|
-
now = datetime.now()
|
|
475
|
-
period = now.strftime("%p") # 返回AM或者PM
|
|
476
|
-
return period
|
|
477
|
-
|
|
478
|
-
# ==================== 时间戳转换 ====================
|
|
479
|
-
|
|
480
|
-
@staticmethod
|
|
481
|
-
def convert_timestamp_to_str(timestamp_ms: Optional[int]) -> str:
|
|
482
|
-
"""
|
|
483
|
-
将毫秒时间戳转换为字符串
|
|
484
|
-
|
|
485
|
-
Args:
|
|
486
|
-
timestamp_ms: 毫秒时间戳
|
|
487
|
-
|
|
488
|
-
Returns:
|
|
489
|
-
格式化的时间字符串,如果输入为None则返回'-'
|
|
490
|
-
"""
|
|
491
|
-
if timestamp_ms is None:
|
|
492
|
-
return '-'
|
|
493
|
-
timestamp_s = int(timestamp_ms) / 1000
|
|
494
|
-
dt = datetime.fromtimestamp(timestamp_s)
|
|
495
|
-
return dt.strftime('%Y-%m-%d %H:%M:%S')
|
|
496
|
-
|
|
497
|
-
@staticmethod
|
|
498
|
-
def convert_timestamp_to_date(timestamp_ms: Union[int, float]) -> str:
|
|
499
|
-
"""
|
|
500
|
-
将毫秒时间戳转换为日期字符串
|
|
501
|
-
|
|
502
|
-
Args:
|
|
503
|
-
timestamp_ms: 毫秒时间戳
|
|
504
|
-
|
|
505
|
-
Returns:
|
|
506
|
-
YYYY-MM-DD 格式的日期字符串
|
|
507
|
-
"""
|
|
508
|
-
timestamp_s = timestamp_ms / 1000
|
|
509
|
-
dt = datetime.fromtimestamp(timestamp_s)
|
|
510
|
-
return dt.strftime('%Y-%m-%d')
|
|
511
|
-
|
|
512
|
-
@staticmethod
|
|
513
|
-
def get_start_timestamps(date_str: str) -> int:
|
|
514
|
-
"""
|
|
515
|
-
获取指定日期的开始毫秒时间戳(00:00:00.000)
|
|
516
|
-
|
|
517
|
-
Args:
|
|
518
|
-
date_str: 格式为"YYYY-MM-DD"的日期字符串
|
|
519
|
-
|
|
520
|
-
Returns:
|
|
521
|
-
开始毫秒时间戳
|
|
522
|
-
"""
|
|
523
|
-
start_of_day = datetime.strptime(date_str, "%Y-%m-%d")
|
|
524
|
-
return int(start_of_day.timestamp() * 1000)
|
|
525
|
-
|
|
526
|
-
@staticmethod
|
|
527
|
-
def get_end_timestamps(date_str: str) -> int:
|
|
528
|
-
"""
|
|
529
|
-
获取指定日期的结束毫秒时间戳(23:59:59.999)
|
|
530
|
-
|
|
531
|
-
Args:
|
|
532
|
-
date_str: 格式为"YYYY-MM-DD"的日期字符串
|
|
533
|
-
|
|
534
|
-
Returns:
|
|
535
|
-
结束毫秒时间戳
|
|
536
|
-
"""
|
|
537
|
-
start_of_day = datetime.strptime(date_str, "%Y-%m-%d")
|
|
538
|
-
end_of_day = start_of_day + timedelta(days=1) - timedelta(milliseconds=1)
|
|
539
|
-
return int(end_of_day.timestamp() * 1000)
|
|
540
|
-
|
|
541
|
-
# ==================== 日期格式转换 ====================
|
|
542
|
-
|
|
543
|
-
@staticmethod
|
|
544
|
-
def convert_datetime_to_date(datetime_str: str) -> str:
|
|
545
|
-
"""
|
|
546
|
-
将格式为 'YYYY-MM-DD HH:MM:SS' 的时间字符串转换为 'YYYY-MM-DD' 格式的日期字符串
|
|
547
|
-
|
|
548
|
-
Args:
|
|
549
|
-
datetime_str: 时间字符串,格式为 'YYYY-MM-DD HH:MM:SS'
|
|
550
|
-
|
|
551
|
-
Returns:
|
|
552
|
-
日期字符串,格式为 'YYYY-MM-DD'
|
|
553
|
-
|
|
554
|
-
Example:
|
|
555
|
-
>>> convert_datetime_to_date("2025-06-27 09:49:16")
|
|
556
|
-
'2025-06-27'
|
|
557
|
-
"""
|
|
558
|
-
try:
|
|
559
|
-
dt_obj = datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S')
|
|
560
|
-
return dt_obj.strftime('%Y-%m-%d')
|
|
561
|
-
except ValueError:
|
|
562
|
-
print(f"输入的时间字符串格式错误,需要 'YYYY-MM-DD HH:MM:SS' 格式,但得到: {datetime_str}")
|
|
563
|
-
return datetime_str
|
|
564
|
-
|
|
565
|
-
@staticmethod
|
|
566
|
-
def date_trans(d_t: str) -> str:
|
|
567
|
-
"""
|
|
568
|
-
无斜杠日期转成有斜杠日期
|
|
569
|
-
|
|
570
|
-
Args:
|
|
571
|
-
d_t: 格式为 YYYY-MM-DD 的日期字符串
|
|
572
|
-
|
|
573
|
-
Returns:
|
|
574
|
-
格式为 YYYYMMDD 的日期字符串
|
|
575
|
-
"""
|
|
576
|
-
return datetime.strptime(d_t, "%Y-%m-%d").strftime("%Y%m%d")
|
|
577
|
-
|
|
578
|
-
@staticmethod
|
|
579
|
-
def format_date_cross_platform(date_str: str) -> str:
|
|
580
|
-
"""
|
|
581
|
-
跨平台格式化日期
|
|
582
|
-
|
|
583
|
-
Args:
|
|
584
|
-
date_str: 格式为 YYYY-MM-DD 的日期字符串
|
|
585
|
-
|
|
586
|
-
Returns:
|
|
587
|
-
格式化后的日期字符串
|
|
588
|
-
"""
|
|
589
|
-
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
|
|
590
|
-
import platform
|
|
591
|
-
if platform.system() == "Windows":
|
|
592
|
-
return date_obj.strftime("%Y/%#m/%#d")
|
|
593
|
-
else: # Linux, macOS等
|
|
594
|
-
return date_obj.strftime("%Y/%-m/%-d")
|
|
595
|
-
|
|
596
|
-
# ==================== 日期比较和判断 ====================
|
|
597
|
-
|
|
598
|
-
@staticmethod
|
|
599
|
-
def is_date_greater_or_equal(date_str: str) -> bool:
|
|
600
|
-
"""
|
|
601
|
-
比较指定日期是否大于或等于今天的日期
|
|
602
|
-
|
|
603
|
-
Args:
|
|
604
|
-
date_str: 格式为YYYY-MM-DD的日期字符串
|
|
605
|
-
|
|
606
|
-
Returns:
|
|
607
|
-
如果指定日期大于或等于今天返回True,否则返回False
|
|
608
|
-
"""
|
|
609
|
-
try:
|
|
610
|
-
year, month, day = map(int, date_str.split('-'))
|
|
611
|
-
input_date = date(year, month, day)
|
|
612
|
-
today = date.today()
|
|
613
|
-
return input_date >= today
|
|
614
|
-
except ValueError:
|
|
615
|
-
print("日期格式不正确,请使用YYYY-MM-DD格式")
|
|
616
|
-
return False
|
|
617
|
-
|
|
618
|
-
@staticmethod
|
|
619
|
-
def is_yesterday(create_time_str: str, dt: Optional[str] = None) -> bool:
|
|
620
|
-
"""
|
|
621
|
-
判断给定的时间字符串是否是昨天
|
|
622
|
-
|
|
623
|
-
Args:
|
|
624
|
-
create_time_str: 创建时间字符串,格式为 "%Y-%m-%d %H:%M:%S"
|
|
625
|
-
dt: 日期字符串,格式为 "%Y-%m-%d" 表示某一天,默认为今天
|
|
626
|
-
|
|
627
|
-
Returns:
|
|
628
|
-
如果 create_time_str 是昨天的日期,返回 True,否则返回 False
|
|
629
|
-
"""
|
|
630
|
-
try:
|
|
631
|
-
create_time = datetime.strptime(create_time_str, "%Y-%m-%d %H:%M:%S")
|
|
632
|
-
if dt is None:
|
|
633
|
-
dt = datetime.now()
|
|
634
|
-
else:
|
|
635
|
-
dt = datetime.strptime(dt, "%Y%m%d")
|
|
636
|
-
except ValueError:
|
|
637
|
-
raise ValueError("时间字符串格式不正确,请使用正确的格式:'%Y-%m-%d %H:%M:%S' 和 '%Y-%m-%d'")
|
|
638
|
-
|
|
639
|
-
yesterday = dt - timedelta(days=1)
|
|
640
|
-
return create_time.date() == yesterday.date()
|
|
641
|
-
|
|
642
|
-
@staticmethod
|
|
643
|
-
def is_yesterday_date(date_str: str, format="%Y-%m-%d") -> bool:
|
|
644
|
-
"""
|
|
645
|
-
判断给定的日期字符串是否是昨天
|
|
646
|
-
|
|
647
|
-
Args:
|
|
648
|
-
date_str: 日期字符串,格式为 "%Y-%m-%d"
|
|
649
|
-
|
|
650
|
-
Returns:
|
|
651
|
-
如果 date_str 是昨天的日期,返回 True,否则返回 False
|
|
652
|
-
"""
|
|
653
|
-
try:
|
|
654
|
-
create_time = datetime.strptime(date_str, format)
|
|
655
|
-
dt = datetime.now()
|
|
656
|
-
except ValueError:
|
|
657
|
-
raise ValueError("时间字符串格式不正确,请使用正确的格式:'%Y-%m-%d'")
|
|
658
|
-
|
|
659
|
-
yesterday = dt - timedelta(days=1)
|
|
660
|
-
return create_time.date() == yesterday.date()
|
|
661
|
-
|
|
662
|
-
# ==================== 文件时间相关 ====================
|
|
663
|
-
|
|
664
|
-
@staticmethod
|
|
665
|
-
def get_file_mtime(file_path: str, to_str: bool = True, tz_offset: int = 8) -> Union[str, datetime]:
|
|
666
|
-
"""
|
|
667
|
-
获取文件的修改时间
|
|
668
|
-
|
|
669
|
-
Args:
|
|
670
|
-
file_path: 文件路径
|
|
671
|
-
to_str: 是否返回格式化字符串(默认 True)
|
|
672
|
-
tz_offset: 时区偏移(默认东八区 +8)
|
|
673
|
-
|
|
674
|
-
Returns:
|
|
675
|
-
格式化时间字符串或 datetime 对象
|
|
676
|
-
|
|
677
|
-
Raises:
|
|
678
|
-
FileNotFoundError: 当文件不存在时
|
|
679
|
-
"""
|
|
680
|
-
if not os.path.exists(file_path):
|
|
681
|
-
raise FileNotFoundError(f"文件不存在: {file_path}")
|
|
682
|
-
|
|
683
|
-
mtime = os.path.getmtime(file_path)
|
|
684
|
-
tz = timezone(timedelta(hours=tz_offset))
|
|
685
|
-
mtime_dt = datetime.fromtimestamp(mtime, tz=tz)
|
|
686
|
-
|
|
687
|
-
return mtime_dt.strftime('%Y-%m-%d %H:%M:%S') if to_str else mtime_dt
|
|
688
|
-
|
|
689
|
-
# ==================== 便捷函数 ====================
|
|
690
|
-
# 为了保持向后兼容,提供一些便捷函数
|
|
691
|
-
|
|
692
|
-
def get_current_date() -> str:
|
|
693
|
-
"""获取当前日期,格式为 YYYYMMDD"""
|
|
694
|
-
return TimeUtils.get_current_date()
|
|
695
|
-
|
|
696
|
-
def get_current_datetime() -> str:
|
|
697
|
-
"""获取当前日期时间,格式为 YYYYMMDDHHMMSS"""
|
|
698
|
-
return TimeUtils.get_current_datetime()
|
|
699
|
-
|
|
700
|
-
def current_datetime() -> str:
|
|
701
|
-
"""获取当前日期时间,格式为 YYYY-MM-DD HH:MM:SS"""
|
|
702
|
-
return TimeUtils.current_datetime()
|
|
703
|
-
|
|
704
|
-
def today_date() -> str:
|
|
705
|
-
"""获取今天的日期,格式为 YYYY-MM-DD"""
|
|
706
|
-
return TimeUtils.today_date()
|
|
707
|
-
|
|
708
|
-
def today_date_hour() -> str:
|
|
709
|
-
"""获取今天的日期和小时,格式为 YYYY-MM-DD_HH"""
|
|
710
|
-
return TimeUtils.today_date_hour()
|
|
711
|
-
|
|
712
|
-
def get_yesterday(dt: Optional[str] = None) -> str:
|
|
713
|
-
"""获取昨天的日期"""
|
|
714
|
-
return TimeUtils.get_yesterday(dt)
|
|
715
|
-
|
|
716
|
-
def tomorrow_date() -> str:
|
|
717
|
-
"""获取明天的日期"""
|
|
718
|
-
return TimeUtils.tomorrow_date()
|
|
719
|
-
|
|
720
|
-
def before_yesterday() -> str:
|
|
721
|
-
"""获取前天的日期"""
|
|
722
|
-
return TimeUtils.before_yesterday()
|
|
723
|
-
|
|
724
|
-
def get_current_year() -> int:
|
|
725
|
-
"""获取当前年份"""
|
|
726
|
-
return TimeUtils.get_current_year()
|
|
727
|
-
|
|
728
|
-
def get_current_month() -> int:
|
|
729
|
-
"""获取当前月份"""
|
|
730
|
-
return TimeUtils.get_current_month()
|
|
731
|
-
|
|
732
|
-
def get_last_month() -> int:
|
|
733
|
-
"""获取上个月的月份"""
|
|
734
|
-
return TimeUtils.get_last_month()
|
|
735
|
-
|
|
736
|
-
def get_week_num() -> int:
|
|
737
|
-
"""获取当前是第几周"""
|
|
738
|
-
return TimeUtils.get_week_num()
|
|
739
|
-
|
|
740
|
-
def get_period() -> str:
|
|
741
|
-
"""获取当前时间段(上午/下午/晚上)"""
|
|
742
|
-
return TimeUtils.get_period()
|
|
743
|
-
|
|
744
|
-
def get_period2() -> str:
|
|
745
|
-
"""获取当前时间段(AM/PM)"""
|
|
746
|
-
return TimeUtils.get_period2()
|
|
747
|
-
|
|
748
|
-
def get_chinese_weekday(date_str: str) -> str:
|
|
749
|
-
"""根据输入的日期字符串返回中文星期几"""
|
|
750
|
-
return TimeUtils.get_chinese_weekday(date_str)
|
|
751
|
-
|
|
752
|
-
def get_weekday_name(date_str: str) -> str:
|
|
753
|
-
"""获取中文星期名称(简短格式)"""
|
|
754
|
-
return TimeUtils.get_weekday_name(date_str)
|
|
755
|
-
|
|
756
|
-
def is_in_month(time_str: str, month: int, fmt: str = "%Y-%m-%d") -> bool:
|
|
757
|
-
"""判断时间字符串是否在指定月份"""
|
|
758
|
-
return TimeUtils.is_in_month(time_str, month, fmt)
|
|
759
|
-
|
|
760
|
-
def date_trans(d_t: str) -> str:
|
|
761
|
-
"""无斜杠日期转成有斜杠日期"""
|
|
762
|
-
return TimeUtils.date_trans(d_t)
|
|
763
|
-
|
|
764
|
-
def is_date_greater_or_equal(date_str: str) -> bool:
|
|
765
|
-
"""比较指定日期是否大于或等于今天的日期"""
|
|
766
|
-
return TimeUtils.is_date_greater_or_equal(date_str)
|
|
767
|
-
|
|
768
|
-
def is_yesterday(create_time_str: str, dt: Optional[str] = None) -> bool:
|
|
769
|
-
"""判断给定的时间字符串是否是昨天"""
|
|
770
|
-
return TimeUtils.is_yesterday(create_time_str, dt)
|
|
771
|
-
|
|
772
|
-
def is_yesterday_date(date_str: str) -> bool:
|
|
773
|
-
"""判断给定的日期字符串是否是昨天"""
|
|
774
|
-
return TimeUtils.is_yesterday_date(date_str)
|
|
775
|
-
|
|
776
|
-
def get_file_mtime(file_path: str, to_str: bool = True, tz_offset: int = 8) -> Union[str, datetime]:
|
|
777
|
-
"""获取文件的修改时间"""
|
|
778
|
-
return TimeUtils.get_file_mtime(file_path, to_str, tz_offset)
|
|
779
|
-
|
|
780
|
-
def convert_timestamp_to_str(timestamp_ms: Optional[int]) -> str:
|
|
781
|
-
"""将毫秒时间戳转换为字符串"""
|
|
782
|
-
return TimeUtils.convert_timestamp_to_str(timestamp_ms)
|
|
783
|
-
|
|
784
|
-
def convert_timestamp_to_date(timestamp_ms: Union[int, float]) -> str:
|
|
785
|
-
"""将毫秒时间戳转换为日期字符串"""
|
|
786
|
-
return TimeUtils.convert_timestamp_to_date(timestamp_ms)
|
|
787
|
-
|
|
788
|
-
def convert_datetime_to_date(datetime_str: str) -> str:
|
|
789
|
-
"""将格式为 'YYYY-MM-DD HH:MM:SS' 的时间字符串转换为 'YYYY-MM-DD' 格式的日期字符串"""
|
|
790
|
-
return TimeUtils.convert_datetime_to_date(datetime_str)
|
|
791
|
-
|
|
792
|
-
def get_current_year_range() -> Tuple[str, str]:
|
|
793
|
-
"""获取当前年份的开始和结束日期"""
|
|
794
|
-
return TimeUtils.get_current_year_range()
|
|
795
|
-
|
|
796
|
-
def get_start_timestamps(date_str: str) -> int:
|
|
797
|
-
"""获取指定日期的开始毫秒时间戳(00:00:00.000)"""
|
|
798
|
-
return TimeUtils.get_start_timestamps(date_str)
|
|
799
|
-
|
|
800
|
-
def get_end_timestamps(date_str: str) -> int:
|
|
801
|
-
"""获取指定日期的结束毫秒时间戳(23:59:59.999)"""
|
|
802
|
-
return TimeUtils.get_end_timestamps(date_str)
|
|
803
|
-
|
|
804
|
-
def format_date_cross_platform(date_str: str) -> str:
|
|
805
|
-
"""跨平台格式化日期"""
|
|
806
|
-
return TimeUtils.format_date_cross_platform(date_str)
|
|
807
|
-
|
|
808
|
-
def get_past_7_days_range(start_from: Optional[str] = None) -> Tuple[str, str]:
|
|
809
|
-
"""获取过去7天的日期范围(包括结束日,共7天)"""
|
|
810
|
-
return TimeUtils.get_past_7_days_range(start_from)
|
|
811
|
-
|
|
812
|
-
def get_past_7_days_range_format(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> Tuple[str, str]:
|
|
813
|
-
"""获取过去7天的日期范围(包括结束日,共7天),支持自定义格式"""
|
|
814
|
-
return TimeUtils.get_past_7_days_range_format(start_from, format_str)
|
|
815
|
-
|
|
816
|
-
def get_past_nth_day(n: int, start_from: Optional[str] = None) -> str:
|
|
817
|
-
"""获取过去第n天的日期"""
|
|
818
|
-
return TimeUtils.get_past_nth_day(n, start_from)
|
|
819
|
-
|
|
820
|
-
def get_past_n_days_list(n: int, start_from: Optional[str] = None) -> List[str]:
|
|
821
|
-
"""获取过去n天的日期列表,从最旧到最近的日期"""
|
|
822
|
-
return TimeUtils.get_past_n_days_list(n, start_from)
|
|
823
|
-
|
|
824
|
-
def get_past_7_days_list(start_from: Optional[str] = None) -> List[str]:
|
|
825
|
-
"""获取过去7天的日期列表(不包含 start_from 当天),共7天"""
|
|
826
|
-
return TimeUtils.get_past_7_days_list(start_from)
|
|
827
|
-
|
|
828
|
-
def date_range(start_date: str, end_date: str) -> List[str]:
|
|
829
|
-
"""生成两个日期之间的日期列表"""
|
|
830
|
-
return TimeUtils.date_range(start_date, end_date)
|
|
831
|
-
|
|
832
|
-
def get_dates_from_first_of_month_to_yesterday() -> List[str]:
|
|
833
|
-
"""获取从本月第一天到昨天的日期列表"""
|
|
834
|
-
return TimeUtils.get_dates_from_first_of_month_to_yesterday()
|
|
835
|
-
|
|
836
|
-
def get_last_month_range() -> Tuple[str, str]:
|
|
837
|
-
"""获取上个月的第一天和最后一天"""
|
|
838
|
-
return TimeUtils.get_last_month_range()
|
|
839
|
-
|
|
840
|
-
def get_last_month_range_time_str() -> Tuple[str, str]:
|
|
841
|
-
"""获取上个月第一天和最后一天的时间字符串"""
|
|
842
|
-
return TimeUtils.get_last_month_range_time_str()
|
|
843
|
-
|
|
844
|
-
def get_last_month_range_time() -> Tuple[int, int]:
|
|
845
|
-
"""获取上个月第一天和最后一天的毫秒级时间戳"""
|
|
846
|
-
return TimeUtils.get_last_month_range_time()
|
|
847
|
-
|
|
848
|
-
# 为了向后兼容,保留一些旧函数名
|
|
849
|
-
def get_past_7_days_range_old() -> Tuple[str, str]:
|
|
850
|
-
"""获取过去7天的日期范围(旧版本)"""
|
|
851
|
-
end_date = datetime.today() - timedelta(days=1) # 昨天为结束日期
|
|
852
|
-
start_date = end_date - timedelta(days=6) # 往前推6天为开始日期
|
|
853
|
-
return start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d')
|
|
854
|
-
|
|
855
|
-
def get_past_7_days_list_old() -> List[str]:
|
|
856
|
-
"""获取过去7天的日期列表(旧版本)"""
|
|
857
|
-
today = datetime.today()
|
|
858
|
-
return [
|
|
859
|
-
(today - timedelta(days=i)).strftime('%Y-%m-%d')
|
|
860
|
-
for i in range(1, 8)
|
|
861
|
-
]
|
|
862
|
-
|
|
863
|
-
if __name__ == "__main__":
|
|
864
|
-
# 测试示例
|
|
865
|
-
print(f"当前日期: {today_date()}")
|
|
866
|
-
print(f"昨天: {get_yesterday()}")
|
|
867
|
-
print(f"明天: {tomorrow_date()}")
|
|
868
|
-
print(f"当前年份: {get_current_year()}")
|
|
869
|
-
print(f"当前月份: {get_current_month()}")
|
|
870
|
-
print(f"当前周数: {get_week_num()}")
|
|
871
|
-
print(f"当前时间段: {get_period()}")
|
|
872
|
-
print(f"中文星期: {get_chinese_weekday(today_date())}")
|
|
873
|
-
|
|
874
|
-
# 测试日期范围
|
|
875
|
-
start, end = get_past_7_days_range()
|
|
876
|
-
print(f"过去7天范围: {start} 到 {end}")
|
|
877
|
-
|
|
878
|
-
# 测试时间戳转换
|
|
879
|
-
current_ts = int(datetime.now().timestamp() * 1000)
|
|
880
|
-
print(f"当前时间戳: {current_ts}")
|
|
881
|
-
print(f"时间戳转字符串: {convert_timestamp_to_str(current_ts)}")
|
|
882
|
-
print(f"时间戳转日期: {convert_timestamp_to_date(current_ts)}")
|
|
1
|
+
"""
|
|
2
|
+
时间工具模块
|
|
3
|
+
提供各种时间相关的工具函数,包括日期获取、格式化、转换、计算等功能
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import calendar
|
|
8
|
+
from datetime import date, datetime, timedelta, timezone
|
|
9
|
+
from typing import Optional, Tuple, List, Union
|
|
10
|
+
|
|
11
|
+
class TimeUtils:
|
|
12
|
+
"""时间工具类,提供各种时间相关的静态方法"""
|
|
13
|
+
|
|
14
|
+
# ==================== 当前时间获取 ====================
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def get_current_date() -> str:
|
|
18
|
+
"""获取当前日期,格式为 YYYYMMDD"""
|
|
19
|
+
return datetime.now().strftime('%Y%m%d')
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def get_current_datetime() -> str:
|
|
23
|
+
"""获取当前日期时间,格式为 YYYYMMDDHHMMSS"""
|
|
24
|
+
return datetime.now().strftime('%Y%m%d%H%M%S')
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def current_datetime() -> str:
|
|
28
|
+
"""获取当前日期时间,格式为 YYYY-MM-DD HH:MM:SS"""
|
|
29
|
+
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def today_date() -> str:
|
|
33
|
+
"""获取今天的日期,格式为 YYYY-MM-DD"""
|
|
34
|
+
return datetime.now().strftime('%Y-%m-%d')
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def today_date_hour() -> str:
|
|
38
|
+
"""获取今天的日期和小时,格式为 YYYY-MM-DD_HH"""
|
|
39
|
+
return datetime.now().strftime('%Y-%m-%d_%H')
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def get_current_year() -> int:
|
|
43
|
+
"""获取当前年份"""
|
|
44
|
+
return datetime.now().year
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def get_current_month() -> int:
|
|
48
|
+
"""获取当前月份(1-12)"""
|
|
49
|
+
return datetime.now().month
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def get_current_year_range() -> Tuple[str, str]:
|
|
53
|
+
"""获取当前年份的开始和结束日期"""
|
|
54
|
+
current_year = datetime.now().year
|
|
55
|
+
start_date = datetime(current_year, 1, 1).strftime('%Y-%m-%d')
|
|
56
|
+
end_date = datetime(current_year, 12, 31).strftime('%Y-%m-%d')
|
|
57
|
+
return start_date, end_date
|
|
58
|
+
|
|
59
|
+
# ==================== 相对日期获取 ====================
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def get_yesterday(dt: Optional[str] = None) -> str:
|
|
63
|
+
"""
|
|
64
|
+
获取昨天的日期
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
dt: 可选的基础日期,格式为 YYYYMMDD,默认为今天
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
昨天的日期,格式为 YYYY-MM-DD
|
|
71
|
+
"""
|
|
72
|
+
if dt is None:
|
|
73
|
+
dt = datetime.now()
|
|
74
|
+
else:
|
|
75
|
+
dt = datetime.strptime(dt, "%Y%m%d")
|
|
76
|
+
yesterday = dt - timedelta(days=1)
|
|
77
|
+
return yesterday.strftime("%Y-%m-%d")
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def before_yesterday() -> str:
|
|
81
|
+
"""获取前天的日期"""
|
|
82
|
+
return (datetime.now().date() - timedelta(days=2)).strftime("%Y-%m-%d")
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def tomorrow_date() -> str:
|
|
86
|
+
"""获取明天的日期"""
|
|
87
|
+
return (datetime.now().date() + timedelta(days=1)).strftime("%Y-%m-%d")
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def get_last_month() -> int:
|
|
91
|
+
"""获取上个月的月份"""
|
|
92
|
+
today = datetime.today()
|
|
93
|
+
last_month = today.month - 1 if today.month > 1 else 12
|
|
94
|
+
return last_month
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def get_last_two_month() -> int:
|
|
98
|
+
"""获取上上个月的月份"""
|
|
99
|
+
today = datetime.today()
|
|
100
|
+
# 计算上上个月:当前月份减2
|
|
101
|
+
last_two_month = today.month - 2
|
|
102
|
+
# 处理跨年情况
|
|
103
|
+
if last_two_month < 1:
|
|
104
|
+
last_two_month += 12
|
|
105
|
+
return last_two_month
|
|
106
|
+
|
|
107
|
+
# ==================== 日期范围计算 ====================
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def get_past_7_days_range(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> Tuple[str, str,]:
|
|
111
|
+
"""
|
|
112
|
+
获取过去7天的日期范围(包括结束日,共7天)
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
(start_date_str, end_date_str) 日期范围元组
|
|
119
|
+
|
|
120
|
+
Example:
|
|
121
|
+
>>> get_past_7_days_range('2025-07-02')
|
|
122
|
+
('2025-06-25', '2025-07-01')
|
|
123
|
+
"""
|
|
124
|
+
if start_from:
|
|
125
|
+
try:
|
|
126
|
+
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
127
|
+
except ValueError:
|
|
128
|
+
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
129
|
+
else:
|
|
130
|
+
base_date = datetime.today()
|
|
131
|
+
|
|
132
|
+
end_date = base_date - timedelta(days=1) # 默认昨天为结束
|
|
133
|
+
start_date = end_date - timedelta(days=6) # 往前推6天为开始
|
|
134
|
+
|
|
135
|
+
return start_date.strftime(format_str), end_date.strftime(format_str)
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
def get_past_7_days_range_format(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> Tuple[str, str]:
|
|
139
|
+
"""
|
|
140
|
+
获取过去7天的日期范围(包括结束日,共7天),支持自定义格式
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
144
|
+
format_str: 日期格式字符串
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
(start_date_str, end_date_str) 日期范围元组
|
|
148
|
+
"""
|
|
149
|
+
if start_from:
|
|
150
|
+
try:
|
|
151
|
+
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
152
|
+
except ValueError:
|
|
153
|
+
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
154
|
+
else:
|
|
155
|
+
base_date = datetime.today()
|
|
156
|
+
|
|
157
|
+
end_date = base_date - timedelta(days=1) # 默认昨天为结束
|
|
158
|
+
start_date = end_date - timedelta(days=6) # 往前推6天为开始
|
|
159
|
+
|
|
160
|
+
return start_date.strftime(format_str), end_date.strftime(format_str)
|
|
161
|
+
|
|
162
|
+
@staticmethod
|
|
163
|
+
def get_month_first_day(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> str:
|
|
164
|
+
"""
|
|
165
|
+
获取某月的第一天
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
start_from: 参考日期,格式为'YYYY-MM-DD',默认使用今天
|
|
169
|
+
format_str: 返回的日期格式,默认是'%Y-%m-%d'
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
指定格式的某月第一天日期字符串
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
>>> get_month_first_day('2025-07-02')
|
|
176
|
+
'2025-07-01'
|
|
177
|
+
"""
|
|
178
|
+
if start_from:
|
|
179
|
+
try:
|
|
180
|
+
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
181
|
+
except ValueError:
|
|
182
|
+
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
183
|
+
else:
|
|
184
|
+
base_date = datetime.today()
|
|
185
|
+
|
|
186
|
+
# 获取当月第一天
|
|
187
|
+
first_day = base_date.replace(day=1)
|
|
188
|
+
return first_day.strftime(format_str)
|
|
189
|
+
|
|
190
|
+
@staticmethod
|
|
191
|
+
def get_past_nth_day(n: int, start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> str:
|
|
192
|
+
"""
|
|
193
|
+
获取过去第n天的日期
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
n: 获取过去第n天的日期(n=1 表示昨天,n=2 表示前天,以此类推)
|
|
197
|
+
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
'YYYY-MM-DD' 格式的日期
|
|
201
|
+
|
|
202
|
+
Example:
|
|
203
|
+
>>> get_past_nth_day(29, '2025-07-02')
|
|
204
|
+
'2025-06-03'
|
|
205
|
+
"""
|
|
206
|
+
if start_from:
|
|
207
|
+
try:
|
|
208
|
+
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
209
|
+
except ValueError:
|
|
210
|
+
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
211
|
+
else:
|
|
212
|
+
base_date = datetime.today()
|
|
213
|
+
|
|
214
|
+
past_date = base_date - timedelta(days=n)
|
|
215
|
+
return past_date.strftime(format_str)
|
|
216
|
+
|
|
217
|
+
@staticmethod
|
|
218
|
+
def get_past_n_days_list(n: int, start_from: Optional[str] = None) -> List[str]:
|
|
219
|
+
"""
|
|
220
|
+
获取过去n天的日期列表,从最旧到最近的日期
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
n: 获取过去多少天
|
|
224
|
+
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
['YYYY-MM-DD', ..., 'YYYY-MM-DD'],从旧到新排序
|
|
228
|
+
|
|
229
|
+
Example:
|
|
230
|
+
>>> get_past_n_days_list(7, '2025-07-02')
|
|
231
|
+
['2025-07-01', '2025-06-30', '2025-06-29', '2025-06-28', '2025-06-27', '2025-06-26', '2025-06-25']
|
|
232
|
+
"""
|
|
233
|
+
if start_from:
|
|
234
|
+
try:
|
|
235
|
+
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
236
|
+
except ValueError:
|
|
237
|
+
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
238
|
+
else:
|
|
239
|
+
base_date = datetime.today()
|
|
240
|
+
|
|
241
|
+
return [
|
|
242
|
+
(base_date - timedelta(days=i)).strftime('%Y-%m-%d')
|
|
243
|
+
for i in range(1, n + 1)
|
|
244
|
+
]
|
|
245
|
+
|
|
246
|
+
@staticmethod
|
|
247
|
+
def get_past_7_days_list(start_from: Optional[str] = None) -> List[str]:
|
|
248
|
+
"""
|
|
249
|
+
获取过去7天的日期列表(不包含 start_from 当天),共7天
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
start_from: 可选的起始参考日期(格式 'YYYY-MM-DD'),默认以今天为起点
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
['YYYY-MM-DD', ..., 'YYYY-MM-DD'],从旧到新排序
|
|
256
|
+
"""
|
|
257
|
+
if start_from:
|
|
258
|
+
try:
|
|
259
|
+
base_date = datetime.strptime(start_from, '%Y-%m-%d')
|
|
260
|
+
except ValueError:
|
|
261
|
+
raise ValueError("start_from 格式必须是 'YYYY-MM-DD'")
|
|
262
|
+
else:
|
|
263
|
+
base_date = datetime.today()
|
|
264
|
+
|
|
265
|
+
return [
|
|
266
|
+
(base_date - timedelta(days=i)).strftime('%Y-%m-%d')
|
|
267
|
+
for i in range(1, 8)
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
@staticmethod
|
|
271
|
+
def date_range(start_date: str, end_date: str) -> List[str]:
|
|
272
|
+
"""
|
|
273
|
+
生成两个日期之间的日期列表
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
start_date: 开始日期,格式为YYYY-MM-DD
|
|
277
|
+
end_date: 结束日期,格式为YYYY-MM-DD
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
包含两个日期之间所有日期的列表,日期格式为YYYY-MM-DD
|
|
281
|
+
|
|
282
|
+
Raises:
|
|
283
|
+
ValueError: 当开始日期大于结束日期时
|
|
284
|
+
"""
|
|
285
|
+
start = datetime.strptime(start_date, "%Y-%m-%d")
|
|
286
|
+
end = datetime.strptime(end_date, "%Y-%m-%d")
|
|
287
|
+
|
|
288
|
+
if start > end:
|
|
289
|
+
raise ValueError("开始日期不能大于结束日期")
|
|
290
|
+
|
|
291
|
+
date_list = []
|
|
292
|
+
current_date = start
|
|
293
|
+
while current_date <= end:
|
|
294
|
+
date_list.append(current_date.strftime("%Y-%m-%d"))
|
|
295
|
+
current_date += timedelta(days=1)
|
|
296
|
+
|
|
297
|
+
return date_list
|
|
298
|
+
|
|
299
|
+
@staticmethod
|
|
300
|
+
def get_dates_from_first_of_month_to_yesterday() -> List[str]:
|
|
301
|
+
"""获取从本月第一天到昨天的日期列表
|
|
302
|
+
如果今天是本月第一天,则返回上个月的日期列表
|
|
303
|
+
"""
|
|
304
|
+
today = datetime.today()
|
|
305
|
+
yesterday = today - timedelta(days=1)
|
|
306
|
+
|
|
307
|
+
# 如果今天是本月第一天,取上个月
|
|
308
|
+
if today.day == 1:
|
|
309
|
+
# 找到上个月最后一天
|
|
310
|
+
last_month_last_day = today - timedelta(days=1)
|
|
311
|
+
# 上个月第一天
|
|
312
|
+
first_day_of_last_month = last_month_last_day.replace(day=1)
|
|
313
|
+
start_date = first_day_of_last_month
|
|
314
|
+
end_date = last_month_last_day
|
|
315
|
+
else:
|
|
316
|
+
start_date = today.replace(day=1)
|
|
317
|
+
end_date = yesterday
|
|
318
|
+
|
|
319
|
+
date_list = []
|
|
320
|
+
current_date = start_date
|
|
321
|
+
while current_date <= end_date:
|
|
322
|
+
date_list.append(current_date.strftime('%Y-%m-%d'))
|
|
323
|
+
current_date += timedelta(days=1)
|
|
324
|
+
|
|
325
|
+
return date_list
|
|
326
|
+
|
|
327
|
+
# ==================== 月份相关 ====================
|
|
328
|
+
|
|
329
|
+
@staticmethod
|
|
330
|
+
def get_last_month_range() -> Tuple[str, str]:
|
|
331
|
+
"""获取上个月的第一天和最后一天"""
|
|
332
|
+
today = datetime.today()
|
|
333
|
+
last_month = today.month - 1 if today.month > 1 else 12
|
|
334
|
+
year = today.year if today.month > 1 else today.year - 1
|
|
335
|
+
|
|
336
|
+
first_day = datetime(year, last_month, 1)
|
|
337
|
+
last_day = datetime(year, last_month, calendar.monthrange(year, last_month)[1])
|
|
338
|
+
|
|
339
|
+
return first_day.strftime("%Y-%m-%d"), last_day.strftime("%Y-%m-%d")
|
|
340
|
+
|
|
341
|
+
@staticmethod
|
|
342
|
+
def get_last_two_month_range() -> Tuple[str, str]:
|
|
343
|
+
"""获取上上个月的第一天和最后一天"""
|
|
344
|
+
today = datetime.today()
|
|
345
|
+
# 计算上上个月
|
|
346
|
+
last_two_month = today.month - 2
|
|
347
|
+
year = today.year
|
|
348
|
+
|
|
349
|
+
# 处理跨年情况
|
|
350
|
+
if last_two_month < 1:
|
|
351
|
+
last_two_month += 12
|
|
352
|
+
year -= 1
|
|
353
|
+
|
|
354
|
+
first_day = datetime(year, last_two_month, 1)
|
|
355
|
+
last_day = datetime(year, last_two_month, calendar.monthrange(year, last_two_month)[1])
|
|
356
|
+
|
|
357
|
+
return first_day.strftime("%Y-%m-%d"), last_day.strftime("%Y-%m-%d")
|
|
358
|
+
|
|
359
|
+
@staticmethod
|
|
360
|
+
def get_last_month_range_time_str() -> Tuple[str, str]:
|
|
361
|
+
"""获取上个月第一天和最后一天的时间字符串"""
|
|
362
|
+
today = datetime.today()
|
|
363
|
+
last_month = today.month - 1 if today.month > 1 else 12
|
|
364
|
+
year = today.year if today.month > 1 else today.year - 1
|
|
365
|
+
|
|
366
|
+
first_day = datetime(year, last_month, 1, 0, 0, 0)
|
|
367
|
+
last_day = datetime(year, last_month, calendar.monthrange(year, last_month)[1], 23, 59, 59)
|
|
368
|
+
|
|
369
|
+
start_time_str = first_day.strftime("%Y-%m-%d %H:%M:%S")
|
|
370
|
+
end_time_str = last_day.strftime("%Y-%m-%d %H:%M:%S")
|
|
371
|
+
|
|
372
|
+
return start_time_str, end_time_str
|
|
373
|
+
|
|
374
|
+
@staticmethod
|
|
375
|
+
def get_last_month_range_time() -> Tuple[int, int]:
|
|
376
|
+
"""获取上个月第一天和最后一天的毫秒级时间戳"""
|
|
377
|
+
today = datetime.today()
|
|
378
|
+
last_month = today.month - 1 if today.month > 1 else 12
|
|
379
|
+
year = today.year if today.month > 1 else today.year - 1
|
|
380
|
+
|
|
381
|
+
first_day = datetime(year, last_month, 1, 0, 0, 0)
|
|
382
|
+
last_day = datetime(year, last_month, calendar.monthrange(year, last_month)[1], 23, 59, 59, 0)
|
|
383
|
+
|
|
384
|
+
start_timestamp = int(first_day.timestamp() * 1000)
|
|
385
|
+
end_timestamp = int(last_day.timestamp() * 1000)
|
|
386
|
+
|
|
387
|
+
return start_timestamp, end_timestamp
|
|
388
|
+
|
|
389
|
+
@staticmethod
|
|
390
|
+
def get_year_range_time(year=2024):
|
|
391
|
+
"""获取某一整年的第一天和最后一天的毫秒级时间戳"""
|
|
392
|
+
first_day = datetime(year, 1, 1, 0, 0, 0)
|
|
393
|
+
last_day = datetime(year, 12, 31, 0, 0, 0, 0)
|
|
394
|
+
|
|
395
|
+
start_timestamp = int(first_day.timestamp() * 1000)
|
|
396
|
+
end_timestamp = int(last_day.timestamp() * 1000)
|
|
397
|
+
|
|
398
|
+
return start_timestamp, end_timestamp
|
|
399
|
+
|
|
400
|
+
@staticmethod
|
|
401
|
+
def is_in_month(time_str: str, month: int, fmt: str = "%Y-%m-%d") -> bool:
|
|
402
|
+
"""
|
|
403
|
+
判断时间字符串是否在指定月份
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
time_str: 时间字符串
|
|
407
|
+
month: 月份(1-12)
|
|
408
|
+
fmt: 时间格式
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
如果时间在指定月份返回True,否则返回False
|
|
412
|
+
"""
|
|
413
|
+
try:
|
|
414
|
+
dt = datetime.strptime(time_str, fmt)
|
|
415
|
+
return dt.month == month
|
|
416
|
+
except ValueError:
|
|
417
|
+
return False
|
|
418
|
+
|
|
419
|
+
# ==================== 星期相关 ====================
|
|
420
|
+
|
|
421
|
+
@staticmethod
|
|
422
|
+
def get_week_num() -> int:
|
|
423
|
+
"""获取当前是第几周"""
|
|
424
|
+
today = date.today()
|
|
425
|
+
week_num = today.isocalendar()[1] # 返回 (year, week_num, weekday)
|
|
426
|
+
return week_num
|
|
427
|
+
|
|
428
|
+
@staticmethod
|
|
429
|
+
def get_chinese_weekday(date_str: str) -> str:
|
|
430
|
+
"""
|
|
431
|
+
根据输入的日期字符串返回中文星期几
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
date_str: 格式为'YYYY-MM-DD'的日期字符串
|
|
435
|
+
|
|
436
|
+
Returns:
|
|
437
|
+
中文星期几,如'星期一'
|
|
438
|
+
|
|
439
|
+
Example:
|
|
440
|
+
>>> get_chinese_weekday('2025-04-15')
|
|
441
|
+
'星期二'
|
|
442
|
+
"""
|
|
443
|
+
try:
|
|
444
|
+
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
|
|
445
|
+
weekday_num = date_obj.weekday()
|
|
446
|
+
weekday_cn = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
|
|
447
|
+
return weekday_cn[weekday_num]
|
|
448
|
+
except ValueError as e:
|
|
449
|
+
raise ValueError(f"日期格式错误,请输入'YYYY-MM-DD'格式的日期字符串。错误详情: {str(e)}")
|
|
450
|
+
|
|
451
|
+
@staticmethod
|
|
452
|
+
def get_weekday_name(date_str: str) -> str:
|
|
453
|
+
"""获取中文星期名称(简短格式)"""
|
|
454
|
+
weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
|
|
455
|
+
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
|
|
456
|
+
return weekdays[date_obj.weekday()]
|
|
457
|
+
|
|
458
|
+
# ==================== 时间段相关 ====================
|
|
459
|
+
|
|
460
|
+
@staticmethod
|
|
461
|
+
def get_period() -> str:
|
|
462
|
+
"""获取当前时间段(上午/下午/晚上)"""
|
|
463
|
+
hour = datetime.now().hour
|
|
464
|
+
if 5 <= hour < 12:
|
|
465
|
+
return "上午"
|
|
466
|
+
elif 12 <= hour < 18:
|
|
467
|
+
return "下午"
|
|
468
|
+
else:
|
|
469
|
+
return "晚上"
|
|
470
|
+
|
|
471
|
+
@staticmethod
|
|
472
|
+
def get_period2() -> str:
|
|
473
|
+
"""获取当前时间段(AM/PM)"""
|
|
474
|
+
now = datetime.now()
|
|
475
|
+
period = now.strftime("%p") # 返回AM或者PM
|
|
476
|
+
return period
|
|
477
|
+
|
|
478
|
+
# ==================== 时间戳转换 ====================
|
|
479
|
+
|
|
480
|
+
@staticmethod
|
|
481
|
+
def convert_timestamp_to_str(timestamp_ms: Optional[int]) -> str:
|
|
482
|
+
"""
|
|
483
|
+
将毫秒时间戳转换为字符串
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
timestamp_ms: 毫秒时间戳
|
|
487
|
+
|
|
488
|
+
Returns:
|
|
489
|
+
格式化的时间字符串,如果输入为None则返回'-'
|
|
490
|
+
"""
|
|
491
|
+
if timestamp_ms is None:
|
|
492
|
+
return '-'
|
|
493
|
+
timestamp_s = int(timestamp_ms) / 1000
|
|
494
|
+
dt = datetime.fromtimestamp(timestamp_s)
|
|
495
|
+
return dt.strftime('%Y-%m-%d %H:%M:%S')
|
|
496
|
+
|
|
497
|
+
@staticmethod
|
|
498
|
+
def convert_timestamp_to_date(timestamp_ms: Union[int, float]) -> str:
|
|
499
|
+
"""
|
|
500
|
+
将毫秒时间戳转换为日期字符串
|
|
501
|
+
|
|
502
|
+
Args:
|
|
503
|
+
timestamp_ms: 毫秒时间戳
|
|
504
|
+
|
|
505
|
+
Returns:
|
|
506
|
+
YYYY-MM-DD 格式的日期字符串
|
|
507
|
+
"""
|
|
508
|
+
timestamp_s = timestamp_ms / 1000
|
|
509
|
+
dt = datetime.fromtimestamp(timestamp_s)
|
|
510
|
+
return dt.strftime('%Y-%m-%d')
|
|
511
|
+
|
|
512
|
+
@staticmethod
|
|
513
|
+
def get_start_timestamps(date_str: str) -> int:
|
|
514
|
+
"""
|
|
515
|
+
获取指定日期的开始毫秒时间戳(00:00:00.000)
|
|
516
|
+
|
|
517
|
+
Args:
|
|
518
|
+
date_str: 格式为"YYYY-MM-DD"的日期字符串
|
|
519
|
+
|
|
520
|
+
Returns:
|
|
521
|
+
开始毫秒时间戳
|
|
522
|
+
"""
|
|
523
|
+
start_of_day = datetime.strptime(date_str, "%Y-%m-%d")
|
|
524
|
+
return int(start_of_day.timestamp() * 1000)
|
|
525
|
+
|
|
526
|
+
@staticmethod
|
|
527
|
+
def get_end_timestamps(date_str: str) -> int:
|
|
528
|
+
"""
|
|
529
|
+
获取指定日期的结束毫秒时间戳(23:59:59.999)
|
|
530
|
+
|
|
531
|
+
Args:
|
|
532
|
+
date_str: 格式为"YYYY-MM-DD"的日期字符串
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
结束毫秒时间戳
|
|
536
|
+
"""
|
|
537
|
+
start_of_day = datetime.strptime(date_str, "%Y-%m-%d")
|
|
538
|
+
end_of_day = start_of_day + timedelta(days=1) - timedelta(milliseconds=1)
|
|
539
|
+
return int(end_of_day.timestamp() * 1000)
|
|
540
|
+
|
|
541
|
+
# ==================== 日期格式转换 ====================
|
|
542
|
+
|
|
543
|
+
@staticmethod
|
|
544
|
+
def convert_datetime_to_date(datetime_str: str) -> str:
|
|
545
|
+
"""
|
|
546
|
+
将格式为 'YYYY-MM-DD HH:MM:SS' 的时间字符串转换为 'YYYY-MM-DD' 格式的日期字符串
|
|
547
|
+
|
|
548
|
+
Args:
|
|
549
|
+
datetime_str: 时间字符串,格式为 'YYYY-MM-DD HH:MM:SS'
|
|
550
|
+
|
|
551
|
+
Returns:
|
|
552
|
+
日期字符串,格式为 'YYYY-MM-DD'
|
|
553
|
+
|
|
554
|
+
Example:
|
|
555
|
+
>>> convert_datetime_to_date("2025-06-27 09:49:16")
|
|
556
|
+
'2025-06-27'
|
|
557
|
+
"""
|
|
558
|
+
try:
|
|
559
|
+
dt_obj = datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S')
|
|
560
|
+
return dt_obj.strftime('%Y-%m-%d')
|
|
561
|
+
except ValueError:
|
|
562
|
+
print(f"输入的时间字符串格式错误,需要 'YYYY-MM-DD HH:MM:SS' 格式,但得到: {datetime_str}")
|
|
563
|
+
return datetime_str
|
|
564
|
+
|
|
565
|
+
@staticmethod
|
|
566
|
+
def date_trans(d_t: str) -> str:
|
|
567
|
+
"""
|
|
568
|
+
无斜杠日期转成有斜杠日期
|
|
569
|
+
|
|
570
|
+
Args:
|
|
571
|
+
d_t: 格式为 YYYY-MM-DD 的日期字符串
|
|
572
|
+
|
|
573
|
+
Returns:
|
|
574
|
+
格式为 YYYYMMDD 的日期字符串
|
|
575
|
+
"""
|
|
576
|
+
return datetime.strptime(d_t, "%Y-%m-%d").strftime("%Y%m%d")
|
|
577
|
+
|
|
578
|
+
@staticmethod
|
|
579
|
+
def format_date_cross_platform(date_str: str) -> str:
|
|
580
|
+
"""
|
|
581
|
+
跨平台格式化日期
|
|
582
|
+
|
|
583
|
+
Args:
|
|
584
|
+
date_str: 格式为 YYYY-MM-DD 的日期字符串
|
|
585
|
+
|
|
586
|
+
Returns:
|
|
587
|
+
格式化后的日期字符串
|
|
588
|
+
"""
|
|
589
|
+
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
|
|
590
|
+
import platform
|
|
591
|
+
if platform.system() == "Windows":
|
|
592
|
+
return date_obj.strftime("%Y/%#m/%#d")
|
|
593
|
+
else: # Linux, macOS等
|
|
594
|
+
return date_obj.strftime("%Y/%-m/%-d")
|
|
595
|
+
|
|
596
|
+
# ==================== 日期比较和判断 ====================
|
|
597
|
+
|
|
598
|
+
@staticmethod
|
|
599
|
+
def is_date_greater_or_equal(date_str: str) -> bool:
|
|
600
|
+
"""
|
|
601
|
+
比较指定日期是否大于或等于今天的日期
|
|
602
|
+
|
|
603
|
+
Args:
|
|
604
|
+
date_str: 格式为YYYY-MM-DD的日期字符串
|
|
605
|
+
|
|
606
|
+
Returns:
|
|
607
|
+
如果指定日期大于或等于今天返回True,否则返回False
|
|
608
|
+
"""
|
|
609
|
+
try:
|
|
610
|
+
year, month, day = map(int, date_str.split('-'))
|
|
611
|
+
input_date = date(year, month, day)
|
|
612
|
+
today = date.today()
|
|
613
|
+
return input_date >= today
|
|
614
|
+
except ValueError:
|
|
615
|
+
print("日期格式不正确,请使用YYYY-MM-DD格式")
|
|
616
|
+
return False
|
|
617
|
+
|
|
618
|
+
@staticmethod
|
|
619
|
+
def is_yesterday(create_time_str: str, dt: Optional[str] = None) -> bool:
|
|
620
|
+
"""
|
|
621
|
+
判断给定的时间字符串是否是昨天
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
create_time_str: 创建时间字符串,格式为 "%Y-%m-%d %H:%M:%S"
|
|
625
|
+
dt: 日期字符串,格式为 "%Y-%m-%d" 表示某一天,默认为今天
|
|
626
|
+
|
|
627
|
+
Returns:
|
|
628
|
+
如果 create_time_str 是昨天的日期,返回 True,否则返回 False
|
|
629
|
+
"""
|
|
630
|
+
try:
|
|
631
|
+
create_time = datetime.strptime(create_time_str, "%Y-%m-%d %H:%M:%S")
|
|
632
|
+
if dt is None:
|
|
633
|
+
dt = datetime.now()
|
|
634
|
+
else:
|
|
635
|
+
dt = datetime.strptime(dt, "%Y%m%d")
|
|
636
|
+
except ValueError:
|
|
637
|
+
raise ValueError("时间字符串格式不正确,请使用正确的格式:'%Y-%m-%d %H:%M:%S' 和 '%Y-%m-%d'")
|
|
638
|
+
|
|
639
|
+
yesterday = dt - timedelta(days=1)
|
|
640
|
+
return create_time.date() == yesterday.date()
|
|
641
|
+
|
|
642
|
+
@staticmethod
|
|
643
|
+
def is_yesterday_date(date_str: str, format="%Y-%m-%d") -> bool:
|
|
644
|
+
"""
|
|
645
|
+
判断给定的日期字符串是否是昨天
|
|
646
|
+
|
|
647
|
+
Args:
|
|
648
|
+
date_str: 日期字符串,格式为 "%Y-%m-%d"
|
|
649
|
+
|
|
650
|
+
Returns:
|
|
651
|
+
如果 date_str 是昨天的日期,返回 True,否则返回 False
|
|
652
|
+
"""
|
|
653
|
+
try:
|
|
654
|
+
create_time = datetime.strptime(date_str, format)
|
|
655
|
+
dt = datetime.now()
|
|
656
|
+
except ValueError:
|
|
657
|
+
raise ValueError("时间字符串格式不正确,请使用正确的格式:'%Y-%m-%d'")
|
|
658
|
+
|
|
659
|
+
yesterday = dt - timedelta(days=1)
|
|
660
|
+
return create_time.date() == yesterday.date()
|
|
661
|
+
|
|
662
|
+
# ==================== 文件时间相关 ====================
|
|
663
|
+
|
|
664
|
+
@staticmethod
|
|
665
|
+
def get_file_mtime(file_path: str, to_str: bool = True, tz_offset: int = 8) -> Union[str, datetime]:
|
|
666
|
+
"""
|
|
667
|
+
获取文件的修改时间
|
|
668
|
+
|
|
669
|
+
Args:
|
|
670
|
+
file_path: 文件路径
|
|
671
|
+
to_str: 是否返回格式化字符串(默认 True)
|
|
672
|
+
tz_offset: 时区偏移(默认东八区 +8)
|
|
673
|
+
|
|
674
|
+
Returns:
|
|
675
|
+
格式化时间字符串或 datetime 对象
|
|
676
|
+
|
|
677
|
+
Raises:
|
|
678
|
+
FileNotFoundError: 当文件不存在时
|
|
679
|
+
"""
|
|
680
|
+
if not os.path.exists(file_path):
|
|
681
|
+
raise FileNotFoundError(f"文件不存在: {file_path}")
|
|
682
|
+
|
|
683
|
+
mtime = os.path.getmtime(file_path)
|
|
684
|
+
tz = timezone(timedelta(hours=tz_offset))
|
|
685
|
+
mtime_dt = datetime.fromtimestamp(mtime, tz=tz)
|
|
686
|
+
|
|
687
|
+
return mtime_dt.strftime('%Y-%m-%d %H:%M:%S') if to_str else mtime_dt
|
|
688
|
+
|
|
689
|
+
# ==================== 便捷函数 ====================
|
|
690
|
+
# 为了保持向后兼容,提供一些便捷函数
|
|
691
|
+
|
|
692
|
+
def get_current_date() -> str:
|
|
693
|
+
"""获取当前日期,格式为 YYYYMMDD"""
|
|
694
|
+
return TimeUtils.get_current_date()
|
|
695
|
+
|
|
696
|
+
def get_current_datetime() -> str:
|
|
697
|
+
"""获取当前日期时间,格式为 YYYYMMDDHHMMSS"""
|
|
698
|
+
return TimeUtils.get_current_datetime()
|
|
699
|
+
|
|
700
|
+
def current_datetime() -> str:
|
|
701
|
+
"""获取当前日期时间,格式为 YYYY-MM-DD HH:MM:SS"""
|
|
702
|
+
return TimeUtils.current_datetime()
|
|
703
|
+
|
|
704
|
+
def today_date() -> str:
|
|
705
|
+
"""获取今天的日期,格式为 YYYY-MM-DD"""
|
|
706
|
+
return TimeUtils.today_date()
|
|
707
|
+
|
|
708
|
+
def today_date_hour() -> str:
|
|
709
|
+
"""获取今天的日期和小时,格式为 YYYY-MM-DD_HH"""
|
|
710
|
+
return TimeUtils.today_date_hour()
|
|
711
|
+
|
|
712
|
+
def get_yesterday(dt: Optional[str] = None) -> str:
|
|
713
|
+
"""获取昨天的日期"""
|
|
714
|
+
return TimeUtils.get_yesterday(dt)
|
|
715
|
+
|
|
716
|
+
def tomorrow_date() -> str:
|
|
717
|
+
"""获取明天的日期"""
|
|
718
|
+
return TimeUtils.tomorrow_date()
|
|
719
|
+
|
|
720
|
+
def before_yesterday() -> str:
|
|
721
|
+
"""获取前天的日期"""
|
|
722
|
+
return TimeUtils.before_yesterday()
|
|
723
|
+
|
|
724
|
+
def get_current_year() -> int:
|
|
725
|
+
"""获取当前年份"""
|
|
726
|
+
return TimeUtils.get_current_year()
|
|
727
|
+
|
|
728
|
+
def get_current_month() -> int:
|
|
729
|
+
"""获取当前月份"""
|
|
730
|
+
return TimeUtils.get_current_month()
|
|
731
|
+
|
|
732
|
+
def get_last_month() -> int:
|
|
733
|
+
"""获取上个月的月份"""
|
|
734
|
+
return TimeUtils.get_last_month()
|
|
735
|
+
|
|
736
|
+
def get_week_num() -> int:
|
|
737
|
+
"""获取当前是第几周"""
|
|
738
|
+
return TimeUtils.get_week_num()
|
|
739
|
+
|
|
740
|
+
def get_period() -> str:
|
|
741
|
+
"""获取当前时间段(上午/下午/晚上)"""
|
|
742
|
+
return TimeUtils.get_period()
|
|
743
|
+
|
|
744
|
+
def get_period2() -> str:
|
|
745
|
+
"""获取当前时间段(AM/PM)"""
|
|
746
|
+
return TimeUtils.get_period2()
|
|
747
|
+
|
|
748
|
+
def get_chinese_weekday(date_str: str) -> str:
|
|
749
|
+
"""根据输入的日期字符串返回中文星期几"""
|
|
750
|
+
return TimeUtils.get_chinese_weekday(date_str)
|
|
751
|
+
|
|
752
|
+
def get_weekday_name(date_str: str) -> str:
|
|
753
|
+
"""获取中文星期名称(简短格式)"""
|
|
754
|
+
return TimeUtils.get_weekday_name(date_str)
|
|
755
|
+
|
|
756
|
+
def is_in_month(time_str: str, month: int, fmt: str = "%Y-%m-%d") -> bool:
|
|
757
|
+
"""判断时间字符串是否在指定月份"""
|
|
758
|
+
return TimeUtils.is_in_month(time_str, month, fmt)
|
|
759
|
+
|
|
760
|
+
def date_trans(d_t: str) -> str:
|
|
761
|
+
"""无斜杠日期转成有斜杠日期"""
|
|
762
|
+
return TimeUtils.date_trans(d_t)
|
|
763
|
+
|
|
764
|
+
def is_date_greater_or_equal(date_str: str) -> bool:
|
|
765
|
+
"""比较指定日期是否大于或等于今天的日期"""
|
|
766
|
+
return TimeUtils.is_date_greater_or_equal(date_str)
|
|
767
|
+
|
|
768
|
+
def is_yesterday(create_time_str: str, dt: Optional[str] = None) -> bool:
|
|
769
|
+
"""判断给定的时间字符串是否是昨天"""
|
|
770
|
+
return TimeUtils.is_yesterday(create_time_str, dt)
|
|
771
|
+
|
|
772
|
+
def is_yesterday_date(date_str: str) -> bool:
|
|
773
|
+
"""判断给定的日期字符串是否是昨天"""
|
|
774
|
+
return TimeUtils.is_yesterday_date(date_str)
|
|
775
|
+
|
|
776
|
+
def get_file_mtime(file_path: str, to_str: bool = True, tz_offset: int = 8) -> Union[str, datetime]:
|
|
777
|
+
"""获取文件的修改时间"""
|
|
778
|
+
return TimeUtils.get_file_mtime(file_path, to_str, tz_offset)
|
|
779
|
+
|
|
780
|
+
def convert_timestamp_to_str(timestamp_ms: Optional[int]) -> str:
|
|
781
|
+
"""将毫秒时间戳转换为字符串"""
|
|
782
|
+
return TimeUtils.convert_timestamp_to_str(timestamp_ms)
|
|
783
|
+
|
|
784
|
+
def convert_timestamp_to_date(timestamp_ms: Union[int, float]) -> str:
|
|
785
|
+
"""将毫秒时间戳转换为日期字符串"""
|
|
786
|
+
return TimeUtils.convert_timestamp_to_date(timestamp_ms)
|
|
787
|
+
|
|
788
|
+
def convert_datetime_to_date(datetime_str: str) -> str:
|
|
789
|
+
"""将格式为 'YYYY-MM-DD HH:MM:SS' 的时间字符串转换为 'YYYY-MM-DD' 格式的日期字符串"""
|
|
790
|
+
return TimeUtils.convert_datetime_to_date(datetime_str)
|
|
791
|
+
|
|
792
|
+
def get_current_year_range() -> Tuple[str, str]:
|
|
793
|
+
"""获取当前年份的开始和结束日期"""
|
|
794
|
+
return TimeUtils.get_current_year_range()
|
|
795
|
+
|
|
796
|
+
def get_start_timestamps(date_str: str) -> int:
|
|
797
|
+
"""获取指定日期的开始毫秒时间戳(00:00:00.000)"""
|
|
798
|
+
return TimeUtils.get_start_timestamps(date_str)
|
|
799
|
+
|
|
800
|
+
def get_end_timestamps(date_str: str) -> int:
|
|
801
|
+
"""获取指定日期的结束毫秒时间戳(23:59:59.999)"""
|
|
802
|
+
return TimeUtils.get_end_timestamps(date_str)
|
|
803
|
+
|
|
804
|
+
def format_date_cross_platform(date_str: str) -> str:
|
|
805
|
+
"""跨平台格式化日期"""
|
|
806
|
+
return TimeUtils.format_date_cross_platform(date_str)
|
|
807
|
+
|
|
808
|
+
def get_past_7_days_range(start_from: Optional[str] = None) -> Tuple[str, str]:
|
|
809
|
+
"""获取过去7天的日期范围(包括结束日,共7天)"""
|
|
810
|
+
return TimeUtils.get_past_7_days_range(start_from)
|
|
811
|
+
|
|
812
|
+
def get_past_7_days_range_format(start_from: Optional[str] = None, format_str: str = '%Y-%m-%d') -> Tuple[str, str]:
|
|
813
|
+
"""获取过去7天的日期范围(包括结束日,共7天),支持自定义格式"""
|
|
814
|
+
return TimeUtils.get_past_7_days_range_format(start_from, format_str)
|
|
815
|
+
|
|
816
|
+
def get_past_nth_day(n: int, start_from: Optional[str] = None) -> str:
|
|
817
|
+
"""获取过去第n天的日期"""
|
|
818
|
+
return TimeUtils.get_past_nth_day(n, start_from)
|
|
819
|
+
|
|
820
|
+
def get_past_n_days_list(n: int, start_from: Optional[str] = None) -> List[str]:
|
|
821
|
+
"""获取过去n天的日期列表,从最旧到最近的日期"""
|
|
822
|
+
return TimeUtils.get_past_n_days_list(n, start_from)
|
|
823
|
+
|
|
824
|
+
def get_past_7_days_list(start_from: Optional[str] = None) -> List[str]:
|
|
825
|
+
"""获取过去7天的日期列表(不包含 start_from 当天),共7天"""
|
|
826
|
+
return TimeUtils.get_past_7_days_list(start_from)
|
|
827
|
+
|
|
828
|
+
def date_range(start_date: str, end_date: str) -> List[str]:
|
|
829
|
+
"""生成两个日期之间的日期列表"""
|
|
830
|
+
return TimeUtils.date_range(start_date, end_date)
|
|
831
|
+
|
|
832
|
+
def get_dates_from_first_of_month_to_yesterday() -> List[str]:
|
|
833
|
+
"""获取从本月第一天到昨天的日期列表"""
|
|
834
|
+
return TimeUtils.get_dates_from_first_of_month_to_yesterday()
|
|
835
|
+
|
|
836
|
+
def get_last_month_range() -> Tuple[str, str]:
|
|
837
|
+
"""获取上个月的第一天和最后一天"""
|
|
838
|
+
return TimeUtils.get_last_month_range()
|
|
839
|
+
|
|
840
|
+
def get_last_month_range_time_str() -> Tuple[str, str]:
|
|
841
|
+
"""获取上个月第一天和最后一天的时间字符串"""
|
|
842
|
+
return TimeUtils.get_last_month_range_time_str()
|
|
843
|
+
|
|
844
|
+
def get_last_month_range_time() -> Tuple[int, int]:
|
|
845
|
+
"""获取上个月第一天和最后一天的毫秒级时间戳"""
|
|
846
|
+
return TimeUtils.get_last_month_range_time()
|
|
847
|
+
|
|
848
|
+
# 为了向后兼容,保留一些旧函数名
|
|
849
|
+
def get_past_7_days_range_old() -> Tuple[str, str]:
|
|
850
|
+
"""获取过去7天的日期范围(旧版本)"""
|
|
851
|
+
end_date = datetime.today() - timedelta(days=1) # 昨天为结束日期
|
|
852
|
+
start_date = end_date - timedelta(days=6) # 往前推6天为开始日期
|
|
853
|
+
return start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d')
|
|
854
|
+
|
|
855
|
+
def get_past_7_days_list_old() -> List[str]:
|
|
856
|
+
"""获取过去7天的日期列表(旧版本)"""
|
|
857
|
+
today = datetime.today()
|
|
858
|
+
return [
|
|
859
|
+
(today - timedelta(days=i)).strftime('%Y-%m-%d')
|
|
860
|
+
for i in range(1, 8)
|
|
861
|
+
]
|
|
862
|
+
|
|
863
|
+
if __name__ == "__main__":
|
|
864
|
+
# 测试示例
|
|
865
|
+
print(f"当前日期: {today_date()}")
|
|
866
|
+
print(f"昨天: {get_yesterday()}")
|
|
867
|
+
print(f"明天: {tomorrow_date()}")
|
|
868
|
+
print(f"当前年份: {get_current_year()}")
|
|
869
|
+
print(f"当前月份: {get_current_month()}")
|
|
870
|
+
print(f"当前周数: {get_week_num()}")
|
|
871
|
+
print(f"当前时间段: {get_period()}")
|
|
872
|
+
print(f"中文星期: {get_chinese_weekday(today_date())}")
|
|
873
|
+
|
|
874
|
+
# 测试日期范围
|
|
875
|
+
start, end = get_past_7_days_range()
|
|
876
|
+
print(f"过去7天范围: {start} 到 {end}")
|
|
877
|
+
|
|
878
|
+
# 测试时间戳转换
|
|
879
|
+
current_ts = int(datetime.now().timestamp() * 1000)
|
|
880
|
+
print(f"当前时间戳: {current_ts}")
|
|
881
|
+
print(f"时间戳转字符串: {convert_timestamp_to_str(current_ts)}")
|
|
882
|
+
print(f"时间戳转日期: {convert_timestamp_to_date(current_ts)}")
|