-
Notifications
You must be signed in to change notification settings - Fork 465
/
__init__.py
139 lines (115 loc) · 4.08 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# coding: utf-8
from __future__ import unicode_literals
from dateparser.parser import _parser
from dateparser.conf import settings
from datetime import datetime
class CalendarBase(object):
"""Base setup class for non-Gregorian calendar system.
:param source:
Date string passed to calendar parser.
:type source: str|unicode
"""
parser = NotImplemented
def __init__(self, source):
self.source = source
def get_date(self):
try:
date_obj, period = self.parser.parse(self.source, settings)
return {'date_obj': date_obj, 'period': period}
except ValueError:
pass
class non_gregorian_parser(_parser):
calendar_converter = NotImplemented
default_year = NotImplemented
default_month = NotImplemented
default_day = NotImplemented
non_gregorian_date_cls = NotImplemented
_digits = None
_months = None
_weekdays = None
_number_letters = None
@classmethod
def _replace_time_conventions(cls, source):
return source
@classmethod
def _replace_digits(cls, source):
return source
@classmethod
def _replace_months(cls, source):
return source
@classmethod
def _replace_weekdays(cls, source):
return source
@classmethod
def _replace_time(cls, source):
return source
@classmethod
def _replace_days(cls, source):
return source
@classmethod
def to_latin(cls, source):
result = source
result = cls._replace_months(result)
result = cls._replace_weekdays(result)
result = cls._replace_digits(result)
result = cls._replace_days(result)
result = cls._replace_time(result)
result = cls._replace_time_conventions(result)
result = result.strip()
return result
def _get_datetime_obj(self, **params):
day = params['day']
year = params['year']
month = params['month']
if (
not(0 < day <= self.calendar_converter.month_length(year, month)) and
not(self._token_day or hasattr(self, '_token_weekday'))
):
day = self.calendar_converter.month_length(year, month)
year, month, day = self.calendar_converter.to_gregorian(year=year, month=month, day=day)
c_params = params.copy()
c_params.update(dict(year=year, month=month, day=day))
return datetime(**c_params)
def _get_datetime_obj_params(self):
if not self.now:
self._set_relative_base()
now_year, now_month, now_day = self.calendar_converter.from_gregorian(
self.now.year, self.now.month, self.now.day)
params = {
'day': self.day or now_day,
'month': self.month or now_month,
'year': self.year or now_year,
'hour': 0, 'minute': 0, 'second': 0, 'microsecond': 0,
}
return params
def _get_date_obj(self, token, directive):
year, month, day = self.default_year, self.default_month, self.default_day
token_len = len(token)
is_digit = token.isdigit()
if directive == '%A' and self._weekdays and token.title() in self._weekdays:
pass
elif (
directive == '%m' and
token_len <= 2 and
is_digit and
1 <= int(token) <= 12
):
month = int(token)
elif directive == '%B' and self._months and token in self._months:
month = list(self._months.keys()).index(token) + 1
elif (
directive == '%d' and
token_len <= 2 and
is_digit and
0 < int(token) <= self.calendar_converter.month_length(year, month)
):
day = int(token)
elif directive == '%Y' and token_len == 4 and is_digit:
year = int(token)
else:
raise ValueError
return self.non_gregorian_date_cls(year, month, day)
@classmethod
def parse(cls, datestring, settings):
datestring = cls.to_latin(datestring)
return super(non_gregorian_parser, cls).parse(datestring, settings)