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/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))
@@ -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** - 让日期处理变得简单而优雅 ✨
@@ -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