dateflow 0.1.1__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.
- dateflow/__init__.py +75 -0
- dateflow/_utils.py +1 -0
- dateflow/easter.py +60 -0
- dateflow/parser.py +875 -0
- dateflow/py.typed +0 -0
- dateflow/relativedelta.py +507 -0
- dateflow/rrule.py +1045 -0
- dateflow/tz.py +337 -0
- dateflow-0.1.1.dist-info/METADATA +412 -0
- dateflow-0.1.1.dist-info/RECORD +12 -0
- dateflow-0.1.1.dist-info/WHEEL +4 -0
- dateflow-0.1.1.dist-info/licenses/LICENSE +21 -0
dateflow/__init__.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""dateflow — A zero-dependency, modern Python replacement for python-dateutil."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
from dateflow.relativedelta import (
|
|
6
|
+
MO,
|
|
7
|
+
TU,
|
|
8
|
+
WE,
|
|
9
|
+
TH,
|
|
10
|
+
FR,
|
|
11
|
+
SA,
|
|
12
|
+
SU,
|
|
13
|
+
relativedelta,
|
|
14
|
+
weekday,
|
|
15
|
+
)
|
|
16
|
+
from dateflow.easter import easter
|
|
17
|
+
from dateflow.parser import ParserError, isoparse, parse
|
|
18
|
+
from dateflow.rrule import (
|
|
19
|
+
YEARLY,
|
|
20
|
+
MONTHLY,
|
|
21
|
+
WEEKLY,
|
|
22
|
+
DAILY,
|
|
23
|
+
HOURLY,
|
|
24
|
+
MINUTELY,
|
|
25
|
+
SECONDLY,
|
|
26
|
+
rrule,
|
|
27
|
+
rruleset,
|
|
28
|
+
rrulestr,
|
|
29
|
+
)
|
|
30
|
+
from dateflow.tz import (
|
|
31
|
+
UTC,
|
|
32
|
+
gettz,
|
|
33
|
+
tzoffset,
|
|
34
|
+
tzutc,
|
|
35
|
+
tzlocal,
|
|
36
|
+
enfold,
|
|
37
|
+
resolve_imaginary,
|
|
38
|
+
datetime_exists,
|
|
39
|
+
datetime_ambiguous,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
"relativedelta",
|
|
44
|
+
"weekday",
|
|
45
|
+
"MO",
|
|
46
|
+
"TU",
|
|
47
|
+
"WE",
|
|
48
|
+
"TH",
|
|
49
|
+
"FR",
|
|
50
|
+
"SA",
|
|
51
|
+
"SU",
|
|
52
|
+
"easter",
|
|
53
|
+
"parse",
|
|
54
|
+
"isoparse",
|
|
55
|
+
"ParserError",
|
|
56
|
+
"UTC",
|
|
57
|
+
"gettz",
|
|
58
|
+
"tzoffset",
|
|
59
|
+
"tzutc",
|
|
60
|
+
"tzlocal",
|
|
61
|
+
"enfold",
|
|
62
|
+
"resolve_imaginary",
|
|
63
|
+
"datetime_exists",
|
|
64
|
+
"datetime_ambiguous",
|
|
65
|
+
"YEARLY",
|
|
66
|
+
"MONTHLY",
|
|
67
|
+
"WEEKLY",
|
|
68
|
+
"DAILY",
|
|
69
|
+
"HOURLY",
|
|
70
|
+
"MINUTELY",
|
|
71
|
+
"SECONDLY",
|
|
72
|
+
"rrule",
|
|
73
|
+
"rruleset",
|
|
74
|
+
"rrulestr",
|
|
75
|
+
]
|
dateflow/_utils.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Internal helpers for dateflow."""
|
dateflow/easter.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Easter date computation — replaces dateutil.easter.
|
|
2
|
+
|
|
3
|
+
Algorithm ported from GM Arts / Claus Tondering / Ouding (1940),
|
|
4
|
+
as quoted in "Explanatory Supplement to the Astronomical Almanac".
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from datetime import date
|
|
10
|
+
|
|
11
|
+
# Method constants
|
|
12
|
+
EASTER_JULIAN = 1
|
|
13
|
+
EASTER_ORTHODOX = 2
|
|
14
|
+
EASTER_WESTERN = 3
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def easter(year: int, method: int = EASTER_WESTERN) -> date:
|
|
18
|
+
"""Compute the date of Easter Sunday for a given year.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
year: The year (1-9999).
|
|
22
|
+
method: One of EASTER_WESTERN (default, Gregorian calendar),
|
|
23
|
+
EASTER_ORTHODOX (Julian algorithm, Gregorian date),
|
|
24
|
+
or EASTER_JULIAN (Julian calendar date).
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
A datetime.date for Easter Sunday.
|
|
28
|
+
"""
|
|
29
|
+
if not 1 <= year <= 9999:
|
|
30
|
+
raise ValueError(f"year must be between 1 and 9999, got {year}")
|
|
31
|
+
|
|
32
|
+
if method not in (EASTER_JULIAN, EASTER_ORTHODOX, EASTER_WESTERN):
|
|
33
|
+
raise ValueError(f"invalid method: {method}")
|
|
34
|
+
|
|
35
|
+
y = year
|
|
36
|
+
g = y % 19
|
|
37
|
+
e = 0
|
|
38
|
+
|
|
39
|
+
if method < 3:
|
|
40
|
+
# Julian-based methods (EASTER_JULIAN and EASTER_ORTHODOX)
|
|
41
|
+
i = (19 * g + 15) % 30
|
|
42
|
+
j = (y + y // 4 + i) % 7
|
|
43
|
+
if method == 2:
|
|
44
|
+
# Convert Julian date to Gregorian by adding offset
|
|
45
|
+
e = 10
|
|
46
|
+
if y > 1600:
|
|
47
|
+
e = e + y // 100 - 16 - (y // 100 - 16) // 4
|
|
48
|
+
else:
|
|
49
|
+
# Western/Gregorian method
|
|
50
|
+
c = y // 100
|
|
51
|
+
h = (c - c // 4 - (8 * c + 13) // 25 + 19 * g + 15) % 30
|
|
52
|
+
i = h - (h // 28) * (1 - (h // 28) * (29 // (h + 1)) * ((21 - g) // 11))
|
|
53
|
+
j = (y + y // 4 + i + 2 - c + c // 4) % 7
|
|
54
|
+
|
|
55
|
+
# p can be from -6 to 56 corresponding to dates 22 March to 23 May
|
|
56
|
+
p = i - j + e
|
|
57
|
+
d = 1 + (p + 27 + (p + 6) // 40) % 31
|
|
58
|
+
m = 3 + (p + 26) // 30
|
|
59
|
+
|
|
60
|
+
return date(y, m, d)
|