terryutils 1.0.5__tar.gz → 1.0.6__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: terryutils
3
- Version: 1.0.5
3
+ Version: 1.0.6
4
4
  Summary: My personal python toolkit
5
5
  Author-email: Terry Zhu <596480606@qq.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "terryutils" # pip install 用这个
7
- version = "1.0.5"
7
+ version = "1.0.6"
8
8
  description = "My personal python toolkit"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -0,0 +1,3 @@
1
+ from .mysql_util import MysqlUtil
2
+ from .log import setup_logger
3
+ from .date_util import DateUtils
@@ -0,0 +1,228 @@
1
+ from datetime import datetime, date, timedelta
2
+ import calendar
3
+ import re
4
+
5
+ class DateUtils:
6
+ """企业级 Python 日期工具类"""
7
+
8
+ COMMON_FORMATS = [
9
+ "%Y-%m-%d %H:%M:%S",
10
+ "%Y-%m-%d %H:%M",
11
+ "%Y-%m-%d",
12
+ "%d/%m/%Y",
13
+ "%d-%m-%Y",
14
+ "%Y/%m/%d",
15
+ ]
16
+
17
+ # -------------------- 基础获取 --------------------
18
+ @staticmethod
19
+ def now(fmt="%Y-%m-%d %H:%M:%S"):
20
+ """当前时间"""
21
+ return datetime.now().strftime(fmt)
22
+
23
+ @staticmethod
24
+ def today(fmt="%Y-%m-%d"):
25
+ """今天"""
26
+ return date.today().strftime(fmt)
27
+
28
+ @staticmethod
29
+ def datetime_now():
30
+ """返回datetime对象"""
31
+ return datetime.now()
32
+
33
+ @staticmethod
34
+ def date_today():
35
+ """返回date对象"""
36
+ return date.today()
37
+
38
+ # -------------------- 字符串与datetime互转 --------------------
39
+ @staticmethod
40
+ def parse(date_str, fmt=None):
41
+ """尝试多种格式解析字符串"""
42
+ if isinstance(date_str, (int, float)):
43
+ return datetime.fromtimestamp(date_str)
44
+ if isinstance(date_str, datetime):
45
+ return date_str
46
+ if fmt:
47
+ return datetime.strptime(date_str, fmt)
48
+ for f in DateUtils.COMMON_FORMATS:
49
+ try:
50
+ return datetime.strptime(date_str, f)
51
+ except:
52
+ continue
53
+ raise ValueError(f"无法解析日期: {date_str}")
54
+
55
+ @staticmethod
56
+ def format(dt, fmt="%Y-%m-%d %H:%M:%S"):
57
+ if isinstance(dt, str):
58
+ dt = DateUtils.parse(dt)
59
+ return dt.strftime(fmt)
60
+
61
+ @staticmethod
62
+ def to_timestamp(dt):
63
+ dt = DateUtils.parse(dt) if isinstance(dt, (str, int, float)) else dt
64
+ return int(dt.timestamp())
65
+
66
+ @staticmethod
67
+ def from_timestamp(ts):
68
+ return datetime.fromtimestamp(ts)
69
+
70
+ # -------------------- 日期加减 --------------------
71
+ @staticmethod
72
+ def add_days(dt, days):
73
+ dt = DateUtils.parse(dt)
74
+ return dt + timedelta(days=days)
75
+
76
+ @staticmethod
77
+ def add_seconds(dt, seconds, ft):
78
+ dt = DateUtils.parse(dt, ft)
79
+ return dt + timedelta(seconds=seconds)
80
+
81
+ @staticmethod
82
+ def add_months(dt, months):
83
+ dt = DateUtils.parse(dt)
84
+ month = dt.month - 1 + months
85
+ year = dt.year + month // 12
86
+ month = month % 12 + 1
87
+ day = min(dt.day, calendar.monthrange(year, month)[1])
88
+ return dt.replace(year=year, month=month, day=day)
89
+
90
+ @staticmethod
91
+ def add_years(dt, years):
92
+ dt = DateUtils.parse(dt)
93
+ try:
94
+ return dt.replace(year=dt.year + years)
95
+ except ValueError:
96
+ # 闰年2月29日处理
97
+ return dt.replace(month=2, day=28, year=dt.year + years)
98
+
99
+ # -------------------- 周/月/季度起止 --------------------
100
+ @staticmethod
101
+ def start_of_day(dt=None):
102
+ dt = DateUtils.parse(dt) if dt else datetime.now()
103
+ return datetime(dt.year, dt.month, dt.day, 0, 0, 0)
104
+
105
+ @staticmethod
106
+ def end_of_day(dt=None):
107
+ dt = DateUtils.parse(dt) if dt else datetime.now()
108
+ return datetime(dt.year, dt.month, dt.day, 23, 59, 59)
109
+
110
+ @staticmethod
111
+ def start_of_week(dt=None):
112
+ dt = DateUtils.parse(dt) if dt else datetime.now()
113
+ start = dt - timedelta(days=dt.weekday())
114
+ return datetime(start.year, start.month, start.day)
115
+
116
+ @staticmethod
117
+ def end_of_week(dt=None):
118
+ dt = DateUtils.parse(dt) if dt else datetime.now()
119
+ end = dt + timedelta(days=6 - dt.weekday())
120
+ return datetime(end.year, end.month, end.day, 23, 59, 59)
121
+
122
+ @staticmethod
123
+ def start_of_month(dt=None):
124
+ dt = DateUtils.parse(dt) if dt else datetime.now()
125
+ return datetime(dt.year, dt.month, 1)
126
+
127
+ @staticmethod
128
+ def end_of_month(dt=None):
129
+ dt = DateUtils.parse(dt) if dt else datetime.now()
130
+ last_day = calendar.monthrange(dt.year, dt.month)[1]
131
+ return datetime(dt.year, dt.month, last_day, 23, 59, 59)
132
+
133
+ @staticmethod
134
+ def start_of_quarter(dt=None):
135
+ dt = DateUtils.parse(dt) if dt else datetime.now()
136
+ month = ((dt.month - 1) // 3) * 3 + 1
137
+ return datetime(dt.year, month, 1)
138
+
139
+ @staticmethod
140
+ def end_of_quarter(dt=None):
141
+ dt = DateUtils.parse(dt) if dt else datetime.now()
142
+ month = ((dt.month - 1) // 3 + 1) * 3
143
+ last_day = calendar.monthrange(dt.year, month)[1]
144
+ return datetime(dt.year, month, last_day, 23, 59, 59)
145
+
146
+ # -------------------- 日期判断 --------------------
147
+ @staticmethod
148
+ def is_leap_year(year):
149
+ return calendar.isleap(year)
150
+
151
+ @staticmethod
152
+ def weekday(dt=None):
153
+ dt = DateUtils.parse(dt) if dt else datetime.now()
154
+ return dt.weekday() # 0=周一
155
+
156
+ @staticmethod
157
+ def is_weekend(dt=None):
158
+ return DateUtils.weekday(dt) >= 5
159
+
160
+ @staticmethod
161
+ def days_between(start, end):
162
+ start = DateUtils.parse(start)
163
+ end = DateUtils.parse(end)
164
+ return (end - start).days
165
+
166
+ # -------------------- 日期区间 --------------------
167
+ @staticmethod
168
+ def date_range(start, end, step=1):
169
+ start = DateUtils.parse(start)
170
+ end = DateUtils.parse(end)
171
+ days = []
172
+ delta = timedelta(days=step)
173
+ current = start
174
+ while current <= end:
175
+ days.append(current)
176
+ current += delta
177
+ return days
178
+
179
+ # -------------------- 自然语言解析 --------------------
180
+ @staticmethod
181
+ def smart_parse(text):
182
+ """支持 '今天','明天','昨天','上周一','下个月15号'"""
183
+ today = datetime.now()
184
+ text = text.strip()
185
+ if text == "今天":
186
+ return today
187
+ elif text == "明天":
188
+ return today + timedelta(days=1)
189
+ elif text == "昨天":
190
+ return today - timedelta(days=1)
191
+ m = re.match(r"上周([一二三四五六日])", text)
192
+ if m:
193
+ weekday_map = {"一":0,"二":1,"三":2,"四":3,"五":4,"六":5,"日":6}
194
+ target_weekday = weekday_map[m.group(1)]
195
+ delta_days = today.weekday() - target_weekday + 7
196
+ return today - timedelta(days=delta_days)
197
+ # TODO: 可继续扩展自然语言解析
198
+ return DateUtils.parse(text)
199
+
200
+ @staticmethod
201
+ def add_days_str(date_str, days, fmt="%Y-%m-%d"):
202
+ """直接对字符串日期加减天数,返回字符串"""
203
+ dt = datetime.strptime(date_str, fmt)
204
+ dt += timedelta(days=days)
205
+ return dt.strftime(fmt)
206
+
207
+ @staticmethod
208
+ def format_day(date_str, fmt="%Y-%m-%d"):
209
+ """直接对字符串日期加减天数,返回字符串"""
210
+ dt = datetime.strptime(date_str, fmt)
211
+ return dt.strftime("%Y年%m月%d日")
212
+
213
+ @staticmethod
214
+ def to_timestamp(dt):
215
+ dt = DateUtils.parse(dt) if isinstance(dt, (str, int, float)) else dt
216
+ return int(dt.timestamp())
217
+ # ------------------------ 测试 ------------------------
218
+ if __name__ == "__main__":
219
+ print("现在时间:", DateUtils.now())
220
+ print("今天:", DateUtils.today())
221
+ print("月初:", DateUtils.start_of_month())
222
+ print("月末:", DateUtils.end_of_month())
223
+ print("季度开始:", DateUtils.start_of_quarter())
224
+ print("季度结束:", DateUtils.end_of_quarter())
225
+ print("加3天:", DateUtils.add_days(datetime.now(), 3))
226
+ print("是否周末:", DateUtils.is_weekend())
227
+ print("自然语言解析 明天:", DateUtils.smart_parse("明天"))
228
+ print("日期区间:", [d.strftime("%Y-%m-%d") for d in DateUtils.date_range("2025-12-01", "2025-12-05")])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: terryutils
3
- Version: 1.0.5
3
+ Version: 1.0.6
4
4
  Summary: My personal python toolkit
5
5
  Author-email: Terry Zhu <596480606@qq.com>
6
6
  License: MIT
@@ -1,6 +1,7 @@
1
1
  README.md
2
2
  pyproject.toml
3
3
  src/terryutils/__init__.py
4
+ src/terryutils/date_util.py
4
5
  src/terryutils/log.py
5
6
  src/terryutils/mysql_util.py
6
7
  src/terryutils.egg-info/PKG-INFO
@@ -1,2 +0,0 @@
1
- from .mysql_util import MysqlUtil
2
- from .log import setup_logger
File without changes
File without changes