npdatetime 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.
- npdatetime/__init__.py +1090 -0
- npdatetime/__init__.pyi +293 -0
- npdatetime/_custom_strptime.py +305 -0
- npdatetime/config.py +14 -0
- npdatetime/data/calendar_bs.csv +127 -0
- npdatetime-0.1.1.dist-info/LICENSE +20 -0
- npdatetime-0.1.1.dist-info/METADATA +180 -0
- npdatetime-0.1.1.dist-info/RECORD +10 -0
- npdatetime-0.1.1.dist-info/WHEEL +5 -0
- npdatetime-0.1.1.dist-info/top_level.txt +1 -0
npdatetime/__init__.pyi
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""Most of the code derived from Python3.5 's datetime.pyi"""
|
|
2
|
+
import sys
|
|
3
|
+
import datetime as _actual_datetime
|
|
4
|
+
|
|
5
|
+
from time import struct_time
|
|
6
|
+
from typing import Optional, Tuple, overload, ClassVar, Type, TypeVar
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# __version__: str
|
|
10
|
+
__author__: str
|
|
11
|
+
|
|
12
|
+
_S = TypeVar("_S")
|
|
13
|
+
_A = TypeVar("_A")
|
|
14
|
+
|
|
15
|
+
_Text = str
|
|
16
|
+
|
|
17
|
+
MINYEAR: int
|
|
18
|
+
MAXYEAR: int
|
|
19
|
+
|
|
20
|
+
NEPAL_TIME_UTC_OFFSET: int
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class tzinfo:
|
|
24
|
+
def tzname(self, dt: Optional[datetime]) -> Optional[str]: ...
|
|
25
|
+
def utcoffset(self, dt: Optional[datetime]) -> Optional[_actual_datetime.timedelta]: ...
|
|
26
|
+
def dst(self, dt: Optional[datetime]) -> Optional[_actual_datetime.timedelta]: ...
|
|
27
|
+
def fromutc(self, dt: datetime) -> datetime: ...
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class timezone(tzinfo):
|
|
31
|
+
utc: ClassVar[timezone]
|
|
32
|
+
min: ClassVar[timezone]
|
|
33
|
+
max: ClassVar[timezone]
|
|
34
|
+
|
|
35
|
+
def __init__(self, offset: _actual_datetime.timedelta, name: str = ...) -> None: ...
|
|
36
|
+
def __hash__(self) -> int: ...
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
_tzinfo = tzinfo
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class date:
|
|
43
|
+
min: ClassVar[date]
|
|
44
|
+
max: ClassVar[date]
|
|
45
|
+
resolution: ClassVar[_actual_datetime.timedelta]
|
|
46
|
+
|
|
47
|
+
def __new__(cls: Type[_S], year: int, month: int, day: int) -> _S: ...
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def fromtimestamp(cls: Type[_S], __timestamp: float) -> _S: ...
|
|
51
|
+
@classmethod
|
|
52
|
+
def today(cls: Type[_S]) -> _S: ...
|
|
53
|
+
@classmethod
|
|
54
|
+
def fromordinal(cls: Type[_S], n: int) -> _S: ...
|
|
55
|
+
@classmethod
|
|
56
|
+
def from_datetime_date(cls, from_date: _A) -> _S: ...
|
|
57
|
+
def to_datetime_date(self) -> _A: ...
|
|
58
|
+
if sys.version_info >= (3, 7):
|
|
59
|
+
@classmethod
|
|
60
|
+
def fromisoformat(cls: Type[_S], date_string: str) -> _S: ...
|
|
61
|
+
if sys.version_info >= (3, 8):
|
|
62
|
+
@classmethod
|
|
63
|
+
def fromisocalendar(cls: Type[_S], year: int, week: int, day: int) -> _S: ...
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def year(self) -> int: ...
|
|
67
|
+
@property
|
|
68
|
+
def month(self) -> int: ...
|
|
69
|
+
@property
|
|
70
|
+
def day(self) -> int: ...
|
|
71
|
+
|
|
72
|
+
def ctime(self) -> str: ...
|
|
73
|
+
def strftime(self, fmt: _Text) -> str: ...
|
|
74
|
+
def __format__(self, fmt: str) -> str: ...
|
|
75
|
+
def isoformat(self) -> str: ...
|
|
76
|
+
def timetuple(self) -> struct_time: ...
|
|
77
|
+
def toordinal(self) -> int: ...
|
|
78
|
+
def replace(self, year: int = ..., month: int = ..., day: int = ...) -> date: ...
|
|
79
|
+
def __le__(self, other: date) -> bool: ...
|
|
80
|
+
def __lt__(self, other: date) -> bool: ...
|
|
81
|
+
def __ge__(self, other: date) -> bool: ...
|
|
82
|
+
def __gt__(self, other: date) -> bool: ...
|
|
83
|
+
if sys.version_info >= (3, 8):
|
|
84
|
+
def __add__(self: _S, other: _actual_datetime.timedelta) -> _S: ...
|
|
85
|
+
def __radd__(self: _S, other: _actual_datetime.timedelta) -> _S: ...
|
|
86
|
+
else:
|
|
87
|
+
def __add__(self, other: _actual_datetime.timedelta) -> date: ...
|
|
88
|
+
def __radd__(self, other: _actual_datetime.timedelta) -> date: ...
|
|
89
|
+
@overload
|
|
90
|
+
def __sub__(self, other: _actual_datetime.timedelta) -> date: ...
|
|
91
|
+
@overload
|
|
92
|
+
def __sub__(self, other: date) -> _actual_datetime.timedelta: ...
|
|
93
|
+
def __hash__(self) -> int: ...
|
|
94
|
+
def weekday(self) -> int: ...
|
|
95
|
+
def isoweekday(self) -> int: ...
|
|
96
|
+
def isocalendar(self) -> Tuple[int, int, int]: ...
|
|
97
|
+
|
|
98
|
+
class time:
|
|
99
|
+
min: ClassVar[time]
|
|
100
|
+
max: ClassVar[time]
|
|
101
|
+
resolution: ClassVar[_actual_datetime.timedelta]
|
|
102
|
+
|
|
103
|
+
if sys.version_info >= (3, 6):
|
|
104
|
+
def __init__(self, hour: int = ..., minute: int = ..., second: int = ..., microsecond: int = ...,
|
|
105
|
+
tzinfo: Optional[_tzinfo] = ..., *, fold: int = ...) -> None: ...
|
|
106
|
+
else:
|
|
107
|
+
def __init__(self, hour: int = ..., minute: int = ..., second: int = ..., microsecond: int = ...,
|
|
108
|
+
tzinfo: Optional[_tzinfo] = ...) -> None: ...
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def hour(self) -> int: ...
|
|
112
|
+
@property
|
|
113
|
+
def minute(self) -> int: ...
|
|
114
|
+
@property
|
|
115
|
+
def second(self) -> int: ...
|
|
116
|
+
@property
|
|
117
|
+
def microsecond(self) -> int: ...
|
|
118
|
+
@property
|
|
119
|
+
def tzinfo(self) -> Optional[_tzinfo]: ...
|
|
120
|
+
if sys.version_info >= (3, 6):
|
|
121
|
+
@property
|
|
122
|
+
def fold(self) -> int: ...
|
|
123
|
+
|
|
124
|
+
def __le__(self, other: time) -> bool: ...
|
|
125
|
+
def __lt__(self, other: time) -> bool: ...
|
|
126
|
+
def __ge__(self, other: time) -> bool: ...
|
|
127
|
+
def __gt__(self, other: time) -> bool: ...
|
|
128
|
+
def __hash__(self) -> int: ...
|
|
129
|
+
if sys.version_info >= (3, 6):
|
|
130
|
+
def isoformat(self, timespec: str = ...) -> str: ...
|
|
131
|
+
else:
|
|
132
|
+
def isoformat(self) -> str: ...
|
|
133
|
+
if sys.version_info >= (3, 7):
|
|
134
|
+
@classmethod
|
|
135
|
+
def fromisoformat(cls: Type[_S], time_string: str) -> _S: ...
|
|
136
|
+
def strftime(self, fmt: _Text) -> str: ...
|
|
137
|
+
def __format__(self, fmt: str) -> str: ...
|
|
138
|
+
def utcoffset(self) -> Optional[_actual_datetime.timedelta]: ...
|
|
139
|
+
def tzname(self) -> Optional[str]: ...
|
|
140
|
+
def dst(self) -> Optional[int]: ...
|
|
141
|
+
if sys.version_info >= (3, 6):
|
|
142
|
+
def replace(self, hour: int = ..., minute: int = ..., second: int = ...,
|
|
143
|
+
microsecond: int = ..., tzinfo: Optional[_tzinfo] = ...,
|
|
144
|
+
*, fold: int = ...) -> time: ...
|
|
145
|
+
else:
|
|
146
|
+
def replace(self, hour: int = ..., minute: int = ..., second: int = ...,
|
|
147
|
+
microsecond: int = ..., tzinfo: Optional[_tzinfo] = ...) -> time: ...
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
_date = date
|
|
151
|
+
_time = time
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class datetime(date):
|
|
155
|
+
min: ClassVar[datetime]
|
|
156
|
+
max: ClassVar[datetime]
|
|
157
|
+
resolution: ClassVar[_actual_datetime.timedelta]
|
|
158
|
+
|
|
159
|
+
if sys.version_info >= (3, 6):
|
|
160
|
+
def __new__(
|
|
161
|
+
cls: Type[_S],
|
|
162
|
+
year: int,
|
|
163
|
+
month: int,
|
|
164
|
+
day: int,
|
|
165
|
+
hour: int = ...,
|
|
166
|
+
minute: int = ...,
|
|
167
|
+
second: int = ...,
|
|
168
|
+
microsecond: int = ...,
|
|
169
|
+
tzinfo: Optional[_tzinfo] = ...,
|
|
170
|
+
*,
|
|
171
|
+
fold: int = ...,
|
|
172
|
+
) -> _S: ...
|
|
173
|
+
else:
|
|
174
|
+
def __new__(
|
|
175
|
+
cls: Type[_S],
|
|
176
|
+
year: int,
|
|
177
|
+
month: int,
|
|
178
|
+
day: int,
|
|
179
|
+
hour: int = ...,
|
|
180
|
+
minute: int = ...,
|
|
181
|
+
second: int = ...,
|
|
182
|
+
microsecond: int = ...,
|
|
183
|
+
tzinfo: Optional[_tzinfo] = ...,
|
|
184
|
+
) -> _S: ...
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def year(self) -> int: ...
|
|
188
|
+
@property
|
|
189
|
+
def month(self) -> int: ...
|
|
190
|
+
@property
|
|
191
|
+
def day(self) -> int: ...
|
|
192
|
+
@property
|
|
193
|
+
def hour(self) -> int: ...
|
|
194
|
+
@property
|
|
195
|
+
def minute(self) -> int: ...
|
|
196
|
+
@property
|
|
197
|
+
def second(self) -> int: ...
|
|
198
|
+
@property
|
|
199
|
+
def microsecond(self) -> int: ...
|
|
200
|
+
@property
|
|
201
|
+
def tzinfo(self) -> Optional[_tzinfo]: ...
|
|
202
|
+
if sys.version_info >= (3, 6):
|
|
203
|
+
@property
|
|
204
|
+
def fold(self) -> int: ...
|
|
205
|
+
|
|
206
|
+
@classmethod
|
|
207
|
+
def fromtimestamp(cls: Type[_S], t: float, tz: Optional[_tzinfo] = ...) -> _S: ...
|
|
208
|
+
@classmethod
|
|
209
|
+
def utcfromtimestamp(cls: Type[_S], t: float) -> _S: ...
|
|
210
|
+
@classmethod
|
|
211
|
+
def today(cls: Type[_S]) -> _S: ...
|
|
212
|
+
@classmethod
|
|
213
|
+
def fromordinal(cls: Type[_S], n: int) -> _S: ...
|
|
214
|
+
if sys.version_info >= (3, 8):
|
|
215
|
+
@classmethod
|
|
216
|
+
def now(cls: Type[_S], tz: Optional[_tzinfo] = ...) -> _S: ...
|
|
217
|
+
else:
|
|
218
|
+
@overload
|
|
219
|
+
@classmethod
|
|
220
|
+
def now(cls: Type[_S], tz: None = ...) -> _S: ...
|
|
221
|
+
@overload
|
|
222
|
+
@classmethod
|
|
223
|
+
def now(cls, tz: _tzinfo) -> datetime: ...
|
|
224
|
+
@classmethod
|
|
225
|
+
def utcnow(cls: Type[_S]) -> _S: ...
|
|
226
|
+
if sys.version_info >= (3, 6):
|
|
227
|
+
@classmethod
|
|
228
|
+
def combine(cls, date: _date, time: _time, tzinfo: Optional[_tzinfo] = ...) -> datetime: ...
|
|
229
|
+
else:
|
|
230
|
+
@classmethod
|
|
231
|
+
def combine(cls, date: _date, time: _time) -> datetime: ...
|
|
232
|
+
if sys.version_info >= (3, 7):
|
|
233
|
+
@classmethod
|
|
234
|
+
def fromisoformat(cls: Type[_S], date_string: str) -> _S: ...
|
|
235
|
+
def strftime(self, fmt: _Text) -> str: ...
|
|
236
|
+
def __format__(self, fmt: str) -> str: ...
|
|
237
|
+
def toordinal(self) -> int: ...
|
|
238
|
+
def timetuple(self) -> struct_time: ...
|
|
239
|
+
def timestamp(self) -> float: ...
|
|
240
|
+
def utctimetuple(self) -> struct_time: ...
|
|
241
|
+
def date(self) -> _date: ...
|
|
242
|
+
def time(self) -> _time: ...
|
|
243
|
+
def timetz(self) -> _time: ...
|
|
244
|
+
if sys.version_info >= (3, 6):
|
|
245
|
+
def replace(self, year: int = ..., month: int = ..., day: int = ..., hour: int = ...,
|
|
246
|
+
minute: int = ..., second: int = ..., microsecond: int = ..., tzinfo:
|
|
247
|
+
Optional[_tzinfo] = ..., *, fold: int = ...) -> datetime: ...
|
|
248
|
+
else:
|
|
249
|
+
def replace(self, year: int = ..., month: int = ..., day: int = ..., hour: int = ...,
|
|
250
|
+
minute: int = ..., second: int = ..., microsecond: int = ..., tzinfo:
|
|
251
|
+
Optional[_tzinfo] = ...) -> datetime: ...
|
|
252
|
+
if sys.version_info >= (3, 8):
|
|
253
|
+
def astimezone(self: _S, tz: Optional[_tzinfo] = ...) -> _S: ...
|
|
254
|
+
elif sys.version_info >= (3, 3):
|
|
255
|
+
def astimezone(self, tz: Optional[_tzinfo] = ...) -> datetime: ...
|
|
256
|
+
else:
|
|
257
|
+
def astimezone(self, tz: _tzinfo) -> datetime: ...
|
|
258
|
+
def ctime(self) -> str: ...
|
|
259
|
+
if sys.version_info >= (3, 6):
|
|
260
|
+
def isoformat(self, sep: str = ..., timespec: str = ...) -> str: ...
|
|
261
|
+
else:
|
|
262
|
+
def isoformat(self, sep: str = ...) -> str: ...
|
|
263
|
+
@classmethod
|
|
264
|
+
def strptime(cls, date_string: _Text, format: _Text) -> datetime: ...
|
|
265
|
+
def utcoffset(self) -> Optional[_actual_datetime.timedelta]: ...
|
|
266
|
+
def tzname(self) -> Optional[str]: ...
|
|
267
|
+
def dst(self) -> Optional[_actual_datetime.timedelta]: ...
|
|
268
|
+
def __le__(self, other: datetime) -> bool: ... # type: ignore
|
|
269
|
+
def __lt__(self, other: datetime) -> bool: ... # type: ignore
|
|
270
|
+
def __ge__(self, other: datetime) -> bool: ... # type: ignore
|
|
271
|
+
def __gt__(self, other: datetime) -> bool: ... # type: ignore
|
|
272
|
+
if sys.version_info >= (3, 8):
|
|
273
|
+
def __add__(self: _S, other: _actual_datetime.timedelta) -> _S: ...
|
|
274
|
+
def __radd__(self: _S, other: _actual_datetime.timedelta) -> _S: ...
|
|
275
|
+
else:
|
|
276
|
+
def __add__(self, other: _actual_datetime.timedelta) -> datetime: ...
|
|
277
|
+
def __radd__(self, other: _actual_datetime.timedelta) -> datetime: ...
|
|
278
|
+
@overload # type: ignore
|
|
279
|
+
def __sub__(self, other: datetime) -> _actual_datetime.timedelta: ...
|
|
280
|
+
@overload
|
|
281
|
+
def __sub__(self, other: _actual_datetime.timedelta) -> datetime: ...
|
|
282
|
+
def __hash__(self) -> int: ...
|
|
283
|
+
def weekday(self) -> int: ...
|
|
284
|
+
def isoweekday(self) -> int: ...
|
|
285
|
+
def isocalendar(self) -> Tuple[int, int, int]: ...
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class UTC0545(_actual_datetime.tzinfo):
|
|
289
|
+
def utcoffset(self, dt: datetime) -> _actual_datetime.timedelta: ...
|
|
290
|
+
def dst(self, dt: datetime) -> _actual_datetime.timedelta: ...
|
|
291
|
+
def tzname(self, dt: datetime) -> str: ...
|
|
292
|
+
def fromutc(self, dt: datetime) -> datetime: ...
|
|
293
|
+
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"""Code derived form of Python3.5 's _strptime.py core library to support npdatetime."""
|
|
2
|
+
import time
|
|
3
|
+
import locale
|
|
4
|
+
import calendar
|
|
5
|
+
import _strptime as _actual_strptime
|
|
6
|
+
|
|
7
|
+
from datetime import (timedelta as datetime_timedelta, timezone as datetime_timezone)
|
|
8
|
+
|
|
9
|
+
from npdatetime import date as datetime_date
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from _thread import allocate_lock as _thread_allocate_lock
|
|
13
|
+
except ImportError:
|
|
14
|
+
from _dummy_thread import allocate_lock as _thread_allocate_lock
|
|
15
|
+
|
|
16
|
+
__all__ = []
|
|
17
|
+
|
|
18
|
+
_MONTHNAMES = (None, "bai", "jes", "asa", "shr", "bha", "asw", "kar", "man", "pou", "mag", "fal", "cha")
|
|
19
|
+
_FULLMONTHNAMES = (None, "bashan", "jestha", "asar", "shrawan", "bhadau", "aswin", "kartik", "mangsir", "poush", "magh", "falgun", "chaitra")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _getlang():
|
|
23
|
+
# Figure out what the current language is set to.
|
|
24
|
+
return locale.getlocale(locale.LC_TIME)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class _TimeRE(_actual_strptime.TimeRE):
|
|
28
|
+
|
|
29
|
+
def __init__(self, locale_time=None):
|
|
30
|
+
"""Create keys/values.
|
|
31
|
+
|
|
32
|
+
Order of execution is important for dependency reasons.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
if locale_time:
|
|
36
|
+
self.locale_time = locale_time
|
|
37
|
+
else:
|
|
38
|
+
self.locale_time = _actual_strptime.LocaleTime()
|
|
39
|
+
base = super(_actual_strptime.TimeRE, self)
|
|
40
|
+
base.__init__({
|
|
41
|
+
# The " \d" part of the regex is to make %c from ANSI C work
|
|
42
|
+
'd': r"(?P<d>3[0-2]|[1-2]\d|0[1-9]|[1-9]| [1-9])",
|
|
43
|
+
'f': r"(?P<f>[0-9]{1,6})",
|
|
44
|
+
'H': r"(?P<H>2[0-3]|[0-1]\d|\d)",
|
|
45
|
+
'I': r"(?P<I>1[0-2]|0[1-9]|[1-9])",
|
|
46
|
+
'j': r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])",
|
|
47
|
+
'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])",
|
|
48
|
+
'M': r"(?P<M>[0-5]\d|\d)",
|
|
49
|
+
'S': r"(?P<S>6[0-1]|[0-5]\d|\d)",
|
|
50
|
+
'U': r"(?P<U>5[0-3]|[0-4]\d|\d)",
|
|
51
|
+
'w': r"(?P<w>[0-6])",
|
|
52
|
+
# W is set below by using 'U'
|
|
53
|
+
'y': r"(?P<y>\d\d)",
|
|
54
|
+
# XXX: Does 'Y' need to worry about having less or more than
|
|
55
|
+
# 4 digits?
|
|
56
|
+
'Y': r"(?P<Y>\d\d\d\d)",
|
|
57
|
+
'z': r"(?P<z>[+-]\d\d[0-5]\d)",
|
|
58
|
+
'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
|
|
59
|
+
'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
|
|
60
|
+
'B': self.__seqToRE(_FULLMONTHNAMES[1:], 'B'),
|
|
61
|
+
'b': self.__seqToRE(_MONTHNAMES[1:], 'b'),
|
|
62
|
+
'p': self.__seqToRE(self.locale_time.am_pm, 'p'),
|
|
63
|
+
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
|
|
64
|
+
for tz in tz_names),
|
|
65
|
+
'Z'),
|
|
66
|
+
'%': '%'})
|
|
67
|
+
base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
|
|
68
|
+
base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
|
|
69
|
+
base.__setitem__('x', self.pattern(self.locale_time.LC_date))
|
|
70
|
+
base.__setitem__('X', self.pattern(self.locale_time.LC_time))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
_cache_lock = _thread_allocate_lock()
|
|
74
|
+
# DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock
|
|
75
|
+
# first!
|
|
76
|
+
_TimeRE_cache = _TimeRE()
|
|
77
|
+
_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache
|
|
78
|
+
_regex_cache = {}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
|
|
82
|
+
"""Calculate the Julian day based on the year, week of the year, and day of
|
|
83
|
+
the week, with week_start_day representing whether the week of the year
|
|
84
|
+
assumes the week starts on Sunday or Monday (6 or 0)."""
|
|
85
|
+
first_weekday = datetime_date(year, 1, 1).weekday()
|
|
86
|
+
# If we are dealing with the %U directive (week starts on Sunday), it's
|
|
87
|
+
# easier to just shift the view to Sunday being the first day of the
|
|
88
|
+
# week.
|
|
89
|
+
if not week_starts_Mon:
|
|
90
|
+
first_weekday = (first_weekday + 1) % 7
|
|
91
|
+
day_of_week = (day_of_week + 1) % 7
|
|
92
|
+
# Need to watch out for a week 0 (when the first day of the year is not
|
|
93
|
+
# the same as that specified by %U or %W).
|
|
94
|
+
week_0_length = (7 - first_weekday) % 7
|
|
95
|
+
if week_of_year == 0:
|
|
96
|
+
return 1 + day_of_week - first_weekday
|
|
97
|
+
else:
|
|
98
|
+
days_to_week = week_0_length + (7 * (week_of_year - 1))
|
|
99
|
+
return 1 + days_to_week + day_of_week
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
|
103
|
+
"""Return a 2-tuple consisting of a time struct and an int containing
|
|
104
|
+
the number of microseconds based on the input string and the
|
|
105
|
+
format string."""
|
|
106
|
+
|
|
107
|
+
for index, arg in enumerate([data_string, format]):
|
|
108
|
+
if not isinstance(arg, str):
|
|
109
|
+
msg = "strptime() argument {} must be str, not {}"
|
|
110
|
+
raise TypeError(msg.format(index, type(arg)))
|
|
111
|
+
|
|
112
|
+
global _TimeRE_cache, _regex_cache
|
|
113
|
+
with _cache_lock:
|
|
114
|
+
locale_time = _TimeRE_cache.locale_time
|
|
115
|
+
if (_getlang() != locale_time.lang or
|
|
116
|
+
time.tzname != locale_time.tzname or
|
|
117
|
+
time.daylight != locale_time.daylight):
|
|
118
|
+
_TimeRE_cache = _TimeRE()
|
|
119
|
+
_regex_cache.clear()
|
|
120
|
+
locale_time = _TimeRE_cache.locale_time
|
|
121
|
+
if len(_regex_cache) > _CACHE_MAX_SIZE:
|
|
122
|
+
_regex_cache.clear()
|
|
123
|
+
format_regex = _regex_cache.get(format)
|
|
124
|
+
if not format_regex:
|
|
125
|
+
try:
|
|
126
|
+
format_regex = _TimeRE_cache.compile(format)
|
|
127
|
+
# KeyError raised when a bad format is found; can be specified as
|
|
128
|
+
# \\, in which case it was a stray % but with a space after it
|
|
129
|
+
except KeyError as err:
|
|
130
|
+
bad_directive = err.args[0]
|
|
131
|
+
if bad_directive == "\\":
|
|
132
|
+
bad_directive = "%"
|
|
133
|
+
del err
|
|
134
|
+
raise ValueError("'%s' is a bad directive in format '%s'" %
|
|
135
|
+
(bad_directive, format)) from None
|
|
136
|
+
# IndexError only occurs when the format string is "%"
|
|
137
|
+
except IndexError:
|
|
138
|
+
raise ValueError("stray %% in format '%s'" % format) from None
|
|
139
|
+
_regex_cache[format] = format_regex
|
|
140
|
+
found = format_regex.match(data_string)
|
|
141
|
+
if not found:
|
|
142
|
+
raise ValueError("time data %r does not match format %r" %
|
|
143
|
+
(data_string, format))
|
|
144
|
+
if len(data_string) != found.end():
|
|
145
|
+
raise ValueError("unconverted data remains: %s" %
|
|
146
|
+
data_string[found.end():])
|
|
147
|
+
|
|
148
|
+
year = None
|
|
149
|
+
month = day = 1
|
|
150
|
+
hour = minute = second = fraction = 0
|
|
151
|
+
tz = -1
|
|
152
|
+
tzoffset = None
|
|
153
|
+
# Default to -1 to signify that values not known; not critical to have,
|
|
154
|
+
# though
|
|
155
|
+
week_of_year = -1
|
|
156
|
+
week_of_year_start = -1
|
|
157
|
+
# weekday and julian defaulted to None so as to signal need to calculate
|
|
158
|
+
# values
|
|
159
|
+
weekday = julian = None
|
|
160
|
+
found_dict = found.groupdict()
|
|
161
|
+
for group_key in found_dict.keys():
|
|
162
|
+
# Directives not explicitly handled below:
|
|
163
|
+
# c, x, X
|
|
164
|
+
# handled by making out of other directives
|
|
165
|
+
# U, W
|
|
166
|
+
# worthless without day of the week
|
|
167
|
+
if group_key == 'y':
|
|
168
|
+
year = int(found_dict['y'])
|
|
169
|
+
# Open Group specification for strptime() states that a %y
|
|
170
|
+
# value in the range of [00, 68] is in the century 2000, while
|
|
171
|
+
# [69,99] is in the century 1900
|
|
172
|
+
if year <= 89:
|
|
173
|
+
year += 2000
|
|
174
|
+
else:
|
|
175
|
+
year += 1900
|
|
176
|
+
elif group_key == 'Y':
|
|
177
|
+
year = int(found_dict['Y'])
|
|
178
|
+
elif group_key == 'm':
|
|
179
|
+
month = int(found_dict['m'])
|
|
180
|
+
elif group_key == 'B':
|
|
181
|
+
month = _FULLMONTHNAMES.index(found_dict['B'].lower())
|
|
182
|
+
elif group_key == 'b':
|
|
183
|
+
month = _MONTHNAMES.index(found_dict['b'].lower())
|
|
184
|
+
elif group_key == 'd':
|
|
185
|
+
day = int(found_dict['d'])
|
|
186
|
+
elif group_key == 'H':
|
|
187
|
+
hour = int(found_dict['H'])
|
|
188
|
+
elif group_key == 'I':
|
|
189
|
+
hour = int(found_dict['I'])
|
|
190
|
+
ampm = found_dict.get('p', '').lower()
|
|
191
|
+
# If there was no AM/PM indicator, we'll treat this like AM
|
|
192
|
+
if ampm in ('', locale_time.am_pm[0]):
|
|
193
|
+
# We're in AM so the hour is correct unless we're
|
|
194
|
+
# looking at 12 midnight.
|
|
195
|
+
# 12 midnight == 12 AM == hour 0
|
|
196
|
+
if hour == 12:
|
|
197
|
+
hour = 0
|
|
198
|
+
elif ampm == locale_time.am_pm[1]:
|
|
199
|
+
# We're in PM so we need to add 12 to the hour unless
|
|
200
|
+
# we're looking at 12 noon.
|
|
201
|
+
# 12 noon == 12 PM == hour 12
|
|
202
|
+
if hour != 12:
|
|
203
|
+
hour += 12
|
|
204
|
+
elif group_key == 'M':
|
|
205
|
+
minute = int(found_dict['M'])
|
|
206
|
+
elif group_key == 'S':
|
|
207
|
+
second = int(found_dict['S'])
|
|
208
|
+
elif group_key == 'f':
|
|
209
|
+
s = found_dict['f']
|
|
210
|
+
# Pad to always return microseconds.
|
|
211
|
+
s += "0" * (6 - len(s))
|
|
212
|
+
fraction = int(s)
|
|
213
|
+
elif group_key == 'A':
|
|
214
|
+
weekday = locale_time.f_weekday.index(found_dict['A'].lower())
|
|
215
|
+
elif group_key == 'a':
|
|
216
|
+
weekday = locale_time.a_weekday.index(found_dict['a'].lower())
|
|
217
|
+
elif group_key == 'w':
|
|
218
|
+
weekday = int(found_dict['w'])
|
|
219
|
+
if weekday == 0:
|
|
220
|
+
weekday = 6
|
|
221
|
+
else:
|
|
222
|
+
weekday -= 1
|
|
223
|
+
elif group_key == 'j':
|
|
224
|
+
julian = int(found_dict['j'])
|
|
225
|
+
elif group_key in ('U', 'W'):
|
|
226
|
+
week_of_year = int(found_dict[group_key])
|
|
227
|
+
if group_key == 'U':
|
|
228
|
+
# U starts week on Sunday.
|
|
229
|
+
week_of_year_start = 6
|
|
230
|
+
else:
|
|
231
|
+
# W starts week on Monday.
|
|
232
|
+
week_of_year_start = 0
|
|
233
|
+
elif group_key == 'z':
|
|
234
|
+
z = found_dict['z']
|
|
235
|
+
tzoffset = int(z[1:3]) * 60 + int(z[3:5])
|
|
236
|
+
if z.startswith("-"):
|
|
237
|
+
tzoffset = -tzoffset
|
|
238
|
+
elif group_key == 'Z':
|
|
239
|
+
# Since -1 is default value only need to worry about setting tz if
|
|
240
|
+
# it can be something other than -1.
|
|
241
|
+
found_zone = found_dict['Z'].lower()
|
|
242
|
+
for value, tz_values in enumerate(locale_time.timezone):
|
|
243
|
+
if found_zone in tz_values:
|
|
244
|
+
# Deal with bad locale setup where timezone names are the
|
|
245
|
+
# same and yet time.daylight is true; too ambiguous to
|
|
246
|
+
# be able to tell what timezone has daylight savings
|
|
247
|
+
if (time.tzname[0] == time.tzname[1] and
|
|
248
|
+
time.daylight and found_zone not in ("utc", "gmt")):
|
|
249
|
+
break
|
|
250
|
+
else:
|
|
251
|
+
tz = value
|
|
252
|
+
break
|
|
253
|
+
|
|
254
|
+
if year is None:
|
|
255
|
+
year = 1975
|
|
256
|
+
if julian is None and week_of_year != -1 and weekday is not None:
|
|
257
|
+
week_starts_Mon = True if week_of_year_start == 0 else False
|
|
258
|
+
julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
|
|
259
|
+
week_starts_Mon)
|
|
260
|
+
if julian <= 0:
|
|
261
|
+
year -= 1
|
|
262
|
+
yday = 366 if calendar.isleap(year) else 365
|
|
263
|
+
julian += yday
|
|
264
|
+
# Cannot pre-calculate datetime_date() since can change in Julian
|
|
265
|
+
# calculation and thus could have different value for the day of the week
|
|
266
|
+
# calculation.
|
|
267
|
+
if julian is None:
|
|
268
|
+
# Need to add 1 to result since first day of the year is 1, not 0.
|
|
269
|
+
julian = datetime_date(year, month, day).toordinal() - \
|
|
270
|
+
datetime_date(year, 1, 1).toordinal() + 1
|
|
271
|
+
else: # Assume that if they bothered to include Julian day it will
|
|
272
|
+
# be accurate.
|
|
273
|
+
datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
|
|
274
|
+
year = datetime_result.year
|
|
275
|
+
month = datetime_result.month
|
|
276
|
+
day = datetime_result.day
|
|
277
|
+
if weekday is None:
|
|
278
|
+
weekday = datetime_date(year, month, day).weekday()
|
|
279
|
+
# Add timezone info
|
|
280
|
+
tzname = found_dict.get("Z")
|
|
281
|
+
if tzoffset is not None:
|
|
282
|
+
gmtoff = tzoffset * 60
|
|
283
|
+
else:
|
|
284
|
+
gmtoff = None
|
|
285
|
+
|
|
286
|
+
return (year, month, day,
|
|
287
|
+
hour, minute, second,
|
|
288
|
+
weekday, julian, tz, tzname, gmtoff), fraction
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"):
|
|
292
|
+
"""Return a class cls instance based on the input string and the
|
|
293
|
+
format string."""
|
|
294
|
+
tt, fraction = _strptime(data_string, format)
|
|
295
|
+
tzname, gmtoff = tt[-2:]
|
|
296
|
+
args = tt[:6] + (fraction,)
|
|
297
|
+
if gmtoff is not None:
|
|
298
|
+
tzdelta = datetime_timedelta(seconds=gmtoff)
|
|
299
|
+
if tzname:
|
|
300
|
+
tz = datetime_timezone(tzdelta, tzname)
|
|
301
|
+
else:
|
|
302
|
+
tz = datetime_timezone(tzdelta)
|
|
303
|
+
args += (tz,)
|
|
304
|
+
|
|
305
|
+
return cls(*args)
|
npdatetime/config.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
# Define the base directory
|
|
4
|
+
BASE_DIR = os.path.dirname(__file__)
|
|
5
|
+
|
|
6
|
+
# Path to the calendar data file
|
|
7
|
+
CALENDAR_PATH = os.path.join(BASE_DIR, 'data', 'calendar_bs.csv')
|
|
8
|
+
|
|
9
|
+
# Reference date for conversions
|
|
10
|
+
REFERENCE_DATE_AD = {'year': 1918, 'month': 4, 'day': 13}
|
|
11
|
+
|
|
12
|
+
# Valid range for Nepali dates
|
|
13
|
+
MINDATE = {'year': 1975, 'month': 1, 'day': 1}
|
|
14
|
+
MAXDATE = {'year': 2100, 'month': 12, 'day': 30}
|