staran 1.0.9__py3-none-any.whl → 1.0.10__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.
@@ -0,0 +1,495 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Date类v1.0.10新功能测试
6
+ ======================
7
+
8
+ 测试v1.0.10版本新增的功能:
9
+ - 时区支持
10
+ - 日期表达式解析
11
+ - 二十四节气
12
+ - 数据可视化
13
+ - 增强日期范围操作
14
+ """
15
+
16
+ import unittest
17
+ import datetime
18
+ import sys
19
+ import os
20
+
21
+ # 添加项目根目录到路径
22
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
23
+
24
+ from staran.date.core.core import Date, DateRange
25
+ from staran.date import get_version_info, parse_expression
26
+
27
+ class TestV1010TimezoneSupport(unittest.TestCase):
28
+ """测试时区支持功能"""
29
+
30
+ def setUp(self):
31
+ self.date = Date("2025-07-29")
32
+
33
+ def test_get_supported_timezones(self):
34
+ """测试获取支持的时区"""
35
+ try:
36
+ timezones = Date.get_supported_timezones()
37
+ self.assertIsInstance(timezones, list)
38
+ if timezones: # 如果功能可用
39
+ self.assertIn('UTC', timezones)
40
+ self.assertIn('UTC+8', timezones)
41
+ except NotImplementedError:
42
+ self.skipTest("时区功能不可用")
43
+
44
+ def test_get_timezone_info(self):
45
+ """测试获取时区信息"""
46
+ try:
47
+ tz_info = self.date.get_timezone_info('UTC+8')
48
+ self.assertIsInstance(tz_info, dict)
49
+ self.assertIn('name', tz_info)
50
+ self.assertIn('current_offset', tz_info)
51
+ self.assertIn('offset_string', tz_info)
52
+ except NotImplementedError:
53
+ self.skipTest("时区功能不可用")
54
+
55
+ def test_timezone_conversion(self):
56
+ """测试时区转换"""
57
+ try:
58
+ time_part = datetime.time(12, 0, 0)
59
+ result = self.date.to_timezone('UTC+8', time_part)
60
+ self.assertIsInstance(result, datetime.datetime)
61
+ self.assertEqual(result.date(), self.date.to_date_object())
62
+ except NotImplementedError:
63
+ self.skipTest("时区功能不可用")
64
+
65
+ class TestV1010ExpressionParsing(unittest.TestCase):
66
+ """测试日期表达式解析功能"""
67
+
68
+ def test_simple_expressions(self):
69
+ """测试简单表达式"""
70
+ try:
71
+ # 基本表达式
72
+ today = Date.today()
73
+
74
+ tomorrow = parse_expression("明天")
75
+ if tomorrow: # 如果功能可用
76
+ expected_tomorrow = today.add_days(1)
77
+ self.assertEqual(tomorrow.to_date_object(), expected_tomorrow.to_date_object())
78
+
79
+ yesterday = parse_expression("昨天")
80
+ if yesterday:
81
+ expected_yesterday = today.add_days(-1)
82
+ self.assertEqual(yesterday.to_date_object(), expected_yesterday.to_date_object())
83
+ except NotImplementedError:
84
+ self.skipTest("表达式解析功能不可用")
85
+
86
+ def test_detailed_parsing(self):
87
+ """测试详细解析"""
88
+ try:
89
+ result = Date.parse_expression_detailed("明天")
90
+ self.assertIsInstance(result, dict)
91
+ self.assertIn('success', result)
92
+ self.assertIn('confidence', result)
93
+ self.assertIn('matched_pattern', result)
94
+ except NotImplementedError:
95
+ self.skipTest("表达式解析功能不可用")
96
+
97
+ def test_expression_matching(self):
98
+ """测试表达式匹配"""
99
+ try:
100
+ today = Date.today()
101
+ self.assertTrue(today.matches_expression("今天"))
102
+ except NotImplementedError:
103
+ self.skipTest("表达式解析功能不可用")
104
+
105
+ class TestV1010SolarTerms(unittest.TestCase):
106
+ """测试二十四节气功能"""
107
+
108
+ def setUp(self):
109
+ self.date = Date("2025-07-29")
110
+ self.year = 2025
111
+
112
+ def test_get_year_solar_terms(self):
113
+ """测试获取年份节气"""
114
+ try:
115
+ terms = Date.get_year_solar_terms(self.year)
116
+ self.assertIsInstance(terms, list)
117
+ if terms: # 如果功能可用
118
+ self.assertEqual(len(terms), 24)
119
+ # 检查第一个节气
120
+ first_term = terms[0]
121
+ self.assertEqual(first_term.name, '立春')
122
+ except NotImplementedError:
123
+ self.skipTest("节气功能不可用")
124
+
125
+ def test_get_season_solar_terms(self):
126
+ """测试获取季节节气"""
127
+ try:
128
+ spring_terms = Date.get_season_solar_terms(self.year, '春季')
129
+ self.assertIsInstance(spring_terms, list)
130
+ if spring_terms: # 如果功能可用
131
+ self.assertEqual(len(spring_terms), 6)
132
+ self.assertEqual(spring_terms[0].name, '立春')
133
+ except NotImplementedError:
134
+ self.skipTest("节气功能不可用")
135
+
136
+ def test_solar_term_queries(self):
137
+ """测试节气查询"""
138
+ try:
139
+ # 获取当前最近节气
140
+ current_term = self.date.get_solar_term()
141
+ if current_term: # 如果功能可用
142
+ self.assertIsNotNone(current_term.name)
143
+ self.assertIsNotNone(current_term.season)
144
+
145
+ # 获取下一个节气
146
+ next_term = self.date.get_next_solar_term()
147
+ if next_term:
148
+ self.assertIsNotNone(next_term.name)
149
+
150
+ # 获取上一个节气
151
+ prev_term = self.date.get_previous_solar_term()
152
+ if prev_term:
153
+ self.assertIsNotNone(prev_term.name)
154
+
155
+ # 到下个节气的天数
156
+ days = self.date.days_to_next_solar_term()
157
+ self.assertIsInstance(days, int)
158
+ self.assertGreaterEqual(days, 0)
159
+
160
+ except NotImplementedError:
161
+ self.skipTest("节气功能不可用")
162
+
163
+ def test_is_solar_term(self):
164
+ """测试是否节气日"""
165
+ try:
166
+ is_term = self.date.is_solar_term()
167
+ self.assertIsInstance(is_term, bool)
168
+ except NotImplementedError:
169
+ self.skipTest("节气功能不可用")
170
+
171
+ def test_solar_term_season(self):
172
+ """测试获取节气季节"""
173
+ try:
174
+ season = self.date.get_solar_term_season()
175
+ self.assertIsInstance(season, str)
176
+ except NotImplementedError:
177
+ self.skipTest("节气功能不可用")
178
+
179
+ class TestV1010Visualization(unittest.TestCase):
180
+ """测试数据可视化功能"""
181
+
182
+ def setUp(self):
183
+ self.dates = [Date("2025-07-29"), Date("2025-07-30"), Date("2025-07-31")]
184
+ self.events = ["事件1", "事件2", "事件3"]
185
+
186
+ def test_create_timeline_chart(self):
187
+ """测试创建时间轴图表"""
188
+ try:
189
+ from staran.date import create_timeline_chart
190
+ chart_data = create_timeline_chart(self.dates, self.events, 'echarts')
191
+
192
+ self.assertIsNotNone(chart_data)
193
+ self.assertEqual(chart_data.chart_type, 'timeline')
194
+ self.assertEqual(chart_data.library, 'echarts')
195
+ self.assertIsInstance(chart_data.data, list)
196
+ except (NotImplementedError, ImportError):
197
+ self.skipTest("可视化功能不可用")
198
+
199
+ def test_create_calendar_heatmap(self):
200
+ """测试创建日历热力图"""
201
+ try:
202
+ date_values = {
203
+ Date("2025-07-29"): 85,
204
+ Date("2025-07-30"): 92,
205
+ Date("2025-07-31"): 78
206
+ }
207
+
208
+ chart_data = Date.create_calendar_heatmap(date_values, 2025, 'echarts')
209
+
210
+ self.assertIsNotNone(chart_data)
211
+ self.assertEqual(chart_data.chart_type, 'calendar_heatmap')
212
+ self.assertEqual(chart_data.library, 'echarts')
213
+ except NotImplementedError:
214
+ self.skipTest("可视化功能不可用")
215
+
216
+ def test_create_time_series_chart(self):
217
+ """测试创建时间序列图"""
218
+ try:
219
+ time_series_data = [
220
+ (Date("2025-07-29"), 100),
221
+ (Date("2025-07-30"), 120),
222
+ (Date("2025-07-31"), 95)
223
+ ]
224
+
225
+ chart_data = Date.create_time_series_chart(time_series_data, 'echarts')
226
+
227
+ self.assertIsNotNone(chart_data)
228
+ self.assertEqual(chart_data.chart_type, 'time_series')
229
+ self.assertEqual(chart_data.library, 'echarts')
230
+ except NotImplementedError:
231
+ self.skipTest("可视化功能不可用")
232
+
233
+ def test_create_date_distribution_chart(self):
234
+ """测试创建日期分布图"""
235
+ try:
236
+ chart_data = Date.create_date_distribution_chart(self.dates, 'month', 'echarts')
237
+
238
+ self.assertIsNotNone(chart_data)
239
+ self.assertEqual(chart_data.chart_type, 'distribution')
240
+ self.assertEqual(chart_data.library, 'echarts')
241
+ except NotImplementedError:
242
+ self.skipTest("可视化功能不可用")
243
+
244
+ class TestV1010EnhancedDateRanges(unittest.TestCase):
245
+ """测试增强的日期范围功能"""
246
+
247
+ def setUp(self):
248
+ self.start_date = Date("2025-07-29")
249
+ self.end_date = Date("2025-08-15")
250
+
251
+ def test_create_range_to(self):
252
+ """测试创建到指定日期的范围"""
253
+ date_range = self.start_date.create_range_to(self.end_date)
254
+
255
+ self.assertIsInstance(date_range, DateRange)
256
+ self.assertEqual(date_range.start, self.start_date)
257
+ self.assertEqual(date_range.end, self.end_date)
258
+
259
+ def test_create_range_with_days(self):
260
+ """测试创建指定天数的范围"""
261
+ # 未来10天
262
+ future_range = self.start_date.create_range_with_days(10)
263
+ self.assertEqual(future_range.start, self.start_date)
264
+ self.assertEqual(future_range.end, self.start_date.add_days(10))
265
+
266
+ # 过去5天
267
+ past_range = self.start_date.create_range_with_days(-5)
268
+ self.assertEqual(past_range.start, self.start_date.add_days(-5))
269
+ self.assertEqual(past_range.end, self.start_date)
270
+
271
+ def test_in_range(self):
272
+ """测试是否在范围内"""
273
+ test_date = Date("2025-08-01")
274
+
275
+ # 在范围内
276
+ self.assertTrue(test_date.in_range(self.start_date, self.end_date))
277
+
278
+ # 不在范围内
279
+ out_of_range_date = Date("2025-09-01")
280
+ self.assertFalse(out_of_range_date.in_range(self.start_date, self.end_date))
281
+
282
+ def test_create_date_sequence(self):
283
+ """测试创建日期序列"""
284
+ sequence = Date.create_date_sequence(self.start_date, self.start_date.add_days(6), 2)
285
+
286
+ self.assertIsInstance(sequence, list)
287
+ self.assertEqual(len(sequence), 4) # 0, 2, 4, 6天
288
+ self.assertEqual(sequence[0], self.start_date)
289
+ self.assertEqual(sequence[1], self.start_date.add_days(2))
290
+
291
+ def test_find_common_dates(self):
292
+ """测试查找共同日期"""
293
+ list1 = [Date("2025-07-29"), Date("2025-07-30"), Date("2025-07-31")]
294
+ list2 = [Date("2025-07-30"), Date("2025-07-31"), Date("2025-08-01")]
295
+ list3 = [Date("2025-07-31"), Date("2025-08-01"), Date("2025-08-02")]
296
+
297
+ common_dates = Date.find_common_dates([list1, list2, list3])
298
+
299
+ self.assertIsInstance(common_dates, list)
300
+ self.assertEqual(len(common_dates), 1)
301
+ self.assertEqual(common_dates[0], Date("2025-07-31"))
302
+
303
+ class TestV1010UtilityMethods(unittest.TestCase):
304
+ """测试v1.0.10实用工具方法"""
305
+
306
+ def setUp(self):
307
+ self.date = Date("2025-07-29")
308
+
309
+ def test_get_version_info(self):
310
+ """测试获取版本信息"""
311
+ version_info = self.date.get_version_info()
312
+
313
+ self.assertIsInstance(version_info, dict)
314
+ self.assertIn('version', version_info)
315
+ self.assertEqual(version_info['version'], '1.0.10')
316
+ self.assertIn('enhanced_features', version_info)
317
+ self.assertIn('available_modules', version_info)
318
+ self.assertIn('api_count', version_info)
319
+
320
+ def test_get_feature_status(self):
321
+ """测试获取功能状态"""
322
+ feature_status = Date.get_feature_status()
323
+
324
+ self.assertIsInstance(feature_status, dict)
325
+ self.assertIn('core_date_operations', feature_status)
326
+ self.assertTrue(feature_status['core_date_operations'])
327
+ self.assertIn('lunar_calendar', feature_status)
328
+ self.assertTrue(feature_status['lunar_calendar'])
329
+ self.assertIn('multilingual_support', feature_status)
330
+ self.assertTrue(feature_status['multilingual_support'])
331
+
332
+ def test_help_system(self):
333
+ """测试帮助系统"""
334
+ # 测试创建方法帮助
335
+ help_creation = self.date.help('creation')
336
+ self.assertIsInstance(help_creation, str)
337
+ self.assertIn('Date', help_creation)
338
+
339
+ # 测试格式化帮助
340
+ help_formatting = self.date.help('formatting')
341
+ self.assertIsInstance(help_formatting, str)
342
+ self.assertIn('format', help_formatting)
343
+
344
+ # 测试计算帮助
345
+ help_calculations = self.date.help('calculations')
346
+ self.assertIsInstance(help_calculations, str)
347
+ self.assertIn('add_days', help_calculations)
348
+
349
+ # 测试全部帮助
350
+ help_all = self.date.help('all')
351
+ self.assertIsInstance(help_all, str)
352
+ self.assertIn('Date', help_all)
353
+
354
+ class TestV1010Integration(unittest.TestCase):
355
+ """测试v1.0.10集成功能"""
356
+
357
+ def test_version_consistency(self):
358
+ """测试版本一致性"""
359
+ from staran.date import __version__, get_version_info
360
+
361
+ # 检查模块版本
362
+ self.assertEqual(__version__, "1.0.10")
363
+
364
+ # 检查版本信息函数
365
+ version_info = get_version_info()
366
+ self.assertEqual(version_info['version'], "1.0.10")
367
+
368
+ def test_backwards_compatibility(self):
369
+ """测试向后兼容性"""
370
+ # 确保所有v1.0.8和v1.0.9的功能仍然可用
371
+ date = Date("2025-07-29")
372
+
373
+ # 基础功能
374
+ self.assertEqual(date.format_iso(), "2025-07-29")
375
+ self.assertEqual(date.format_chinese(), "2025年07月29日")
376
+
377
+ # 农历功能
378
+ lunar = date.to_lunar()
379
+ self.assertIsNotNone(lunar)
380
+
381
+ # 多语言功能
382
+ Date.set_language('zh_CN')
383
+ localized = date.format_localized()
384
+ self.assertIsInstance(localized, str)
385
+
386
+ # 计算功能
387
+ tomorrow = date.add_days(1)
388
+ self.assertEqual(tomorrow.to_date_object(), datetime.date(2025, 7, 30))
389
+
390
+ def test_api_count_increase(self):
391
+ """测试API数量增加"""
392
+ date = Date("2025-07-29")
393
+ version_info = date.get_version_info()
394
+
395
+ # v1.0.10应该比之前版本有更多API
396
+ api_count = version_info['api_count']
397
+ self.assertGreater(api_count, 120) # 应该超过120个API方法
398
+
399
+ # 测试运行器
400
+ class TestV1010Runner:
401
+ """v1.0.10测试运行器"""
402
+
403
+ @staticmethod
404
+ def run_all_tests():
405
+ """运行所有v1.0.10测试"""
406
+ loader = unittest.TestLoader()
407
+ suite = unittest.TestSuite()
408
+
409
+ # 添加所有测试类
410
+ test_classes = [
411
+ TestV1010TimezoneSupport,
412
+ TestV1010ExpressionParsing,
413
+ TestV1010SolarTerms,
414
+ TestV1010Visualization,
415
+ TestV1010EnhancedDateRanges,
416
+ TestV1010UtilityMethods,
417
+ TestV1010Integration
418
+ ]
419
+
420
+ for test_class in test_classes:
421
+ tests = loader.loadTestsFromTestCase(test_class)
422
+ suite.addTests(tests)
423
+
424
+ # 运行测试
425
+ runner = unittest.TextTestRunner(verbosity=2)
426
+ result = runner.run(suite)
427
+
428
+ return result
429
+
430
+ @staticmethod
431
+ def run_specific_test(test_class_name: str):
432
+ """运行特定测试类"""
433
+ test_classes = {
434
+ 'timezone': TestV1010TimezoneSupport,
435
+ 'expressions': TestV1010ExpressionParsing,
436
+ 'solar_terms': TestV1010SolarTerms,
437
+ 'visualization': TestV1010Visualization,
438
+ 'ranges': TestV1010EnhancedDateRanges,
439
+ 'utilities': TestV1010UtilityMethods,
440
+ 'integration': TestV1010Integration
441
+ }
442
+
443
+ test_class = test_classes.get(test_class_name)
444
+ if test_class:
445
+ loader = unittest.TestLoader()
446
+ suite = loader.loadTestsFromTestCase(test_class)
447
+ runner = unittest.TextTestRunner(verbosity=2)
448
+ return runner.run(suite)
449
+ else:
450
+ print(f"测试类 '{test_class_name}' 不存在")
451
+ print(f"可用的测试类: {list(test_classes.keys())}")
452
+
453
+ if __name__ == "__main__":
454
+ print("🧪 Staran v1.0.10 新功能测试")
455
+ print("=" * 50)
456
+
457
+ # 检查命令行参数
458
+ if len(sys.argv) > 1:
459
+ test_name = sys.argv[1]
460
+ print(f"运行特定测试: {test_name}")
461
+ TestV1010Runner.run_specific_test(test_name)
462
+ else:
463
+ print("运行所有v1.0.10新功能测试")
464
+ result = TestV1010Runner.run_all_tests()
465
+
466
+ # 输出结果摘要
467
+ print(f"\n" + "=" * 50)
468
+ print(f"测试摘要:")
469
+ print(f" 运行测试数: {result.testsRun}")
470
+ print(f" 失败数: {len(result.failures)}")
471
+ print(f" 错误数: {len(result.errors)}")
472
+ print(f" 跳过数: {len(result.skipped)}")
473
+
474
+ if result.failures:
475
+ print(f"\n失败的测试:")
476
+ for test, traceback in result.failures:
477
+ print(f" - {test}")
478
+
479
+ if result.errors:
480
+ print(f"\n错误的测试:")
481
+ for test, traceback in result.errors:
482
+ print(f" - {test}")
483
+
484
+ if result.skipped:
485
+ print(f"\n跳过的测试:")
486
+ for test, reason in result.skipped:
487
+ print(f" - {test}: {reason}")
488
+
489
+ success_rate = (result.testsRun - len(result.failures) - len(result.errors)) / result.testsRun * 100
490
+ print(f"\n成功率: {success_rate:.1f}%")
491
+
492
+ if result.wasSuccessful():
493
+ print("✅ 所有测试通过!")
494
+ else:
495
+ print("❌ 部分测试失败")
@@ -1,18 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: staran
3
- Version: 1.0.9
4
- Summary: staran - 轻量级Python日期工具库
3
+ Version: 1.0.10
4
+ Summary: staran - 企业级Python日期处理库
5
5
  Home-page: https://github.com/starlxa/staran
6
6
  Author: StarAn
7
7
  Author-email: starlxa@icloud.com
8
8
  License: MIT
9
9
  Project-URL: Bug Reports, https://github.com/starlxa/staran/issues
10
10
  Project-URL: Source, https://github.com/starlxa/staran
11
- Keywords: date datetime utilities time-processing lunar calendar i18n
11
+ Project-URL: Documentation, https://github.com/starlxa/staran/blob/master/API_REFERENCE.md
12
+ Keywords: date datetime utilities time-processing lunar calendar i18n timezone visualization api
12
13
  Classifier: Development Status :: 5 - Production/Stable
13
14
  Classifier: Intended Audience :: Developers
14
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
16
  Classifier: Topic :: Utilities
17
+ Classifier: Topic :: Software Development :: Localization
18
+ Classifier: Topic :: Scientific/Engineering :: Visualization
16
19
  Classifier: Programming Language :: Python :: 3
17
20
  Classifier: Programming Language :: Python :: 3.7
18
21
  Classifier: Programming Language :: Python :: 3.8
@@ -21,9 +24,25 @@ Classifier: Programming Language :: Python :: 3.10
21
24
  Classifier: Programming Language :: Python :: 3.11
22
25
  Classifier: Programming Language :: Python :: 3.12
23
26
  Classifier: Operating System :: OS Independent
27
+ Classifier: License :: OSI Approved :: MIT License
24
28
  Requires-Python: >=3.7
25
29
  Description-Content-Type: text/markdown
26
30
  License-File: LICENSE
31
+ Provides-Extra: visualization
32
+ Requires-Dist: matplotlib>=3.0.0; extra == "visualization"
33
+ Requires-Dist: plotly>=5.0.0; extra == "visualization"
34
+ Provides-Extra: web
35
+ Requires-Dist: flask>=2.0.0; extra == "web"
36
+ Provides-Extra: full
37
+ Requires-Dist: matplotlib>=3.0.0; extra == "full"
38
+ Requires-Dist: plotly>=5.0.0; extra == "full"
39
+ Requires-Dist: flask>=2.0.0; extra == "full"
40
+ Provides-Extra: dev
41
+ Requires-Dist: pytest>=6.0.0; extra == "dev"
42
+ Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
43
+ Requires-Dist: black>=21.0.0; extra == "dev"
44
+ Requires-Dist: flake8>=3.8.0; extra == "dev"
45
+ Requires-Dist: mypy>=0.800; extra == "dev"
27
46
  Dynamic: author
28
47
  Dynamic: author-email
29
48
  Dynamic: classifier
@@ -34,6 +53,7 @@ Dynamic: keywords
34
53
  Dynamic: license
35
54
  Dynamic: license-file
36
55
  Dynamic: project-url
56
+ Dynamic: provides-extra
37
57
  Dynamic: requires-python
38
58
  Dynamic: summary
39
59
 
@@ -48,8 +68,9 @@ Dynamic: summary
48
68
 
49
69
  ## 📚 文档导航
50
70
 
51
- - **[API 参考文档](API_REFERENCE.md)** - 完整的API文档和使用指南
52
- - **[更新日志](CHANGELOG.md)** - 详细的版本历史和更新记录
71
+ - **[API 参考文档](https://github.com/StarLxa/staran/tree/master/API_REFERENCE.md)** - 完整的API文档和使用指南
72
+ - **[更新日志](https://github.com/StarLxa/staran/tree/master/CHANGELOG.md)** - 详细的版本历史和更新记录
73
+ - **[PyPI包页面](https://pypi.org/project/staran/)** - 安装和版本信息
53
74
  - **[快速开始](#快速开始)** - 立即开始使用
54
75
 
55
76
  ## 🚀 核心理念
@@ -94,6 +115,9 @@ staran/
94
115
  ### 安装
95
116
 
96
117
  ```bash
118
+ # 从PyPI安装 (推荐)
119
+ pip install staran
120
+
97
121
  # 从源码安装
98
122
  git clone https://github.com/StarLxa/staran.git
99
123
  cd staran
@@ -172,8 +196,9 @@ python -m staran.date.tests.run_tests
172
196
 
173
197
  ## 📖 文档
174
198
 
175
- - **[API参考文档](API_REFERENCE.md)** - 完整的API文档、使用指南和示例
176
- - **[更新日志](CHANGELOG.md)** - 详细的版本历史和功能变更
199
+ - **[API参考文档](https://github.com/StarLxa/staran/tree/master/API_REFERENCE.md)** - 完整的API文档、使用指南和示例
200
+ - **[更新日志](https://github.com/StarLxa/staran/tree/master/CHANGELOG.md)** - 详细的版本历史和功能变更
201
+ - **[PyPI包页面](https://pypi.org/project/staran/)** - 安装和版本信息
177
202
 
178
203
  ## 🛠️ 开发
179
204
 
@@ -200,7 +225,8 @@ python -m staran.date.tests.run_tests
200
225
  ## 📞 支持
201
226
 
202
227
  - **GitHub Issues**: 报告Bug和功能请求
203
- - **文档**: [API参考文档](API_REFERENCE.md)
228
+ - **文档**: [API参考文档](https://github.com/StarLxa/staran/tree/master/API_REFERENCE.md)
229
+ - **PyPI**: [PyPI包页面](https://pypi.org/project/staran/)
204
230
  - **示例**: 查看 `examples/` 目录
205
231
 
206
232
  ## 📄 许可证
@@ -0,0 +1,34 @@
1
+ staran/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ staran/date/__init__.py,sha256=CPVRv_g76wGRuKIoorXsqc58buoUQl5XkIqnZdugJUg,2858
3
+ staran/date/core/__init__.py,sha256=cZmvd7X36qmXUGPrf-K0xOchzPiSONv1rw1WMi1uNXA,430
4
+ staran/date/core/core.py,sha256=1rlVqJaZZh8PxlBcE8R6aJoHP27Xwvpc6DZ5Mv30RhU,88769
5
+ staran/date/core/i18n.py,sha256=bvnqhVGMYvW8Lt3W4uksJw9aRZ2l4cNAy0GiYEQy4II,14677
6
+ staran/date/core/lunar.py,sha256=JCs9EJOsfCXE4jgTkfZZw85-IKvjPbtx70CapEAy4sQ,11980
7
+ staran/date/examples/__init__.py,sha256=5q6uxzeIhPcFo64gXybEozx4E4lt8TEEibFC-dF_EV0,163
8
+ staran/date/examples/basic_usage.py,sha256=hsQZaMRR6tY9krLjmYrH7GrMkk2cGapY-bfjwsL_6YQ,4738
9
+ staran/date/examples/enhanced_features.py,sha256=KDxw1d-h3N19oidCyeHKCSMUrOtr0sP7K5YI1fsowrw,6598
10
+ staran/date/examples/v1010_features_demo.py,sha256=KvqfUsM3KV9kMjM2eNvGMjIdLVnRo1pYRYfLeOFH974,13342
11
+ staran/date/examples/v108_features_demo.py,sha256=E3lxnSY7nKVOi2uVl7Rb8-mxQNetBkg4PiWnV4ydmMs,9380
12
+ staran/date/examples/v109_features_demo.py,sha256=AJJu2VUKeb-GTgCHCRf4nuX9XpGwJuScxhvg2xJgJgg,9994
13
+ staran/date/extensions/__init__.py,sha256=bHkUYgwSg7FmudxLZc7185NXuxX7skMJDp69fWbEKwg,998
14
+ staran/date/extensions/expressions.py,sha256=B-p_17sGWmQfD0RVA_-_NnXvKSNgCGd2HFrH2qdlSDE,21865
15
+ staran/date/extensions/solar_terms.py,sha256=4DUNswNIOvXzIy3Q9i11MitiMoLu59Ru2S3GKnYKmfM,16007
16
+ staran/date/extensions/timezone.py,sha256=CP7kFc96CWO0RGMDF6bmVmUOoL8x9gr7YQdV8Wi5564,11182
17
+ staran/date/integrations/__init__.py,sha256=WUDNgOpktaciTylh7ftQTAgM-ROUgzbCzSajF-BEVJs,837
18
+ staran/date/integrations/api_server.py,sha256=5gV-TFkZY0sj0CA-QIWxMgoDOm1U-Dc6lC0dLMwIqxI,31097
19
+ staran/date/integrations/visualization.py,sha256=B-ZS0jjqW-sIgMBxrmGDOa8LhJS5vNol3NNLJvLNetY,23666
20
+ staran/date/tests/__init__.py,sha256=oYQFFa4lv_68398OrMGk4CMX_4XX-9KuPHTflhkLmbo,171
21
+ staran/date/tests/run_tests.py,sha256=XY8dH_zFgyQ84YAd-49sok1F8VnOsNGB_TpbJex6HKA,5842
22
+ staran/date/tests/test_core.py,sha256=IqiLjlvTBcXmajyFZDIkvh9cxT6ivQ6QFao1cXKx0w8,16539
23
+ staran/date/tests/test_enhancements.py,sha256=Iv7vr_RkHV9kgSdTKWyiAx5zbsJXf-ZLv9ytlp5TtZo,9892
24
+ staran/date/tests/test_v1010_features.py,sha256=VGWwvUtal0IfwGkIjzTCWlSGgeZrljaeJdK9f2a68X0,18266
25
+ staran/date/tests/test_v108_features.py,sha256=wih6mY-fgq1aEYdvXkFqzoeSk73-8Mf9WVe7DFjvyqE,13462
26
+ staran/date/tests/test_v109_features.py,sha256=hN5m3DTQM8j_U9ilh3fN3cQvBZH4DPI7stGlsgdIEEw,10932
27
+ staran/date/utils/__init__.py,sha256=W5DkeslSOINF7kq6wFz3l16fUmGI0XALNuJAALQeLLM,142
28
+ staran/date/utils/helpers.py,sha256=9TlebdCr-YD4vrXjTFMXDG413gbSFwdUNyivAarIp5M,5553
29
+ staran-1.0.10.dist-info/licenses/LICENSE,sha256=2EmsBIyDCono4iVXNpv5_px9qt2b7hfPq1WuyGVMNP4,1361
30
+ staran-1.0.10.dist-info/METADATA,sha256=9FVvrpHWubF7sAn2YOSib0wyaghDys9_ao9A1z5s1Us,8012
31
+ staran-1.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
32
+ staran-1.0.10.dist-info/entry_points.txt,sha256=igvLxDd-ONmb_m9IwbFKMv_uMhAyb_nPfNIq3J3rZUg,54
33
+ staran-1.0.10.dist-info/top_level.txt,sha256=NOUZtXSh5oSIEjHrC0lQ9WmoKtD010Q00dghWyag-Zs,7
34
+ staran-1.0.10.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ staran = staran.date.utils.cli:main
@@ -1,23 +0,0 @@
1
- staran/__init__.py,sha256=lbTKJOdoI1vk57NppCMP2iDCncsgl3-Bk9sa5oln9ro,1172
2
- staran/date/__init__.py,sha256=ksZST17hK2eZ3ImS4U2wIai-iGarsdTHRmtLHDNTGyI,2106
3
- staran/date/core.py,sha256=vKxSDTTNQrB8Srte2mCpZeNSOtEk2fzN7b4Abexmtao,70470
4
- staran/date/i18n.py,sha256=bvnqhVGMYvW8Lt3W4uksJw9aRZ2l4cNAy0GiYEQy4II,14677
5
- staran/date/lunar.py,sha256=JCs9EJOsfCXE4jgTkfZZw85-IKvjPbtx70CapEAy4sQ,11980
6
- staran/date/examples/__init__.py,sha256=5q6uxzeIhPcFo64gXybEozx4E4lt8TEEibFC-dF_EV0,163
7
- staran/date/examples/basic_usage.py,sha256=hsQZaMRR6tY9krLjmYrH7GrMkk2cGapY-bfjwsL_6YQ,4738
8
- staran/date/examples/enhanced_features.py,sha256=KDxw1d-h3N19oidCyeHKCSMUrOtr0sP7K5YI1fsowrw,6598
9
- staran/date/examples/v108_features_demo.py,sha256=E3lxnSY7nKVOi2uVl7Rb8-mxQNetBkg4PiWnV4ydmMs,9380
10
- staran/date/examples/v109_features_demo.py,sha256=AJJu2VUKeb-GTgCHCRf4nuX9XpGwJuScxhvg2xJgJgg,9994
11
- staran/date/tests/__init__.py,sha256=oYQFFa4lv_68398OrMGk4CMX_4XX-9KuPHTflhkLmbo,171
12
- staran/date/tests/run_tests.py,sha256=XY8dH_zFgyQ84YAd-49sok1F8VnOsNGB_TpbJex6HKA,5842
13
- staran/date/tests/test_core.py,sha256=IqiLjlvTBcXmajyFZDIkvh9cxT6ivQ6QFao1cXKx0w8,16539
14
- staran/date/tests/test_enhancements.py,sha256=Iv7vr_RkHV9kgSdTKWyiAx5zbsJXf-ZLv9ytlp5TtZo,9892
15
- staran/date/tests/test_v108_features.py,sha256=wih6mY-fgq1aEYdvXkFqzoeSk73-8Mf9WVe7DFjvyqE,13462
16
- staran/date/tests/test_v109_features.py,sha256=hN5m3DTQM8j_U9ilh3fN3cQvBZH4DPI7stGlsgdIEEw,10932
17
- staran/date/utils/__init__.py,sha256=W5DkeslSOINF7kq6wFz3l16fUmGI0XALNuJAALQeLLM,142
18
- staran/date/utils/helpers.py,sha256=9TlebdCr-YD4vrXjTFMXDG413gbSFwdUNyivAarIp5M,5553
19
- staran-1.0.9.dist-info/licenses/LICENSE,sha256=2EmsBIyDCono4iVXNpv5_px9qt2b7hfPq1WuyGVMNP4,1361
20
- staran-1.0.9.dist-info/METADATA,sha256=xsPPTospviLkXHJTN3eqZFs6gT6RNcmY5gmOhdZBjL4,6585
21
- staran-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- staran-1.0.9.dist-info/top_level.txt,sha256=NOUZtXSh5oSIEjHrC0lQ9WmoKtD010Q00dghWyag-Zs,7
23
- staran-1.0.9.dist-info/RECORD,,
File without changes
File without changes