staran 0.1.0__py3-none-any.whl → 0.1.2__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.
tools/date/date.py DELETED
@@ -1,857 +0,0 @@
1
- # 定义类
2
- class Date:
3
- # 类变量:C扩展可用性检查
4
- _c_extension_checked = False
5
- _has_c_extension = False
6
-
7
- @classmethod
8
- def _check_c_extension(cls):
9
- """检查C扩展是否可用(只检查一次)"""
10
- if not cls._c_extension_checked:
11
- try:
12
- from . import platform_utils
13
- cls._has_c_extension = platform_utils.has_c_extension()
14
- cls._c_extension_checked = True
15
- except (ImportError, AttributeError):
16
- cls._has_c_extension = False
17
- cls._c_extension_checked = True
18
- return cls._has_c_extension
19
-
20
- @classmethod
21
- def has_c_extension(cls):
22
- """检查是否有C扩展可用"""
23
- return cls._check_c_extension()
24
-
25
- @classmethod
26
- def get_platform_info(cls):
27
- """获取平台信息"""
28
- try:
29
- from . import platform_utils
30
- return platform_utils.get_platform_info()
31
- except (ImportError, AttributeError):
32
- import platform
33
- return {
34
- 'system': platform.system(),
35
- 'machine': platform.machine(),
36
- 'python_version': platform.python_version(),
37
- 'has_c_extension': False,
38
- 'implementation': 'Python fallback'
39
- }
40
-
41
- def __init__(self, *args, **kwargs):
42
- # 如果传入一个参数且是字符串,则交给方法 parse_date
43
- if len(args) == 1 and isinstance(args[0], str):
44
- self._str_date(args[0])
45
- # 如果传入位置参数(2个或3个)
46
- elif len(args) in [2, 3]:
47
- self._init_from_args(args)
48
- # 如果使用关键字参数
49
- elif kwargs:
50
- self._init_from_kwargs(kwargs)
51
- # 如果没有参数,使用当天日期
52
- elif len(args) == 0:
53
- self._init_from_today()
54
- else:
55
- raise ValueError("Invalid arguments provided to Date class")
56
-
57
- # 对所有非字符串初始化的情况进行验证
58
- # 如果不是通过parse_date设置的(即不是从字符串解析的),则需要验证
59
- if not (len(args) == 1 and isinstance(args[0], str)):
60
- self._validate_date_values()
61
-
62
- def _init_from_args(self, args):
63
- """从位置参数初始化日期"""
64
- if len(args) == 2:
65
- self.year, self.month = args
66
- self.day = 1
67
- elif len(args) == 3:
68
- self.year, self.month, self.day = args
69
-
70
- def _init_from_kwargs(self, kwargs):
71
- """从关键字参数初始化日期"""
72
- # 获取当天日期作为默认值
73
- try:
74
- from . import platform_utils
75
- default_year, default_month, default_day = platform_utils.get_today()
76
- except (ImportError, AttributeError):
77
- # 回退到datetime实现
78
- import datetime
79
- today = datetime.date.today()
80
- default_year, default_month, default_day = today.year, today.month, today.day
81
-
82
- self.year = kwargs.get('year', default_year)
83
- self.month = kwargs.get('month', default_month)
84
- self.day = kwargs.get('day', default_day)
85
-
86
- def _init_from_today(self):
87
- """使用当天日期初始化"""
88
- try:
89
- from . import platform_utils
90
- self.year, self.month, self.day = platform_utils.get_today()
91
- except (ImportError, AttributeError):
92
- # 回退到datetime实现
93
- import datetime
94
- today = datetime.date.today()
95
- self.year, self.month, self.day = today.year, today.month, today.day
96
-
97
- def _validate_year(self, year):
98
- """验证年份是否有效"""
99
- if not isinstance(year, int):
100
- raise ValueError(f"Year must be an integer, got {type(year).__name__}")
101
- if year < 1:
102
- raise ValueError(f"Year must be positive, got {year}")
103
- return year
104
-
105
- def _validate_month(self, month):
106
- """验证月份是否有效"""
107
- if not isinstance(month, int):
108
- raise ValueError(f"Month must be an integer, got {type(month).__name__}")
109
- if not (1 <= month <= 12):
110
- raise ValueError(f"Month must be between 1 and 12, got {month}")
111
- return month
112
-
113
- def _validate_day(self, day):
114
- """验证日期是否有效"""
115
- if not isinstance(day, int):
116
- raise ValueError(f"Day must be an integer, got {type(day).__name__}")
117
- if not (1 <= day <= 31):
118
- raise ValueError(f"Day must be between 1 and 31, got {day}")
119
- return day
120
-
121
- def _validate_date_values(self):
122
- """验证年、月、日的组合是否合理"""
123
- self.year = self._validate_year(self.year)
124
- self.month = self._validate_month(self.month)
125
- self.day = self._validate_day(self.day)
126
-
127
- # 验证日期组合
128
- self._validate_date_combination()
129
-
130
- def _is_leap_year(self, year):
131
- """检查是否为闰年"""
132
- return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
133
-
134
- # 定义方法,删除原有字符串的 - / . 字符
135
- # 删除后如果为6位,则为 YYYYMM 格式
136
- # 如果为8位,则为 YYYYMMDD 格式
137
- def _str_date(self, date_str):
138
- if not date_str or not isinstance(date_str, str):
139
- raise ValueError("Date string cannot be empty or None")
140
-
141
- # 清理字符串,移除分隔符
142
- cleaned_str = date_str.replace("-", "").replace("/", "").replace(".", "")
143
-
144
- # 验证长度和内容
145
- if len(cleaned_str) not in [6, 8]:
146
- raise ValueError(f"Date string must be 6 (YYYYMM) or 8 (YYYYMMDD) digits after removing separators, got {len(cleaned_str)}")
147
-
148
- if not cleaned_str.isdigit():
149
- raise ValueError("Date string must contain only digits and separators")
150
-
151
- try:
152
- year = int(cleaned_str[:4])
153
- month = int(cleaned_str[4:6])
154
- day = int(cleaned_str[6:]) if len(cleaned_str) == 8 else 1
155
-
156
- # 使用验证方法
157
- self.year = self._validate_year(year)
158
- self.month = self._validate_month(month)
159
- self.day = self._validate_day(day)
160
-
161
- # 验证日期组合的合理性
162
- self._validate_date_combination()
163
-
164
- except ValueError as e:
165
- if "invalid literal" in str(e):
166
- raise ValueError("Date string contains invalid characters")
167
- raise
168
-
169
- def _validate_date_combination(self):
170
- """验证年、月、日组合是否合理(不重复验证单个值)"""
171
- # 进一步验证日期是否在该月份的有效范围内
172
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
173
-
174
- # 检查闰年
175
- if self._is_leap_year(self.year):
176
- days_in_month[1] = 29
177
-
178
- if self.day > days_in_month[self.month - 1]:
179
- raise ValueError(f"Day {self.day} is invalid for {self.year}-{self.month:02d}")
180
-
181
- def past_month(self, months=1):
182
- """
183
- 获取过去的月份
184
-
185
- Args:
186
- months (int): 往前推的月份数,默认为1
187
-
188
- Returns:
189
- Date: 新的Date对象,表示过去指定月份的日期
190
- """
191
- if not isinstance(months, int) or months < 0:
192
- raise ValueError("Months must be a non-negative integer")
193
-
194
- # 计算新的年份和月份
195
- new_year = self.year
196
- new_month = self.month - months
197
-
198
- # 处理月份跨年的情况
199
- while new_month <= 0:
200
- new_month += 12
201
- new_year -= 1
202
-
203
- # 处理日期可能超出目标月份天数的情况
204
- new_day = self._adjust_day_for_month(new_year, new_month, self.day)
205
-
206
- return Date(new_year, new_month, new_day)
207
-
208
- def future_month(self, months=1):
209
- """
210
- 获取未来的月份
211
-
212
- Args:
213
- months (int): 往后推的月份数,默认为1
214
-
215
- Returns:
216
- Date: 新的Date对象,表示未来指定月份的日期
217
- """
218
- if not isinstance(months, int) or months < 0:
219
- raise ValueError("Months must be a non-negative integer")
220
-
221
- # 计算新的年份和月份
222
- new_year = self.year
223
- new_month = self.month + months
224
-
225
- # 处理月份跨年的情况
226
- while new_month > 12:
227
- new_month -= 12
228
- new_year += 1
229
-
230
- # 处理日期可能超出目标月份天数的情况
231
- new_day = self._adjust_day_for_month(new_year, new_month, self.day)
232
-
233
- return Date(new_year, new_month, new_day)
234
-
235
- def _adjust_day_for_month(self, year, month, day):
236
- """
237
- 调整日期以适应目标月份的天数
238
-
239
- Args:
240
- year (int): 目标年份
241
- month (int): 目标月份
242
- day (int): 原始日期
243
-
244
- Returns:
245
- int: 调整后的日期
246
- """
247
- # 获取目标月份的天数
248
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
249
-
250
- # 检查闰年
251
- if self._is_leap_year(year):
252
- days_in_month[1] = 29
253
-
254
- max_day = days_in_month[month - 1]
255
-
256
- # 如果原日期超过目标月份的最大天数,则使用目标月份的最后一天
257
- return min(day, max_day)
258
-
259
- def past_year(self, years=1):
260
- """
261
- 获取过去的年份
262
-
263
- Args:
264
- years (int): 往前推的年份数,默认为1
265
-
266
- Returns:
267
- Date: 新的Date对象,表示过去指定年份的日期
268
- """
269
- if not isinstance(years, int) or years < 0:
270
- raise ValueError("Years must be a non-negative integer")
271
-
272
- new_year = self.year - years
273
- new_month = self.month
274
- new_day = self.day
275
-
276
- # 处理2月29日在非闰年的情况
277
- if new_month == 2 and new_day == 29 and not self._is_leap_year(new_year):
278
- new_day = 28
279
-
280
- return Date(new_year, new_month, new_day)
281
-
282
- def future_year(self, years=1):
283
- """
284
- 获取未来的年份
285
-
286
- Args:
287
- years (int): 往后推的年份数,默认为1
288
-
289
- Returns:
290
- Date: 新的Date对象,表示未来指定年份的日期
291
- """
292
- if not isinstance(years, int) or years < 0:
293
- raise ValueError("Years must be a non-negative integer")
294
-
295
- new_year = self.year + years
296
- new_month = self.month
297
- new_day = self.day
298
-
299
- # 处理2月29日在非闰年的情况
300
- if new_month == 2 and new_day == 29 and not self._is_leap_year(new_year):
301
- new_day = 28
302
-
303
- return Date(new_year, new_month, new_day)
304
-
305
- def past_day(self, days=1):
306
- """
307
- 获取过去的天数
308
-
309
- Args:
310
- days (int): 往前推的天数,默认为1
311
-
312
- Returns:
313
- Date: 新的Date对象,表示过去指定天数的日期
314
- """
315
- if not isinstance(days, int) or days < 0:
316
- raise ValueError("Days must be a non-negative integer")
317
-
318
- # 使用纯算法计算
319
- new_year = self.year
320
- new_month = self.month
321
- new_day = self.day - days
322
-
323
- # 处理日期减法跨月的情况
324
- while new_day <= 0:
325
- new_month -= 1
326
- if new_month <= 0:
327
- new_month = 12
328
- new_year -= 1
329
-
330
- # 获取新月份的天数
331
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
332
- if self._is_leap_year(new_year):
333
- days_in_month[1] = 29
334
-
335
- new_day += days_in_month[new_month - 1]
336
-
337
- return Date(new_year, new_month, new_day)
338
-
339
- def future_day(self, days=1):
340
- """
341
- 获取未来的天数
342
-
343
- Args:
344
- days (int): 往后推的天数,默认为1
345
-
346
- Returns:
347
- Date: 新的Date对象,表示未来指定天数的日期
348
- """
349
- if not isinstance(days, int) or days < 0:
350
- raise ValueError("Days must be a non-negative integer")
351
-
352
- # 使用纯算法计算
353
- new_year = self.year
354
- new_month = self.month
355
- new_day = self.day + days
356
-
357
- # 处理日期加法跨月的情况
358
- while True:
359
- # 获取当前月份的天数
360
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
361
- if self._is_leap_year(new_year):
362
- days_in_month[1] = 29
363
-
364
- max_day = days_in_month[new_month - 1]
365
-
366
- if new_day <= max_day:
367
- break
368
-
369
- new_day -= max_day
370
- new_month += 1
371
-
372
- if new_month > 12:
373
- new_month = 1
374
- new_year += 1
375
-
376
- return Date(new_year, new_month, new_day)
377
-
378
- def past_week(self, weeks=1):
379
- """
380
- 获取过去的周数
381
-
382
- Args:
383
- weeks (int): 往前推的周数,默认为1
384
-
385
- Returns:
386
- Date: 新的Date对象,表示过去指定周数的日期
387
- """
388
- if not isinstance(weeks, int) or weeks < 0:
389
- raise ValueError("Weeks must be a non-negative integer")
390
-
391
- return self.past_day(weeks * 7)
392
-
393
- def future_week(self, weeks=1):
394
- """
395
- 获取未来的周数
396
-
397
- Args:
398
- weeks (int): 往后推的周数,默认为1
399
-
400
- Returns:
401
- Date: 新的Date对象,表示未来指定周数的日期
402
- """
403
- if not isinstance(weeks, int) or weeks < 0:
404
- raise ValueError("Weeks must be a non-negative integer")
405
-
406
- return self.future_day(weeks * 7)
407
-
408
- def add_years(self, years):
409
- """
410
- 智能年份操作:根据正负值自动判断增加或减少年份
411
-
412
- Args:
413
- years (int): 年份数,正数表示未来,负数表示过去,0表示不变
414
-
415
- Returns:
416
- Date: 新的Date对象
417
- """
418
- if not isinstance(years, int):
419
- raise ValueError("Years must be an integer")
420
-
421
- if years == 0:
422
- return Date(self.year, self.month, self.day)
423
- elif years > 0:
424
- return self.future_year(years)
425
- else:
426
- return self.past_year(abs(years))
427
-
428
- def add_months(self, months):
429
- """
430
- 智能月份操作:根据正负值自动判断增加或减少月份
431
-
432
- Args:
433
- months (int): 月份数,正数表示未来,负数表示过去,0表示不变
434
-
435
- Returns:
436
- Date: 新的Date对象
437
- """
438
- if not isinstance(months, int):
439
- raise ValueError("Months must be an integer")
440
-
441
- if months == 0:
442
- return Date(self.year, self.month, self.day)
443
- elif months > 0:
444
- return self.future_month(months)
445
- else:
446
- return self.past_month(abs(months))
447
-
448
- def add_weeks(self, weeks):
449
- """
450
- 智能周数操作:根据正负值自动判断增加或减少周数
451
-
452
- Args:
453
- weeks (int): 周数,正数表示未来,负数表示过去,0表示不变
454
-
455
- Returns:
456
- Date: 新的Date对象
457
- """
458
- if not isinstance(weeks, int):
459
- raise ValueError("Weeks must be an integer")
460
-
461
- if weeks == 0:
462
- return Date(self.year, self.month, self.day)
463
- elif weeks > 0:
464
- return self.future_week(weeks)
465
- else:
466
- return self.past_week(abs(weeks))
467
-
468
- def add_days(self, days):
469
- """
470
- 智能天数操作:根据正负值自动判断增加或减少天数
471
-
472
- Args:
473
- days (int): 天数,正数表示未来,负数表示过去,0表示不变
474
-
475
- Returns:
476
- Date: 新的Date对象
477
- """
478
- if not isinstance(days, int):
479
- raise ValueError("Days must be an integer")
480
-
481
- if days == 0:
482
- return Date(self.year, self.month, self.day)
483
- elif days > 0:
484
- return self.future_day(days)
485
- else:
486
- return self.past_day(abs(days))
487
-
488
- def delta(self, years=0, months=0, weeks=0, days=0):
489
- """
490
- 组合时间操作:同时处理年、月、周、天的增减
491
-
492
- Args:
493
- years (int): 年份增减数,默认为0
494
- months (int): 月份增减数,默认为0
495
- weeks (int): 周数增减数,默认为0
496
- days (int): 天数增减数,默认为0
497
-
498
- Returns:
499
- Date: 新的Date对象
500
- """
501
- # 按顺序应用操作:年 → 月 → 周 → 天
502
- result = self.add_years(years)
503
- result = result.add_months(months)
504
- result = result.add_weeks(weeks)
505
- result = result.add_days(days)
506
-
507
- return result
508
-
509
- # ==================== 日期比较方法 ====================
510
-
511
- def days_between(self, other_date):
512
- """
513
- 计算两个日期之间的天数差
514
-
515
- Args:
516
- other_date (Date): 另一个日期对象
517
-
518
- Returns:
519
- int: 天数差,正数表示other_date在未来,负数表示在过去
520
- """
521
- if not isinstance(other_date, Date):
522
- raise ValueError("other_date must be a Date object")
523
-
524
- # 将日期转换为从公元1年1月1日开始的天数
525
- def date_to_days(date):
526
- total_days = 0
527
-
528
- # 加上年份的天数
529
- for year in range(1, date.year):
530
- if self._is_leap_year(year):
531
- total_days += 366
532
- else:
533
- total_days += 365
534
-
535
- # 加上月份的天数
536
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
537
- if self._is_leap_year(date.year):
538
- days_in_month[1] = 29
539
-
540
- for month in range(1, date.month):
541
- total_days += days_in_month[month - 1]
542
-
543
- # 加上天数
544
- total_days += date.day
545
-
546
- return total_days
547
-
548
- days1 = date_to_days(self)
549
- days2 = date_to_days(other_date)
550
-
551
- return days2 - days1
552
-
553
- def is_before(self, other_date):
554
- """判断是否在另一个日期之前"""
555
- return self.days_between(other_date) > 0
556
-
557
- def is_after(self, other_date):
558
- """判断是否在另一个日期之后"""
559
- return self.days_between(other_date) < 0
560
-
561
- def is_same(self, other_date):
562
- """判断是否是同一天"""
563
- return self.days_between(other_date) == 0
564
-
565
- # ==================== 日期信息查询方法 ====================
566
-
567
- def weekday(self):
568
- """
569
- 获取星期几
570
-
571
- Returns:
572
- int: 0=周一, 1=周二, ..., 6=周日
573
- """
574
- # 使用 Zeller 公式计算星期几
575
- # 将1月和2月看作上一年的13月和14月
576
- if self.month < 3:
577
- month = self.month + 12
578
- year = self.year - 1
579
- else:
580
- month = self.month
581
- year = self.year
582
-
583
- # Zeller公式
584
- h = (self.day + (13 * (month + 1)) // 5 + year + year // 4 - year // 100 + year // 400) % 7
585
-
586
- # 转换为周一=0的格式 (Zeller公式中: 0=周六, 1=周日, 2=周一...)
587
- return (h + 5) % 7
588
-
589
- def weekday_name(self, lang='zh'):
590
- """
591
- 获取星期几的名称
592
-
593
- Args:
594
- lang (str): 语言,'zh'=中文, 'en'=英文
595
-
596
- Returns:
597
- str: 星期几的名称
598
- """
599
- weekday_names = {
600
- 'zh': ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
601
- 'en': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
602
- }
603
- return weekday_names.get(lang, weekday_names['zh'])[self.weekday()]
604
-
605
- def month_name(self, lang='zh'):
606
- """
607
- 获取月份名称
608
-
609
- Args:
610
- lang (str): 语言,'zh'=中文, 'en'=英文
611
-
612
- Returns:
613
- str: 月份名称
614
- """
615
- month_names = {
616
- 'zh': ['一月', '二月', '三月', '四月', '五月', '六月',
617
- '七月', '八月', '九月', '十月', '十一月', '十二月'],
618
- 'en': ['January', 'February', 'March', 'April', 'May', 'June',
619
- 'July', 'August', 'September', 'October', 'November', 'December']
620
- }
621
- return month_names.get(lang, month_names['zh'])[self.month - 1]
622
-
623
- def quarter(self):
624
- """
625
- 获取季度
626
-
627
- Returns:
628
- int: 季度 (1-4)
629
- """
630
- return (self.month - 1) // 3 + 1
631
-
632
- def day_of_year(self):
633
- """
634
- 获取一年中的第几天
635
-
636
- Returns:
637
- int: 一年中的第几天 (1-366)
638
- """
639
- # 每月天数
640
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
641
-
642
- # 检查闰年
643
- if self._is_leap_year(self.year):
644
- days_in_month[1] = 29
645
-
646
- # 累加前面月份的天数,再加上当前月的天数
647
- total_days = sum(days_in_month[:self.month - 1]) + self.day
648
-
649
- return total_days
650
-
651
- def week_of_year(self):
652
- """
653
- 获取一年中的第几周
654
-
655
- Returns:
656
- int: 一年中的第几周
657
- """
658
- # 计算1月1日是星期几
659
- jan_1 = Date(self.year, 1, 1)
660
- jan_1_weekday = jan_1.weekday()
661
-
662
- # 计算当前日期是一年中的第几天
663
- day_of_year = self.day_of_year()
664
-
665
- # 计算第一周的天数(1月1日到第一个周日的天数)
666
- # 如果1月1日是周一(0),第一周有7天
667
- # 如果1月1日是周二(1),第一周有6天,以此类推
668
- first_week_days = 7 - jan_1_weekday
669
-
670
- if day_of_year <= first_week_days:
671
- return 1
672
- else:
673
- # 减去第一周的天数,然后除以7,再加1
674
- return ((day_of_year - first_week_days - 1) // 7) + 2
675
-
676
- # ==================== 特殊日期判断方法 ====================
677
-
678
- def is_weekend(self):
679
- """判断是否是周末"""
680
- return self.weekday() >= 5 # 周六(5)或周日(6)
681
-
682
- def is_leap_year_date(self):
683
- """判断当前日期所在年份是否是闰年"""
684
- return self._is_leap_year(self.year)
685
-
686
- def is_month_end(self):
687
- """判断是否是月末"""
688
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
689
- if self._is_leap_year(self.year):
690
- days_in_month[1] = 29
691
- return self.day == days_in_month[self.month - 1]
692
-
693
- def is_quarter_end(self):
694
- """判断是否是季度末"""
695
- return self.month in [3, 6, 9, 12] and self.is_month_end()
696
-
697
- def is_year_end(self):
698
- """判断是否是年末"""
699
- return self.month == 12 and self.day == 31
700
-
701
- # ==================== 日期边界方法 ====================
702
-
703
- def start_of_month(self):
704
- """获取当月第一天"""
705
- return Date(self.year, self.month, 1)
706
-
707
- def end_of_month(self):
708
- """获取当月最后一天"""
709
- days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
710
- if self._is_leap_year(self.year):
711
- days_in_month[1] = 29
712
- last_day = days_in_month[self.month - 1]
713
- return Date(self.year, self.month, last_day)
714
-
715
- def start_of_year(self):
716
- """获取当年第一天"""
717
- return Date(self.year, 1, 1)
718
-
719
- def end_of_year(self):
720
- """获取当年最后一天"""
721
- return Date(self.year, 12, 31)
722
-
723
- def start_of_quarter(self):
724
- """获取当季度第一天"""
725
- quarter_start_months = [1, 4, 7, 10]
726
- quarter_month = quarter_start_months[self.quarter() - 1]
727
- return Date(self.year, quarter_month, 1)
728
-
729
- def end_of_quarter(self):
730
- """获取当季度最后一天"""
731
- quarter_end_months = [3, 6, 9, 12]
732
- quarter_month = quarter_end_months[self.quarter() - 1]
733
- return Date(self.year, quarter_month, 1).end_of_month()
734
-
735
- # ==================== 格式化和转换方法 ====================
736
-
737
- def to_dict(self):
738
- """
739
- 转换为字典格式
740
-
741
- Returns:
742
- dict: 包含年、月、日的字典
743
- """
744
- return {
745
- 'year': self.year,
746
- 'month': self.month,
747
- 'day': self.day
748
- }
749
-
750
- def to_tuple(self):
751
- """
752
- 转换为元组格式
753
-
754
- Returns:
755
- tuple: (年, 月, 日)
756
- """
757
- return (self.year, self.month, self.day)
758
-
759
- def format(self, format_string):
760
- """
761
- 自定义格式化
762
-
763
- Args:
764
- format_string (str): 格式字符串
765
- 支持: %Y(年), %m(月), %d(日), %M(月名), %W(星期)
766
-
767
- Returns:
768
- str: 格式化后的字符串
769
- """
770
- result = format_string
771
- result = result.replace('%Y', f'{self.year:04d}')
772
- result = result.replace('%m', f'{self.month:02d}')
773
- result = result.replace('%d', f'{self.day:02d}')
774
- result = result.replace('%M', self.month_name())
775
- result = result.replace('%W', self.weekday_name())
776
- return result
777
-
778
- def to_iso_string(self):
779
- """转换为ISO格式字符串"""
780
- return f"{self.year:04d}-{self.month:02d}-{self.day:02d}"
781
-
782
- def to_timestamp(self):
783
- """
784
- 转换为时间戳
785
-
786
- Returns:
787
- float: Unix时间戳
788
- """
789
- try:
790
- from . import platform_utils
791
- return platform_utils.date_to_timestamp(self.year, self.month, self.day)
792
- except (ImportError, AttributeError):
793
- # 回退到datetime实现
794
- import datetime
795
- date = datetime.date(self.year, self.month, self.day)
796
- dt = datetime.datetime.combine(date, datetime.time())
797
- return dt.timestamp()
798
-
799
- # ==================== 魔术方法支持 ====================
800
-
801
- def __eq__(self, other):
802
- """支持 == 比较"""
803
- if not isinstance(other, Date):
804
- return False
805
- return self.year == other.year and self.month == other.month and self.day == other.day
806
-
807
- def __lt__(self, other):
808
- """支持 < 比较"""
809
- if not isinstance(other, Date):
810
- raise TypeError("Cannot compare Date with non-Date object")
811
- return self.days_between(other) > 0
812
-
813
- def __le__(self, other):
814
- """支持 <= 比较"""
815
- return self < other or self == other
816
-
817
- def __gt__(self, other):
818
- """支持 > 比较"""
819
- if not isinstance(other, Date):
820
- raise TypeError("Cannot compare Date with non-Date object")
821
- return self.days_between(other) < 0
822
-
823
- def __ge__(self, other):
824
- """支持 >= 比较"""
825
- return self > other or self == other
826
-
827
- def __ne__(self, other):
828
- """支持 != 比较"""
829
- return not self == other
830
-
831
- def __sub__(self, other):
832
- """支持日期相减,返回天数差"""
833
- if isinstance(other, Date):
834
- return abs(self.days_between(other))
835
- elif isinstance(other, int):
836
- return self.add_days(-other)
837
- else:
838
- raise TypeError("Cannot subtract non-Date/int from Date")
839
-
840
- def __add__(self, other):
841
- """支持日期加天数"""
842
- if isinstance(other, int):
843
- return self.add_days(other)
844
- else:
845
- raise TypeError("Cannot add non-int to Date")
846
-
847
- def __hash__(self):
848
- """支持作为字典键和集合元素"""
849
- return hash((self.year, self.month, self.day))
850
-
851
- def __repr__(self):
852
- """更详细的字符串表示"""
853
- return f"Date({self.year}, {self.month}, {self.day})"
854
-
855
- # 返回日期的字符串表示,格式为 'YYYY-MM-DD'
856
- def __str__(self):
857
- return f"{self.year:04d}-{self.month:02d}-{self.day:02d}"