opendate 0.1.9__py3-none-any.whl → 0.1.11__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.
Potentially problematic release.
This version of opendate might be problematic. Click here for more details.
- date/__init__.py +24 -19
- date/date.py +51 -23
- {opendate-0.1.9.dist-info → opendate-0.1.11.dist-info}/METADATA +1 -1
- opendate-0.1.11.dist-info/RECORD +7 -0
- opendate-0.1.9.dist-info/RECORD +0 -7
- {opendate-0.1.9.dist-info → opendate-0.1.11.dist-info}/LICENSE +0 -0
- {opendate-0.1.9.dist-info → opendate-0.1.11.dist-info}/WHEEL +0 -0
date/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = '0.1.
|
|
1
|
+
__version__ = '0.1.11'
|
|
2
2
|
|
|
3
3
|
import datetime as _datetime
|
|
4
4
|
|
|
@@ -51,6 +51,10 @@ def time(*args, **kwargs):
|
|
|
51
51
|
return Time(*args, **kwargs)
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def interval(*args, **kwargs):
|
|
55
|
+
return Interval(*args, **kwargs)
|
|
56
|
+
|
|
57
|
+
|
|
54
58
|
def parse(s: str | None, fmt: str = None, entity: Entity = NYSE, raise_err: bool = False) -> DateTime | None:
|
|
55
59
|
"""Parse using DateTime.parse
|
|
56
60
|
"""
|
|
@@ -60,14 +64,13 @@ def parse(s: str | None, fmt: str = None, entity: Entity = NYSE, raise_err: bool
|
|
|
60
64
|
def instance(obj: _datetime.date | _datetime.datetime | _datetime.time) -> DateTime | Date | Time:
|
|
61
65
|
"""Create a DateTime/Date/Time instance from a datetime/date/time native one.
|
|
62
66
|
"""
|
|
63
|
-
if isinstance(obj, DateTime | Date | Time):
|
|
64
|
-
return obj
|
|
65
67
|
if isinstance(obj, _datetime.date) and not isinstance(obj, _datetime.datetime):
|
|
66
68
|
return Date.instance(obj)
|
|
67
69
|
if isinstance(obj, _datetime.time):
|
|
68
70
|
return Time.instance(obj)
|
|
69
71
|
if isinstance(obj, _datetime.datetime):
|
|
70
72
|
return DateTime.instance(obj)
|
|
73
|
+
raise ValueError(f'opendate `instance` helper cannot parse type {type(obj)}')
|
|
71
74
|
|
|
72
75
|
|
|
73
76
|
def now(tz: str | _zoneinfo.ZoneInfo | None = None) -> DateTime:
|
|
@@ -84,28 +87,30 @@ def today(tz: str | _zoneinfo.ZoneInfo = None) -> DateTime:
|
|
|
84
87
|
|
|
85
88
|
__all__ = [
|
|
86
89
|
'Date',
|
|
90
|
+
'date',
|
|
87
91
|
'DateTime',
|
|
92
|
+
'datetime',
|
|
93
|
+
'Entity',
|
|
94
|
+
'expect_date',
|
|
95
|
+
'expect_datetime',
|
|
96
|
+
'expect_native_timezone',
|
|
97
|
+
'expect_utc_timezone',
|
|
98
|
+
'instance',
|
|
88
99
|
'Interval',
|
|
100
|
+
'interval',
|
|
89
101
|
'IntervalError',
|
|
90
|
-
'
|
|
91
|
-
'
|
|
102
|
+
'is_business_day',
|
|
103
|
+
'is_within_business_hours',
|
|
104
|
+
'LCL',
|
|
92
105
|
'now',
|
|
93
|
-
'
|
|
106
|
+
'NYSE',
|
|
107
|
+
'overlap_days',
|
|
94
108
|
'parse',
|
|
95
|
-
'LCL',
|
|
96
|
-
'timezone',
|
|
97
|
-
'expect_native_timezone',
|
|
98
|
-
'expect_utc_timezone',
|
|
99
109
|
'prefer_native_timezone',
|
|
100
110
|
'prefer_utc_timezone',
|
|
101
|
-
'
|
|
102
|
-
'expect_datetime',
|
|
103
|
-
'Entity',
|
|
104
|
-
'NYSE',
|
|
105
|
-
'date',
|
|
106
|
-
'datetime',
|
|
111
|
+
'Time',
|
|
107
112
|
'time',
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
'
|
|
113
|
+
'timezone',
|
|
114
|
+
'today',
|
|
115
|
+
'WeekDay',
|
|
111
116
|
]
|
date/date.py
CHANGED
|
@@ -787,8 +787,18 @@ class Date(DateExtrasMixin, DateBusinessMixin, _pendulum.Date):
|
|
|
787
787
|
raise TypeError(f'Invalid type for date parse: {s.__class__}')
|
|
788
788
|
|
|
789
789
|
if fmt:
|
|
790
|
-
|
|
790
|
+
try:
|
|
791
791
|
return cls(*time.strptime(s, fmt)[:3])
|
|
792
|
+
except:
|
|
793
|
+
if raise_err:
|
|
794
|
+
raise ValueError(f'Unable to parse {s} using fmt {fmt}')
|
|
795
|
+
return
|
|
796
|
+
|
|
797
|
+
with contextlib.suppress(ValueError):
|
|
798
|
+
if float(s) and not len(s) == 8: # 20000101
|
|
799
|
+
if raise_err:
|
|
800
|
+
raise ValueError('Invalid date: %s', s)
|
|
801
|
+
return
|
|
792
802
|
|
|
793
803
|
# special shortcode symbolic values: T, Y-2, P-1b
|
|
794
804
|
if m := DATEMATCH.match(s):
|
|
@@ -810,7 +820,7 @@ class Date(DateExtrasMixin, DateBusinessMixin, _pendulum.Date):
|
|
|
810
820
|
return cls.today().subtract(days=1)
|
|
811
821
|
|
|
812
822
|
with contextlib.suppress(TypeError, ValueError):
|
|
813
|
-
return cls.instance(_dateutil.parser.parse(s)
|
|
823
|
+
return cls.instance(_dateutil.parser.parse(s))
|
|
814
824
|
|
|
815
825
|
# Regex with Month Numbers
|
|
816
826
|
exps = (
|
|
@@ -1010,7 +1020,12 @@ class Time(_pendulum.Time):
|
|
|
1010
1020
|
raise TypeError(f'Invalid type for time parse: {s.__class__}')
|
|
1011
1021
|
|
|
1012
1022
|
if fmt:
|
|
1013
|
-
|
|
1023
|
+
try:
|
|
1024
|
+
return cls(*time.strptime(s, fmt)[3:6])
|
|
1025
|
+
except:
|
|
1026
|
+
if raise_err:
|
|
1027
|
+
raise ValueError(f'Unable to parse {s} using fmt {fmt}')
|
|
1028
|
+
return
|
|
1014
1029
|
|
|
1015
1030
|
exps = (
|
|
1016
1031
|
r'^(?P<h>\d{1,2})[:.](?P<m>\d{2})([:.](?P<s>\d{2})([.,](?P<u>\d+))?)?( +(?P<ap>[aApP][mM]))?$',
|
|
@@ -1028,7 +1043,7 @@ class Time(_pendulum.Time):
|
|
|
1028
1043
|
return cls(hh, mm, ss, uu * 1000)
|
|
1029
1044
|
|
|
1030
1045
|
with contextlib.suppress(TypeError, ValueError):
|
|
1031
|
-
return cls.instance(_dateutil.parser.parse(s)
|
|
1046
|
+
return cls.instance(_dateutil.parser.parse(s))
|
|
1032
1047
|
|
|
1033
1048
|
if raise_err:
|
|
1034
1049
|
raise ValueError('Failed to parse time: %s', s)
|
|
@@ -1177,7 +1192,7 @@ class DateTime(DateBusinessMixin, _pendulum.DateTime):
|
|
|
1177
1192
|
UTC time technically equals GMT
|
|
1178
1193
|
>>> this_utc = DateTime.parse('Fri, 31 Oct 2014 18:55:00 GMT')
|
|
1179
1194
|
>>> this_utc
|
|
1180
|
-
DateTime(2014, 10, 31, 18, 55, 0, tzinfo=
|
|
1195
|
+
DateTime(2014, 10, 31, 18, 55, 0, tzinfo=tzutc())
|
|
1181
1196
|
|
|
1182
1197
|
We can freely compare time zones
|
|
1183
1198
|
>>> this_est1==this_est2==this_utc
|
|
@@ -1205,8 +1220,7 @@ class DateTime(DateBusinessMixin, _pendulum.DateTime):
|
|
|
1205
1220
|
return cls.parse(iso).replace(tzinfo=LCL)
|
|
1206
1221
|
|
|
1207
1222
|
with contextlib.suppress(ValueError, TypeError):
|
|
1208
|
-
|
|
1209
|
-
return cls.instance(_pendulum.instance(obj))
|
|
1223
|
+
return cls.instance(_dateutil.parser.parse(s))
|
|
1210
1224
|
|
|
1211
1225
|
for delim in (' ', ':'):
|
|
1212
1226
|
bits = s.split(delim, 1)
|
|
@@ -1356,12 +1370,29 @@ class Interval:
|
|
|
1356
1370
|
set - set end=beg + num
|
|
1357
1371
|
- set set beg=end - num
|
|
1358
1372
|
|
|
1359
|
-
|
|
1373
|
+
Basic/legacy cases
|
|
1374
|
+
>>> Interval(Date(2014, 4, 3), None).b.range(3)
|
|
1360
1375
|
(Date(2014, 4, 3), Date(2014, 4, 8))
|
|
1361
1376
|
>>> Interval(None, Date(2014, 7, 27)).range(20)
|
|
1362
1377
|
(Date(2014, 7, 7), Date(2014, 7, 27))
|
|
1363
|
-
>>> Interval(None,
|
|
1378
|
+
>>> Interval(None, Date(2014, 7, 27)).b.range(20)
|
|
1364
1379
|
(Date(2014, 6, 27), Date(2014, 7, 27))
|
|
1380
|
+
|
|
1381
|
+
Do not modify dates if both are provided
|
|
1382
|
+
>>> Interval(Date(2024, 7, 25), Date(2024, 7, 25)).b.range(None)
|
|
1383
|
+
(Date(2024, 7, 25), Date(2024, 7, 25))
|
|
1384
|
+
>>> Interval(Date(2024, 7, 27), Date(2024, 7, 27)).b.range(None)
|
|
1385
|
+
(Date(2024, 7, 27), Date(2024, 7, 27))
|
|
1386
|
+
|
|
1387
|
+
Edge cases (7/27/24 is weekend)
|
|
1388
|
+
>>> Interval(Date(2024, 7, 27), None).b.range(0)
|
|
1389
|
+
(Date(2024, 7, 27), Date(2024, 7, 27))
|
|
1390
|
+
>>> Interval(None, Date(2024, 7, 27)).b.range(0)
|
|
1391
|
+
(Date(2024, 7, 27), Date(2024, 7, 27))
|
|
1392
|
+
>>> Interval(Date(2024, 7, 27), None).b.range(1)
|
|
1393
|
+
(Date(2024, 7, 27), Date(2024, 7, 29))
|
|
1394
|
+
>>> Interval(None, Date(2024, 7, 27)).b.range(1)
|
|
1395
|
+
(Date(2024, 7, 26), Date(2024, 7, 27))
|
|
1365
1396
|
"""
|
|
1366
1397
|
begdate, enddate = self.begdate, self.enddate
|
|
1367
1398
|
|
|
@@ -1375,17 +1406,14 @@ class Interval:
|
|
|
1375
1406
|
raise IntervalError('Missing begdate and enddate, window specified')
|
|
1376
1407
|
|
|
1377
1408
|
if begdate and enddate:
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
enddate).subtract(days=0)
|
|
1382
|
-
|
|
1383
|
-
if (not begdate and not enddate) or enddate:
|
|
1384
|
-
begdate = (enddate.business() if enddate._business else
|
|
1385
|
-
enddate).subtract(days=window)
|
|
1409
|
+
pass # do nothing if both provided
|
|
1410
|
+
elif (not begdate and not enddate) or enddate:
|
|
1411
|
+
begdate = enddate.subtract(days=window) if window else enddate
|
|
1386
1412
|
else:
|
|
1387
|
-
enddate =
|
|
1388
|
-
|
|
1413
|
+
enddate = begdate.add(days=window) if window else begdate
|
|
1414
|
+
|
|
1415
|
+
enddate._business = False
|
|
1416
|
+
begdate._business = False
|
|
1389
1417
|
|
|
1390
1418
|
return begdate, enddate
|
|
1391
1419
|
|
|
@@ -1491,13 +1519,13 @@ class Interval:
|
|
|
1491
1519
|
def days(self) -> int:
|
|
1492
1520
|
"""Return days between (begdate, enddate] or negative (enddate, begdate].
|
|
1493
1521
|
|
|
1494
|
-
>>> Interval(Date
|
|
1522
|
+
>>> Interval(Date(2018, 9, 6), Date(2018, 9, 10)).days()
|
|
1495
1523
|
4
|
|
1496
|
-
>>> Interval(Date
|
|
1524
|
+
>>> Interval(Date(2018, 9, 10), Date(2018, 9, 6)).days()
|
|
1497
1525
|
-4
|
|
1498
|
-
>>> Interval(Date
|
|
1526
|
+
>>> Interval(Date(2018, 9, 6), Date(2018, 9, 10)).b.days()
|
|
1499
1527
|
2
|
|
1500
|
-
>>> Interval(Date
|
|
1528
|
+
>>> Interval(Date(2018, 9, 10), Date(2018, 9, 6)).b.days()
|
|
1501
1529
|
-2
|
|
1502
1530
|
"""
|
|
1503
1531
|
assert self.begdate
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
date/__init__.py,sha256=zy40bvABy23WBA-LPipESwx0-_jovki_1J8u_hGauYk,2865
|
|
2
|
+
date/date.py,sha256=ewGoFreai0ZvAXmo86b-PiBwlnLAEfvSVsPnvPqZi4A,57580
|
|
3
|
+
date/extras.py,sha256=7xsOsdhKrmGoyLl5W4Xhg9TfuytaaIH7uKWW9PvR5sE,2832
|
|
4
|
+
opendate-0.1.11.dist-info/LICENSE,sha256=V4Rx8WWy7v8Fim6PHcEBszpZkDLbCHeorz1e_gr0Cbk,1111
|
|
5
|
+
opendate-0.1.11.dist-info/METADATA,sha256=xhPS0tMTjnpFQjdkF24MZFZyrqPQzd3OgcGYZsr3wO4,1842
|
|
6
|
+
opendate-0.1.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
7
|
+
opendate-0.1.11.dist-info/RECORD,,
|
opendate-0.1.9.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
date/__init__.py,sha256=GDGA1vmGaVFgt_Fi2ffsxlVdJ837_jW07k_v-O0au6g,2747
|
|
2
|
-
date/date.py,sha256=h9dgscFbeTbSaUDr4qgv-2X6lDiT3Co44wlyDe38Y1o,56603
|
|
3
|
-
date/extras.py,sha256=7xsOsdhKrmGoyLl5W4Xhg9TfuytaaIH7uKWW9PvR5sE,2832
|
|
4
|
-
opendate-0.1.9.dist-info/LICENSE,sha256=V4Rx8WWy7v8Fim6PHcEBszpZkDLbCHeorz1e_gr0Cbk,1111
|
|
5
|
-
opendate-0.1.9.dist-info/METADATA,sha256=7k56td4xBEyV0VC5Ky8K7BN-ihvD2QMSMt_mUb2LZWY,1841
|
|
6
|
-
opendate-0.1.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
7
|
-
opendate-0.1.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|