staran 1.0.0__py3-none-any.whl → 1.0.3__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.
- staran/__init__.py +57 -5
- staran/date/__init__.py +37 -0
- staran/date/core.py +549 -0
- staran/date/examples/__init__.py +11 -0
- staran/date/examples/basic_usage.py +177 -0
- staran/date/tests/__init__.py +11 -0
- staran/date/tests/run_tests.py +109 -0
- staran/date/tests/test_core.py +519 -0
- staran/date/utils/__init__.py +11 -0
- staran/date/utils/helpers.py +203 -0
- staran-1.0.3.dist-info/METADATA +198 -0
- staran-1.0.3.dist-info/RECORD +15 -0
- staran/tools/__init__.py +0 -43
- staran/tools/date.py +0 -300
- staran-1.0.0.dist-info/METADATA +0 -301
- staran-1.0.0.dist-info/RECORD +0 -8
- {staran-1.0.0.dist-info → staran-1.0.3.dist-info}/WHEEL +0 -0
- {staran-1.0.0.dist-info → staran-1.0.3.dist-info}/licenses/LICENSE +0 -0
- {staran-1.0.0.dist-info → staran-1.0.3.dist-info}/top_level.txt +0 -0
staran/tools/date.py
DELETED
@@ -1,300 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
|
4
|
-
"""
|
5
|
-
简化的Date类 - 纯Python实现
|
6
|
-
使用datetime包提供日期处理功能
|
7
|
-
"""
|
8
|
-
|
9
|
-
import datetime
|
10
|
-
import calendar
|
11
|
-
import re
|
12
|
-
|
13
|
-
class Date:
|
14
|
-
"""简化的日期类,基于Python datetime实现"""
|
15
|
-
|
16
|
-
def __init__(self, *args, **kwargs):
|
17
|
-
"""
|
18
|
-
初始化日期对象
|
19
|
-
支持多种创建方式:
|
20
|
-
- Date() - 今日
|
21
|
-
- Date(year, month, day) - 指定日期
|
22
|
-
- Date('20240615') - 从字符串
|
23
|
-
- Date(year=2024, month=6, day=15) - 关键字参数
|
24
|
-
"""
|
25
|
-
# 默认格式设置
|
26
|
-
self._default_format = '%Y-%m-%d' # 默认完整日期格式
|
27
|
-
self._input_format_type = 'full' # 输入格式类型: 'full', 'year_month', 'timestamp', 'today'
|
28
|
-
|
29
|
-
if not args and not kwargs:
|
30
|
-
# 无参数 - 今日
|
31
|
-
today = datetime.date.today()
|
32
|
-
self.year, self.month, self.day = today.year, today.month, today.day
|
33
|
-
self._input_format_type = 'today'
|
34
|
-
self._default_format = '%Y-%m-%d'
|
35
|
-
elif len(args) == 1 and isinstance(args[0], str):
|
36
|
-
# 字符串参数
|
37
|
-
self._init_from_string(args[0])
|
38
|
-
elif len(args) == 1 and isinstance(args[0], int):
|
39
|
-
# 单个整数参数 - 视为时间戳
|
40
|
-
dt = datetime.datetime.fromtimestamp(args[0])
|
41
|
-
self.year, self.month, self.day = dt.year, dt.month, dt.day
|
42
|
-
self._input_format_type = 'timestamp'
|
43
|
-
self._default_format = '%Y-%m-%d'
|
44
|
-
elif len(args) in [2, 3]:
|
45
|
-
# 位置参数
|
46
|
-
self._init_from_args(args)
|
47
|
-
elif kwargs:
|
48
|
-
# 关键字参数
|
49
|
-
self._init_from_kwargs(kwargs)
|
50
|
-
else:
|
51
|
-
raise ValueError("Invalid arguments for Date initialization")
|
52
|
-
|
53
|
-
# 验证日期有效性
|
54
|
-
self._validate_date()
|
55
|
-
|
56
|
-
def _init_from_string(self, date_string):
|
57
|
-
"""从字符串初始化日期"""
|
58
|
-
# 移除所有分隔符
|
59
|
-
clean_string = re.sub(r'[^\d]', '', date_string)
|
60
|
-
|
61
|
-
if len(clean_string) == 6: # YYYYMM
|
62
|
-
self.year = int(clean_string[:4])
|
63
|
-
self.month = int(clean_string[4:6])
|
64
|
-
self.day = 1
|
65
|
-
self._input_format_type = 'year_month'
|
66
|
-
self._default_format = '%Y%m'
|
67
|
-
elif len(clean_string) == 8: # YYYYMMDD
|
68
|
-
self.year = int(clean_string[:4])
|
69
|
-
self.month = int(clean_string[4:6])
|
70
|
-
self.day = int(clean_string[6:8])
|
71
|
-
self._input_format_type = 'full'
|
72
|
-
self._default_format = '%Y%m%d'
|
73
|
-
else:
|
74
|
-
raise ValueError(f"Date string must be 6 (YYYYMM) or 8 (YYYYMMDD) digits after removing separators, got {len(clean_string)}")
|
75
|
-
|
76
|
-
def _init_from_args(self, args):
|
77
|
-
"""从位置参数初始化日期"""
|
78
|
-
if len(args) == 2:
|
79
|
-
self.year, self.month = args
|
80
|
-
self.day = 1
|
81
|
-
self._input_format_type = 'year_month'
|
82
|
-
self._default_format = '%Y-%m'
|
83
|
-
elif len(args) == 3:
|
84
|
-
self.year, self.month, self.day = args
|
85
|
-
self._input_format_type = 'full'
|
86
|
-
self._default_format = '%Y-%m-%d'
|
87
|
-
else:
|
88
|
-
raise ValueError("Expected 2 or 3 positional arguments")
|
89
|
-
|
90
|
-
def _init_from_kwargs(self, kwargs):
|
91
|
-
"""从关键字参数初始化日期"""
|
92
|
-
self.year = kwargs.get('year')
|
93
|
-
self.month = kwargs.get('month')
|
94
|
-
self.day = kwargs.get('day', 1)
|
95
|
-
|
96
|
-
if self.year is None or self.month is None:
|
97
|
-
raise ValueError("year and month are required")
|
98
|
-
|
99
|
-
# 根据是否提供day参数设置格式
|
100
|
-
if 'day' in kwargs:
|
101
|
-
self._input_format_type = 'full'
|
102
|
-
self._default_format = '%Y-%m-%d'
|
103
|
-
else:
|
104
|
-
self._input_format_type = 'year_month'
|
105
|
-
self._default_format = '%Y-%m'
|
106
|
-
|
107
|
-
def _validate_date(self):
|
108
|
-
"""验证日期有效性"""
|
109
|
-
if not isinstance(self.year, int) or self.year <= 0:
|
110
|
-
raise ValueError(f"Year must be positive, got {self.year}")
|
111
|
-
|
112
|
-
if not isinstance(self.month, int) or not (1 <= self.month <= 12):
|
113
|
-
raise ValueError(f"Month must be between 1 and 12, got {self.month}")
|
114
|
-
|
115
|
-
if not isinstance(self.day, int) or self.day <= 0:
|
116
|
-
raise ValueError(f"Day must be positive, got {self.day}")
|
117
|
-
|
118
|
-
# 检查日期是否在该月的有效范围内
|
119
|
-
max_day = calendar.monthrange(self.year, self.month)[1]
|
120
|
-
if self.day > max_day:
|
121
|
-
raise ValueError(f"Day {self.day} is invalid for {self.year}-{self.month:02d}")
|
122
|
-
|
123
|
-
def to_timestamp(self):
|
124
|
-
"""转换为时间戳"""
|
125
|
-
dt = datetime.datetime.combine(
|
126
|
-
datetime.date(self.year, self.month, self.day),
|
127
|
-
datetime.time()
|
128
|
-
)
|
129
|
-
return dt.timestamp()
|
130
|
-
|
131
|
-
def to_date(self):
|
132
|
-
"""转换为Python datetime.date对象"""
|
133
|
-
return datetime.date(self.year, self.month, self.day)
|
134
|
-
|
135
|
-
def to_datetime(self):
|
136
|
-
"""转换为Python datetime.datetime对象"""
|
137
|
-
return datetime.datetime(self.year, self.month, self.day)
|
138
|
-
|
139
|
-
def format(self, fmt=None):
|
140
|
-
"""
|
141
|
-
格式化日期字符串
|
142
|
-
如果不指定格式,使用默认格式(根据输入时的格式确定)
|
143
|
-
"""
|
144
|
-
if fmt is None:
|
145
|
-
fmt = self._default_format
|
146
|
-
return self.to_date().strftime(fmt)
|
147
|
-
|
148
|
-
def format_default(self):
|
149
|
-
"""使用默认格式输出(保持输入时的格式风格)"""
|
150
|
-
return self.format()
|
151
|
-
|
152
|
-
def format_full(self):
|
153
|
-
"""完整日期格式: YYYY-MM-DD"""
|
154
|
-
return self.format('%Y-%m-%d')
|
155
|
-
|
156
|
-
def format_compact(self):
|
157
|
-
"""紧凑格式: YYYYMMDD"""
|
158
|
-
return self.format('%Y%m%d')
|
159
|
-
|
160
|
-
def format_year_month(self):
|
161
|
-
"""年月格式: YYYY-MM"""
|
162
|
-
return self.format('%Y-%m')
|
163
|
-
|
164
|
-
def format_year_month_compact(self):
|
165
|
-
"""年月紧凑格式: YYYYMM"""
|
166
|
-
return self.format('%Y%m')
|
167
|
-
|
168
|
-
def format_chinese(self):
|
169
|
-
"""中文格式: YYYY年MM月DD日"""
|
170
|
-
return self.format('%Y年%m月%d日')
|
171
|
-
|
172
|
-
def format_chinese_short(self):
|
173
|
-
"""中文短格式: YYYY年MM月(适用于年月类型)"""
|
174
|
-
if self._input_format_type == 'year_month':
|
175
|
-
return self.format('%Y年%m月')
|
176
|
-
else:
|
177
|
-
return self.format('%Y年%m月%d日')
|
178
|
-
|
179
|
-
def format_iso(self):
|
180
|
-
"""ISO 8601格式: YYYY-MM-DD"""
|
181
|
-
return self.format('%Y-%m-%d')
|
182
|
-
|
183
|
-
def format_us(self):
|
184
|
-
"""美式格式: MM/DD/YYYY"""
|
185
|
-
return self.format('%m/%d/%Y')
|
186
|
-
|
187
|
-
def format_european(self):
|
188
|
-
"""欧式格式: DD/MM/YYYY"""
|
189
|
-
return self.format('%d/%m/%Y')
|
190
|
-
|
191
|
-
def weekday(self):
|
192
|
-
"""返回星期几(0=Monday, 6=Sunday)"""
|
193
|
-
return self.to_date().weekday()
|
194
|
-
|
195
|
-
def isoweekday(self):
|
196
|
-
"""返回星期几(1=Monday, 7=Sunday)"""
|
197
|
-
return self.to_date().isoweekday()
|
198
|
-
|
199
|
-
def is_leap_year(self):
|
200
|
-
"""判断是否为闰年"""
|
201
|
-
return calendar.isleap(self.year)
|
202
|
-
|
203
|
-
def days_in_month(self):
|
204
|
-
"""返回当月天数"""
|
205
|
-
return calendar.monthrange(self.year, self.month)[1]
|
206
|
-
|
207
|
-
def days_in_year(self):
|
208
|
-
"""返回当年天数"""
|
209
|
-
return 366 if self.is_leap_year() else 365
|
210
|
-
|
211
|
-
def get_default_format(self):
|
212
|
-
"""获取默认格式字符串"""
|
213
|
-
return self._default_format
|
214
|
-
|
215
|
-
def get_input_format_type(self):
|
216
|
-
"""获取输入格式类型"""
|
217
|
-
return self._input_format_type
|
218
|
-
|
219
|
-
def set_default_format(self, fmt):
|
220
|
-
"""设置新的默认格式"""
|
221
|
-
self._default_format = fmt
|
222
|
-
return self
|
223
|
-
|
224
|
-
def add_days(self, days):
|
225
|
-
"""增加天数,返回新的Date对象,保持原始格式"""
|
226
|
-
new_date = self.to_date() + datetime.timedelta(days=days)
|
227
|
-
result = Date(new_date.year, new_date.month, new_date.day)
|
228
|
-
# 保持原始格式设置
|
229
|
-
result._default_format = self._default_format
|
230
|
-
result._input_format_type = self._input_format_type
|
231
|
-
return result
|
232
|
-
|
233
|
-
def add_months(self, months):
|
234
|
-
"""增加月数,返回新的Date对象,保持原始格式"""
|
235
|
-
new_month = self.month + months
|
236
|
-
new_year = self.year
|
237
|
-
|
238
|
-
while new_month > 12:
|
239
|
-
new_month -= 12
|
240
|
-
new_year += 1
|
241
|
-
while new_month < 1:
|
242
|
-
new_month += 12
|
243
|
-
new_year -= 1
|
244
|
-
|
245
|
-
# 处理日期溢出(如1月31日+1个月=2月28/29日)
|
246
|
-
max_day = calendar.monthrange(new_year, new_month)[1]
|
247
|
-
new_day = min(self.day, max_day)
|
248
|
-
|
249
|
-
result = Date(new_year, new_month, new_day)
|
250
|
-
# 保持原始格式设置
|
251
|
-
result._default_format = self._default_format
|
252
|
-
result._input_format_type = self._input_format_type
|
253
|
-
return result
|
254
|
-
|
255
|
-
def difference(self, other):
|
256
|
-
"""计算与另一个日期的天数差"""
|
257
|
-
if not isinstance(other, Date):
|
258
|
-
raise TypeError("Expected Date object")
|
259
|
-
|
260
|
-
date1 = self.to_date()
|
261
|
-
date2 = other.to_date()
|
262
|
-
return (date1 - date2).days
|
263
|
-
|
264
|
-
def __str__(self):
|
265
|
-
"""字符串表示,使用默认格式"""
|
266
|
-
return self.format_default()
|
267
|
-
|
268
|
-
def __repr__(self):
|
269
|
-
"""调试表示"""
|
270
|
-
return f"Date({self.year}, {self.month}, {self.day})"
|
271
|
-
|
272
|
-
def __eq__(self, other):
|
273
|
-
"""相等比较"""
|
274
|
-
if not isinstance(other, Date):
|
275
|
-
return False
|
276
|
-
return (self.year, self.month, self.day) == (other.year, other.month, other.day)
|
277
|
-
|
278
|
-
def __lt__(self, other):
|
279
|
-
"""小于比较"""
|
280
|
-
if not isinstance(other, Date):
|
281
|
-
return NotImplemented
|
282
|
-
return (self.year, self.month, self.day) < (other.year, other.month, other.day)
|
283
|
-
|
284
|
-
def __le__(self, other):
|
285
|
-
"""小于等于比较"""
|
286
|
-
return self < other or self == other
|
287
|
-
|
288
|
-
def __gt__(self, other):
|
289
|
-
"""大于比较"""
|
290
|
-
if not isinstance(other, Date):
|
291
|
-
return NotImplemented
|
292
|
-
return (self.year, self.month, self.day) > (other.year, other.month, other.day)
|
293
|
-
|
294
|
-
def __ge__(self, other):
|
295
|
-
"""大于等于比较"""
|
296
|
-
return self > other or self == other
|
297
|
-
|
298
|
-
def __hash__(self):
|
299
|
-
"""哈希值"""
|
300
|
-
return hash((self.year, self.month, self.day))
|
staran-1.0.0.dist-info/METADATA
DELETED
@@ -1,301 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: staran
|
3
|
-
Version: 1.0.0
|
4
|
-
Summary: staran - 轻量级Python日期工具库
|
5
|
-
Home-page: https://github.com/starlxa/staran
|
6
|
-
Author: StarAn
|
7
|
-
Author-email: starlxa@icloud.com
|
8
|
-
License: MIT
|
9
|
-
Project-URL: Bug Reports, https://github.com/starlxa/staran/issues
|
10
|
-
Project-URL: Source, https://github.com/starlxa/staran
|
11
|
-
Keywords: date datetime utilities time-processing
|
12
|
-
Classifier: Development Status :: 5 - Production/Stable
|
13
|
-
Classifier: Intended Audience :: Developers
|
14
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
15
|
-
Classifier: Topic :: Utilities
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
17
|
-
Classifier: Programming Language :: Python :: 3.7
|
18
|
-
Classifier: Programming Language :: Python :: 3.8
|
19
|
-
Classifier: Programming Language :: Python :: 3.9
|
20
|
-
Classifier: Programming Language :: Python :: 3.10
|
21
|
-
Classifier: Programming Language :: Python :: 3.11
|
22
|
-
Classifier: Programming Language :: Python :: 3.12
|
23
|
-
Classifier: Operating System :: OS Independent
|
24
|
-
Requires-Python: >=3.7
|
25
|
-
Description-Content-Type: text/markdown
|
26
|
-
License-File: LICENSE
|
27
|
-
Dynamic: author
|
28
|
-
Dynamic: author-email
|
29
|
-
Dynamic: classifier
|
30
|
-
Dynamic: description
|
31
|
-
Dynamic: description-content-type
|
32
|
-
Dynamic: home-page
|
33
|
-
Dynamic: keywords
|
34
|
-
Dynamic: license
|
35
|
-
Dynamic: license-file
|
36
|
-
Dynamic: project-url
|
37
|
-
Dynamic: requires-python
|
38
|
-
Dynamic: summary
|
39
|
-
|
40
|
-
# Staran ✨ v1.0.0 - 轻量级Python日期工具库
|
41
|
-
|
42
|
-
- 🔧 **完善的包管理** - 优化setup.py配置,专注核心日期功能
|
43
|
-
- 🗓️ **智能日期处理** - 支持多种日期格式,自动格式记忆
|
44
|
-
- 📅 **灵活日期运算** - 便捷的日期加减运算,保持原格式
|
45
|
-
- 🎯 **简洁易用** - 专注日期处理,轻量级设计
|
46
|
-
- 🔄 **格式转换** - 支持多种日期格式输出
|
47
|
-
- 📦 **零依赖** - 只使用Python标准库,无外部依赖
|
48
|
-
|
49
|
-
## 🎯 专为日期处理设计的Python工具库
|
50
|
-
|
51
|
-
Staran是一个轻量级的日期处理工具库,提供智能的日期格式记忆和便捷的日期运算功能。特别适合需要处理多种日期格式的应用场景。
|
52
|
-
|
53
|
-
## ✨ v1.0.0 新特性
|
54
|
-
|
55
|
-
🎉 **稳定版本发布** - 核心功能完备,API稳定
|
56
|
-
|
57
|
-
- 🔧 **完善的包管理** - 优化setup.py配置,专注核心功能
|
58
|
-
- 📦 **轻量化重构** - 移除非核心模块,专注日期处理
|
59
|
-
- 🗓️ **智能格式记忆** - 根据输入自动记住日期格式
|
60
|
-
- 📅 **丰富的运算功能** - 支持天数和月数的加减运算
|
61
|
-
- 🎯 **零外部依赖** - 只使用Python标准库
|
62
|
-
- 🔄 **多种输出格式** - 支持中文、ISO等多种格式输出
|
63
|
-
|
64
|
-
## 🚧 v1.1.0 计划中的企业级优化
|
65
|
-
|
66
|
-
> **注意:** 当前v1.0.0版本具备完整的核心功能,但在企业工程化标准方面还有提升空间。
|
67
|
-
> 我们将在v1.1.0版本中完成以下企业级优化:
|
68
|
-
|
69
|
-
### 🔬 **代码质量提升**
|
70
|
-
- ✅ **类型注解** - 完整的typing支持和类型检查
|
71
|
-
- ✅ **单元测试** - 100%代码覆盖率的测试套件
|
72
|
-
- ✅ **文档规范** - 完善的docstring和API文档
|
73
|
-
- ✅ **异常处理** - 标准化的异常体系和错误码
|
74
|
-
|
75
|
-
### 🏗️ **架构优化**
|
76
|
-
- ✅ **性能优化** - 缓存机制和延迟计算
|
77
|
-
- ✅ **配置管理** - 支持配置文件和环境变量
|
78
|
-
- ✅ **日志系统** - 结构化日志和调试支持
|
79
|
-
- ✅ **插件架构** - 可扩展的格式化器和验证器
|
80
|
-
|
81
|
-
### 🛡️ **企业级特性**
|
82
|
-
- ✅ **输入验证** - 严格的数据验证和清洗
|
83
|
-
- ✅ **国际化支持** - 多语言和时区处理
|
84
|
-
- ✅ **向后兼容** - API版本管理和迁移指南
|
85
|
-
- ✅ **安全考虑** - 输入安全和数据保护
|
86
|
-
|
87
|
-
### 📊 **开发体验**
|
88
|
-
- ✅ **IDE支持** - 完整的代码提示和自动完成
|
89
|
-
- ✅ **调试工具** - 丰富的调试信息和工具
|
90
|
-
- ✅ **基准测试** - 性能基准和监控
|
91
|
-
- ✅ **CI/CD集成** - 自动化测试和发布流程
|
92
|
-
|
93
|
-
## ⚠️ 当前版本限制
|
94
|
-
|
95
|
-
v1.0.0是一个功能完备的稳定版本,但请注意以下企业级使用的限制:
|
96
|
-
|
97
|
-
### 📝 **代码质量**
|
98
|
-
- **类型检查**: 当前缺少typing注解,IDE代码提示可能不完整
|
99
|
-
- **测试覆盖**: 没有自动化测试套件,建议在生产环境使用前进行充分测试
|
100
|
-
- **异常处理**: 异常信息可能不够详细,调试时需要注意
|
101
|
-
|
102
|
-
### 🏗️ **架构限制**
|
103
|
-
- **性能**: 没有缓存机制,频繁计算可能影响性能
|
104
|
-
- **配置**: 不支持配置文件,所有设置需要在代码中硬编码
|
105
|
-
- **日志**: 没有内置日志系统,调试信息有限
|
106
|
-
|
107
|
-
### 🛡️ **企业特性**
|
108
|
-
- **验证**: 输入验证相对简单,复杂场景可能需要额外验证
|
109
|
-
- **国际化**: 目前只支持基本的中文格式,缺少完整的i18n支持
|
110
|
-
- **安全**: 没有特殊的安全考虑,输入数据请自行验证
|
111
|
-
|
112
|
-
> 💡 **建议**: 如果您需要在企业级生产环境中使用,建议等待v1.1.0版本,或者基于当前版本进行二次开发。
|
113
|
-
|
114
|
-
## 🚀 快速开始
|
115
|
-
|
116
|
-
### 安装
|
117
|
-
```bash
|
118
|
-
pip install staran
|
119
|
-
```
|
120
|
-
|
121
|
-
### 基础用法 - 智能日期处理
|
122
|
-
|
123
|
-
```python
|
124
|
-
from staran import Date
|
125
|
-
|
126
|
-
# 创建日期 - 智能格式记忆
|
127
|
-
date1 = Date('202504') # 输出: 202504 (记住年月格式)
|
128
|
-
date2 = Date('20250415') # 输出: 20250415 (记住完整格式)
|
129
|
-
date3 = Date(2025, 4, 15) # 输出: 2025-04-15
|
130
|
-
|
131
|
-
# 日期运算保持格式
|
132
|
-
new_date = date1.add_months(2) # 输出: 202506 (保持YYYYMM格式)
|
133
|
-
|
134
|
-
# 多种格式输出
|
135
|
-
print(date2.format_chinese()) # 输出: 2025年04月15日
|
136
|
-
print(date2.format_iso()) # 输出: 2025-04-15
|
137
|
-
```
|
138
|
-
|
139
|
-
## 📚 核心功能
|
140
|
-
|
141
|
-
### 🗓️ Date类 - 智能日期处理
|
142
|
-
|
143
|
-
#### 创建日期对象
|
144
|
-
|
145
|
-
```python
|
146
|
-
from staran import Date
|
147
|
-
|
148
|
-
# 字符串格式(自动识别)
|
149
|
-
date1 = Date('2025') # 年份
|
150
|
-
date2 = Date('202504') # 年月
|
151
|
-
date3 = Date('20250415') # 年月日
|
152
|
-
|
153
|
-
# 参数格式
|
154
|
-
date4 = Date(2025, 4, 15) # 年, 月, 日
|
155
|
-
date5 = Date(year=2025, month=4, day=15)
|
156
|
-
|
157
|
-
# 从datetime对象
|
158
|
-
from datetime import datetime
|
159
|
-
date6 = Date(datetime.now())
|
160
|
-
```
|
161
|
-
|
162
|
-
#### 日期运算
|
163
|
-
|
164
|
-
```python
|
165
|
-
# 加减天数
|
166
|
-
tomorrow = date.add_days(1)
|
167
|
-
yesterday = date.add_days(-1)
|
168
|
-
|
169
|
-
# 加减月数
|
170
|
-
next_month = date.add_months(1)
|
171
|
-
last_month = date.add_months(-1)
|
172
|
-
|
173
|
-
# 月末日期
|
174
|
-
month_end = date.month_end()
|
175
|
-
|
176
|
-
# 月初日期
|
177
|
-
month_start = date.month_start()
|
178
|
-
```
|
179
|
-
|
180
|
-
#### 格式化输出
|
181
|
-
|
182
|
-
```python
|
183
|
-
date = Date('20250415')
|
184
|
-
|
185
|
-
print(date) # 20250415 (保持原格式)
|
186
|
-
print(date.format_iso()) # 2025-04-15
|
187
|
-
print(date.format_chinese()) # 2025年04月15日
|
188
|
-
print(date.format_slash()) # 2025/04/15
|
189
|
-
print(date.format_dot()) # 2025.04.15
|
190
|
-
```
|
191
|
-
|
192
|
-
#### 日期比较
|
193
|
-
|
194
|
-
```python
|
195
|
-
date1 = Date('20250415')
|
196
|
-
date2 = Date('20250416')
|
197
|
-
|
198
|
-
print(date1 < date2) # True
|
199
|
-
print(date1 == date2) # False
|
200
|
-
print(date1 > date2) # False
|
201
|
-
```
|
202
|
-
|
203
|
-
## 🎯 特色功能
|
204
|
-
|
205
|
-
### 智能格式记忆
|
206
|
-
|
207
|
-
Date类会根据输入格式自动选择默认输出格式:
|
208
|
-
|
209
|
-
```python
|
210
|
-
# 年月格式 - 输出保持YYYYMM
|
211
|
-
date_ym = Date('202504')
|
212
|
-
print(date_ym) # 202504
|
213
|
-
print(date_ym.add_months(1)) # 202505
|
214
|
-
|
215
|
-
# 完整格式 - 输出保持YYYYMMDD
|
216
|
-
date_full = Date('20250415')
|
217
|
-
print(date_full) # 20250415
|
218
|
-
print(date_full.add_days(1)) # 20250416
|
219
|
-
```
|
220
|
-
|
221
|
-
### 灵活的日期运算
|
222
|
-
|
223
|
-
```python
|
224
|
-
date = Date('202504')
|
225
|
-
|
226
|
-
# 月份运算
|
227
|
-
print(date.add_months(3)) # 202507
|
228
|
-
print(date.add_months(-2)) # 202502
|
229
|
-
|
230
|
-
# 季度运算
|
231
|
-
print(date.add_months(3)) # 下一季度
|
232
|
-
|
233
|
-
# 年份运算
|
234
|
-
print(date.add_months(12)) # 明年同月
|
235
|
-
```
|
236
|
-
|
237
|
-
## 🛠️ 高级用法
|
238
|
-
|
239
|
-
### 批量日期处理
|
240
|
-
|
241
|
-
```python
|
242
|
-
from staran import Date
|
243
|
-
|
244
|
-
# 生成日期序列
|
245
|
-
start_date = Date('202501')
|
246
|
-
dates = []
|
247
|
-
for i in range(12):
|
248
|
-
dates.append(start_date.add_months(i))
|
249
|
-
|
250
|
-
print(dates) # ['202501', '202502', ..., '202512']
|
251
|
-
```
|
252
|
-
|
253
|
-
### 与datetime互操作
|
254
|
-
|
255
|
-
```python
|
256
|
-
from staran import Date
|
257
|
-
from datetime import datetime
|
258
|
-
|
259
|
-
# Date转datetime
|
260
|
-
date = Date('20250415')
|
261
|
-
dt = date.to_datetime()
|
262
|
-
|
263
|
-
# datetime转Date
|
264
|
-
dt = datetime.now()
|
265
|
-
date = Date(dt)
|
266
|
-
```
|
267
|
-
|
268
|
-
## 📋 API参考
|
269
|
-
|
270
|
-
### Date类方法
|
271
|
-
|
272
|
-
| 方法 | 描述 | 示例 |
|
273
|
-
|------|------|------|
|
274
|
-
| `Date(input)` | 创建日期对象 | `Date('202504')` |
|
275
|
-
| `add_days(n)` | 加减天数 | `date.add_days(7)` |
|
276
|
-
| `add_months(n)` | 加减月数 | `date.add_months(2)` |
|
277
|
-
| `month_start()` | 获取月初 | `date.month_start()` |
|
278
|
-
| `month_end()` | 获取月末 | `date.month_end()` |
|
279
|
-
| `format_iso()` | ISO格式 | `date.format_iso()` |
|
280
|
-
| `format_chinese()` | 中文格式 | `date.format_chinese()` |
|
281
|
-
| `format_slash()` | 斜杠格式 | `date.format_slash()` |
|
282
|
-
| `format_dot()` | 点分格式 | `date.format_dot()` |
|
283
|
-
| `to_datetime()` | 转datetime | `date.to_datetime()` |
|
284
|
-
|
285
|
-
## 🤝 贡献
|
286
|
-
|
287
|
-
欢迎提交Issues和Pull Requests!
|
288
|
-
|
289
|
-
## 📄 许可证
|
290
|
-
|
291
|
-
MIT License - 详见 [LICENSE](LICENSE) 文件。
|
292
|
-
|
293
|
-
## 🔗 链接
|
294
|
-
|
295
|
-
- [GitHub仓库](https://github.com/starlxa/staran)
|
296
|
-
- [PyPI包页面](https://pypi.org/project/staran/)
|
297
|
-
- [问题反馈](https://github.com/starlxa/staran/issues)
|
298
|
-
|
299
|
-
---
|
300
|
-
|
301
|
-
**Staran** - 让日期处理变得简单而优雅 ✨
|
staran-1.0.0.dist-info/RECORD
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
staran/__init__.py,sha256=G8Kfqho5-4yN_2WS7xkRa63C0AdDS4OQTWRMLtVnypw,208
|
2
|
-
staran/tools/__init__.py,sha256=4R2WpIlVtR0_QZL2eB5AcwlKffNc0z1V-YIg1lk8xYA,1061
|
3
|
-
staran/tools/date.py,sha256=-QyEMWVx6czMuOIwcV7kR3gBMRVOwb5qevo7GEFSJKE,10488
|
4
|
-
staran-1.0.0.dist-info/licenses/LICENSE,sha256=2EmsBIyDCono4iVXNpv5_px9qt2b7hfPq1WuyGVMNP4,1361
|
5
|
-
staran-1.0.0.dist-info/METADATA,sha256=bnl3wnJe3bVEpCfEC6SwBv7-1BRicwIgf9RTFUCqdOw,8862
|
6
|
-
staran-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
7
|
-
staran-1.0.0.dist-info/top_level.txt,sha256=NOUZtXSh5oSIEjHrC0lQ9WmoKtD010Q00dghWyag-Zs,7
|
8
|
-
staran-1.0.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|