dateparser 1.2.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.
Files changed (256) hide show
  1. dateparser/__init__.py +82 -0
  2. dateparser/calendars/__init__.py +144 -0
  3. dateparser/calendars/hijri.py +6 -0
  4. dateparser/calendars/hijri_parser.py +60 -0
  5. dateparser/calendars/jalali.py +9 -0
  6. dateparser/calendars/jalali_parser.py +184 -0
  7. dateparser/conf.py +267 -0
  8. dateparser/custom_language_detection/__init__.py +0 -0
  9. dateparser/custom_language_detection/fasttext.py +43 -0
  10. dateparser/custom_language_detection/langdetect.py +37 -0
  11. dateparser/custom_language_detection/language_mapping.py +18 -0
  12. dateparser/data/__init__.py +2 -0
  13. dateparser/data/date_translation_data/__init__.py +0 -0
  14. dateparser/data/date_translation_data/af.py +242 -0
  15. dateparser/data/date_translation_data/agq.py +169 -0
  16. dateparser/data/date_translation_data/ak.py +169 -0
  17. dateparser/data/date_translation_data/am.py +222 -0
  18. dateparser/data/date_translation_data/ar.py +574 -0
  19. dateparser/data/date_translation_data/as.py +164 -0
  20. dateparser/data/date_translation_data/asa.py +168 -0
  21. dateparser/data/date_translation_data/ast.py +280 -0
  22. dateparser/data/date_translation_data/az-Cyrl.py +168 -0
  23. dateparser/data/date_translation_data/az-Latn.py +217 -0
  24. dateparser/data/date_translation_data/az.py +217 -0
  25. dateparser/data/date_translation_data/bas.py +169 -0
  26. dateparser/data/date_translation_data/be.py +340 -0
  27. dateparser/data/date_translation_data/bem.py +161 -0
  28. dateparser/data/date_translation_data/bez.py +169 -0
  29. dateparser/data/date_translation_data/bg.py +345 -0
  30. dateparser/data/date_translation_data/bm.py +167 -0
  31. dateparser/data/date_translation_data/bn.py +241 -0
  32. dateparser/data/date_translation_data/bo.py +185 -0
  33. dateparser/data/date_translation_data/br.py +226 -0
  34. dateparser/data/date_translation_data/brx.py +157 -0
  35. dateparser/data/date_translation_data/bs-Cyrl.py +226 -0
  36. dateparser/data/date_translation_data/bs-Latn.py +248 -0
  37. dateparser/data/date_translation_data/bs.py +248 -0
  38. dateparser/data/date_translation_data/ca.py +313 -0
  39. dateparser/data/date_translation_data/ce.py +225 -0
  40. dateparser/data/date_translation_data/cgg.py +169 -0
  41. dateparser/data/date_translation_data/chr.py +240 -0
  42. dateparser/data/date_translation_data/ckb.py +154 -0
  43. dateparser/data/date_translation_data/cs.py +316 -0
  44. dateparser/data/date_translation_data/cy.py +217 -0
  45. dateparser/data/date_translation_data/da.py +296 -0
  46. dateparser/data/date_translation_data/dav.py +169 -0
  47. dateparser/data/date_translation_data/de.py +357 -0
  48. dateparser/data/date_translation_data/dje.py +167 -0
  49. dateparser/data/date_translation_data/dsb.py +270 -0
  50. dateparser/data/date_translation_data/dua.py +169 -0
  51. dateparser/data/date_translation_data/dyo.py +168 -0
  52. dateparser/data/date_translation_data/dz.py +225 -0
  53. dateparser/data/date_translation_data/ebu.py +169 -0
  54. dateparser/data/date_translation_data/ee.py +233 -0
  55. dateparser/data/date_translation_data/el.py +279 -0
  56. dateparser/data/date_translation_data/en.py +851 -0
  57. dateparser/data/date_translation_data/eo.py +169 -0
  58. dateparser/data/date_translation_data/es.py +499 -0
  59. dateparser/data/date_translation_data/et.py +233 -0
  60. dateparser/data/date_translation_data/eu.py +219 -0
  61. dateparser/data/date_translation_data/ewo.py +169 -0
  62. dateparser/data/date_translation_data/fa.py +270 -0
  63. dateparser/data/date_translation_data/ff.py +179 -0
  64. dateparser/data/date_translation_data/fi.py +345 -0
  65. dateparser/data/date_translation_data/fil.py +223 -0
  66. dateparser/data/date_translation_data/fo.py +256 -0
  67. dateparser/data/date_translation_data/fr.py +520 -0
  68. dateparser/data/date_translation_data/fur.py +223 -0
  69. dateparser/data/date_translation_data/fy.py +223 -0
  70. dateparser/data/date_translation_data/ga.py +238 -0
  71. dateparser/data/date_translation_data/gd.py +277 -0
  72. dateparser/data/date_translation_data/gl.py +253 -0
  73. dateparser/data/date_translation_data/gsw.py +179 -0
  74. dateparser/data/date_translation_data/gu.py +216 -0
  75. dateparser/data/date_translation_data/guz.py +170 -0
  76. dateparser/data/date_translation_data/gv.py +166 -0
  77. dateparser/data/date_translation_data/ha.py +176 -0
  78. dateparser/data/date_translation_data/haw.py +168 -0
  79. dateparser/data/date_translation_data/he.py +371 -0
  80. dateparser/data/date_translation_data/hi.py +261 -0
  81. dateparser/data/date_translation_data/hr.py +378 -0
  82. dateparser/data/date_translation_data/hsb.py +271 -0
  83. dateparser/data/date_translation_data/hu.py +297 -0
  84. dateparser/data/date_translation_data/hy.py +246 -0
  85. dateparser/data/date_translation_data/id.py +272 -0
  86. dateparser/data/date_translation_data/ig.py +168 -0
  87. dateparser/data/date_translation_data/ii.py +157 -0
  88. dateparser/data/date_translation_data/is.py +242 -0
  89. dateparser/data/date_translation_data/it.py +282 -0
  90. dateparser/data/date_translation_data/ja.py +286 -0
  91. dateparser/data/date_translation_data/jgo.py +188 -0
  92. dateparser/data/date_translation_data/jmc.py +168 -0
  93. dateparser/data/date_translation_data/ka.py +241 -0
  94. dateparser/data/date_translation_data/kab.py +169 -0
  95. dateparser/data/date_translation_data/kam.py +169 -0
  96. dateparser/data/date_translation_data/kde.py +169 -0
  97. dateparser/data/date_translation_data/kea.py +230 -0
  98. dateparser/data/date_translation_data/khq.py +167 -0
  99. dateparser/data/date_translation_data/ki.py +169 -0
  100. dateparser/data/date_translation_data/kk.py +228 -0
  101. dateparser/data/date_translation_data/kl.py +213 -0
  102. dateparser/data/date_translation_data/kln.py +171 -0
  103. dateparser/data/date_translation_data/km.py +198 -0
  104. dateparser/data/date_translation_data/kn.py +225 -0
  105. dateparser/data/date_translation_data/ko.py +207 -0
  106. dateparser/data/date_translation_data/kok.py +157 -0
  107. dateparser/data/date_translation_data/ks.py +152 -0
  108. dateparser/data/date_translation_data/ksb.py +168 -0
  109. dateparser/data/date_translation_data/ksf.py +169 -0
  110. dateparser/data/date_translation_data/ksh.py +192 -0
  111. dateparser/data/date_translation_data/kw.py +169 -0
  112. dateparser/data/date_translation_data/ky.py +240 -0
  113. dateparser/data/date_translation_data/lag.py +169 -0
  114. dateparser/data/date_translation_data/lb.py +233 -0
  115. dateparser/data/date_translation_data/lg.py +169 -0
  116. dateparser/data/date_translation_data/lkt.py +194 -0
  117. dateparser/data/date_translation_data/ln.py +179 -0
  118. dateparser/data/date_translation_data/lo.py +228 -0
  119. dateparser/data/date_translation_data/lrc.py +154 -0
  120. dateparser/data/date_translation_data/lt.py +263 -0
  121. dateparser/data/date_translation_data/lu.py +169 -0
  122. dateparser/data/date_translation_data/luo.py +169 -0
  123. dateparser/data/date_translation_data/luy.py +168 -0
  124. dateparser/data/date_translation_data/lv.py +257 -0
  125. dateparser/data/date_translation_data/mas.py +173 -0
  126. dateparser/data/date_translation_data/mer.py +168 -0
  127. dateparser/data/date_translation_data/mfe.py +166 -0
  128. dateparser/data/date_translation_data/mg.py +168 -0
  129. dateparser/data/date_translation_data/mgh.py +169 -0
  130. dateparser/data/date_translation_data/mgo.py +151 -0
  131. dateparser/data/date_translation_data/mk.py +234 -0
  132. dateparser/data/date_translation_data/ml.py +217 -0
  133. dateparser/data/date_translation_data/mn.py +224 -0
  134. dateparser/data/date_translation_data/mr.py +229 -0
  135. dateparser/data/date_translation_data/ms.py +242 -0
  136. dateparser/data/date_translation_data/mt.py +175 -0
  137. dateparser/data/date_translation_data/mua.py +169 -0
  138. dateparser/data/date_translation_data/my.py +203 -0
  139. dateparser/data/date_translation_data/mzn.py +199 -0
  140. dateparser/data/date_translation_data/naq.py +169 -0
  141. dateparser/data/date_translation_data/nb.py +261 -0
  142. dateparser/data/date_translation_data/nd.py +169 -0
  143. dateparser/data/date_translation_data/ne.py +207 -0
  144. dateparser/data/date_translation_data/nl.py +273 -0
  145. dateparser/data/date_translation_data/nmg.py +169 -0
  146. dateparser/data/date_translation_data/nn.py +231 -0
  147. dateparser/data/date_translation_data/nnh.py +150 -0
  148. dateparser/data/date_translation_data/nus.py +166 -0
  149. dateparser/data/date_translation_data/nyn.py +169 -0
  150. dateparser/data/date_translation_data/om.py +173 -0
  151. dateparser/data/date_translation_data/or.py +157 -0
  152. dateparser/data/date_translation_data/os.py +203 -0
  153. dateparser/data/date_translation_data/pa-Arab.py +150 -0
  154. dateparser/data/date_translation_data/pa-Guru.py +221 -0
  155. dateparser/data/date_translation_data/pa.py +221 -0
  156. dateparser/data/date_translation_data/pl.py +416 -0
  157. dateparser/data/date_translation_data/ps.py +150 -0
  158. dateparser/data/date_translation_data/pt.py +981 -0
  159. dateparser/data/date_translation_data/qu.py +176 -0
  160. dateparser/data/date_translation_data/rm.py +166 -0
  161. dateparser/data/date_translation_data/rn.py +169 -0
  162. dateparser/data/date_translation_data/ro.py +270 -0
  163. dateparser/data/date_translation_data/rof.py +157 -0
  164. dateparser/data/date_translation_data/ru.py +442 -0
  165. dateparser/data/date_translation_data/rw.py +169 -0
  166. dateparser/data/date_translation_data/rwk.py +168 -0
  167. dateparser/data/date_translation_data/sah.py +219 -0
  168. dateparser/data/date_translation_data/saq.py +169 -0
  169. dateparser/data/date_translation_data/sbp.py +169 -0
  170. dateparser/data/date_translation_data/se.py +280 -0
  171. dateparser/data/date_translation_data/seh.py +169 -0
  172. dateparser/data/date_translation_data/ses.py +167 -0
  173. dateparser/data/date_translation_data/sg.py +169 -0
  174. dateparser/data/date_translation_data/shi-Latn.py +169 -0
  175. dateparser/data/date_translation_data/shi-Tfng.py +169 -0
  176. dateparser/data/date_translation_data/shi.py +169 -0
  177. dateparser/data/date_translation_data/si.py +220 -0
  178. dateparser/data/date_translation_data/sk.py +327 -0
  179. dateparser/data/date_translation_data/sl.py +244 -0
  180. dateparser/data/date_translation_data/smn.py +176 -0
  181. dateparser/data/date_translation_data/sn.py +169 -0
  182. dateparser/data/date_translation_data/so.py +179 -0
  183. dateparser/data/date_translation_data/sq.py +237 -0
  184. dateparser/data/date_translation_data/sr-Cyrl.py +306 -0
  185. dateparser/data/date_translation_data/sr-Latn.py +306 -0
  186. dateparser/data/date_translation_data/sr.py +255 -0
  187. dateparser/data/date_translation_data/sv.py +309 -0
  188. dateparser/data/date_translation_data/sw.py +231 -0
  189. dateparser/data/date_translation_data/ta.py +264 -0
  190. dateparser/data/date_translation_data/te.py +239 -0
  191. dateparser/data/date_translation_data/teo.py +173 -0
  192. dateparser/data/date_translation_data/th.py +300 -0
  193. dateparser/data/date_translation_data/ti.py +173 -0
  194. dateparser/data/date_translation_data/tl.py +137 -0
  195. dateparser/data/date_translation_data/to.py +216 -0
  196. dateparser/data/date_translation_data/tr.py +259 -0
  197. dateparser/data/date_translation_data/twq.py +167 -0
  198. dateparser/data/date_translation_data/tzm.py +169 -0
  199. dateparser/data/date_translation_data/ug.py +203 -0
  200. dateparser/data/date_translation_data/uk.py +502 -0
  201. dateparser/data/date_translation_data/ur.py +256 -0
  202. dateparser/data/date_translation_data/uz-Arab.py +167 -0
  203. dateparser/data/date_translation_data/uz-Cyrl.py +210 -0
  204. dateparser/data/date_translation_data/uz-Latn.py +216 -0
  205. dateparser/data/date_translation_data/uz.py +216 -0
  206. dateparser/data/date_translation_data/vi.py +260 -0
  207. dateparser/data/date_translation_data/vun.py +168 -0
  208. dateparser/data/date_translation_data/wae.py +224 -0
  209. dateparser/data/date_translation_data/xog.py +169 -0
  210. dateparser/data/date_translation_data/yav.py +169 -0
  211. dateparser/data/date_translation_data/yi.py +178 -0
  212. dateparser/data/date_translation_data/yo.py +263 -0
  213. dateparser/data/date_translation_data/yue.py +203 -0
  214. dateparser/data/date_translation_data/zgh.py +169 -0
  215. dateparser/data/date_translation_data/zh-Hans.py +240 -0
  216. dateparser/data/date_translation_data/zh-Hant.py +402 -0
  217. dateparser/data/date_translation_data/zh.py +273 -0
  218. dateparser/data/date_translation_data/zu.py +196 -0
  219. dateparser/data/languages_info.py +826 -0
  220. dateparser/date.py +599 -0
  221. dateparser/date_parser.py +55 -0
  222. dateparser/freshness_date_parser.py +156 -0
  223. dateparser/languages/__init__.py +2 -0
  224. dateparser/languages/dictionary.py +352 -0
  225. dateparser/languages/loader.py +224 -0
  226. dateparser/languages/locale.py +625 -0
  227. dateparser/languages/validation.py +467 -0
  228. dateparser/parser.py +742 -0
  229. dateparser/search/__init__.py +71 -0
  230. dateparser/search/detection.py +78 -0
  231. dateparser/search/search.py +297 -0
  232. dateparser/search/text_detection.py +89 -0
  233. dateparser/timezone_parser.py +91 -0
  234. dateparser/timezones.py +469 -0
  235. dateparser/utils/__init__.py +257 -0
  236. dateparser/utils/strptime.py +108 -0
  237. dateparser-1.2.1.dist-info/AUTHORS.rst +17 -0
  238. dateparser-1.2.1.dist-info/LICENSE +12 -0
  239. dateparser-1.2.1.dist-info/METADATA +864 -0
  240. dateparser-1.2.1.dist-info/RECORD +256 -0
  241. dateparser-1.2.1.dist-info/WHEEL +5 -0
  242. dateparser-1.2.1.dist-info/entry_points.txt +2 -0
  243. dateparser-1.2.1.dist-info/top_level.txt +4 -0
  244. dateparser_cli/__init__.py +0 -0
  245. dateparser_cli/cli.py +36 -0
  246. dateparser_cli/exceptions.py +2 -0
  247. dateparser_cli/fasttext_manager.py +42 -0
  248. dateparser_cli/utils.py +27 -0
  249. dateparser_data/__init__.py +0 -0
  250. dateparser_data/settings.py +33 -0
  251. dateparser_scripts/__init__.py +0 -0
  252. dateparser_scripts/get_cldr_data.py +567 -0
  253. dateparser_scripts/order_languages.py +217 -0
  254. dateparser_scripts/update_supported_languages_and_locales.py +48 -0
  255. dateparser_scripts/utils.py +73 -0
  256. dateparser_scripts/write_complete_data.py +129 -0
@@ -0,0 +1,257 @@
1
+ import calendar
2
+ import logging
3
+ import types
4
+ import unicodedata
5
+ from collections import OrderedDict
6
+ from datetime import datetime
7
+
8
+ import regex as re
9
+ from pytz import UTC, UnknownTimeZoneError, timezone
10
+ from tzlocal import get_localzone
11
+
12
+ from dateparser.timezone_parser import StaticTzInfo, _tz_offsets
13
+
14
+
15
+ def strip_braces(date_string):
16
+ return re.sub(r"[{}()<>\[\]]+", "", date_string)
17
+
18
+
19
+ def normalize_unicode(string, form="NFKD"):
20
+ return "".join(
21
+ c
22
+ for c in unicodedata.normalize(form, string)
23
+ if unicodedata.category(c) != "Mn"
24
+ )
25
+
26
+
27
+ def combine_dicts(primary_dict, supplementary_dict):
28
+ combined_dict = OrderedDict()
29
+ for key, value in primary_dict.items():
30
+ if key in supplementary_dict:
31
+ if isinstance(value, list):
32
+ combined_dict[key] = value + supplementary_dict[key]
33
+ elif isinstance(value, dict):
34
+ combined_dict[key] = combine_dicts(value, supplementary_dict[key])
35
+ else:
36
+ combined_dict[key] = supplementary_dict[key]
37
+ else:
38
+ combined_dict[key] = primary_dict[key]
39
+ remaining_keys = [
40
+ key for key in supplementary_dict.keys() if key not in primary_dict.keys()
41
+ ]
42
+ for key in remaining_keys:
43
+ combined_dict[key] = supplementary_dict[key]
44
+ return combined_dict
45
+
46
+
47
+ def find_date_separator(format):
48
+ m = re.search(r"(?:(?:%[dbBmaA])(\W))+", format)
49
+ if m:
50
+ return m.group(1)
51
+
52
+
53
+ def _get_missing_parts(fmt):
54
+ """
55
+ Return a list containing missing parts (day, month, year)
56
+ from a date format checking its directives
57
+ """
58
+ directive_mapping = {
59
+ "day": ["%d", "%-d", "%j", "%-j"],
60
+ "month": ["%b", "%B", "%m", "%-m"],
61
+ "year": ["%y", "%-y", "%Y"],
62
+ }
63
+
64
+ missing = [
65
+ field
66
+ for field in ("day", "month", "year")
67
+ if not any(directive in fmt for directive in directive_mapping[field])
68
+ ]
69
+ return missing
70
+
71
+
72
+ def get_timezone_from_tz_string(tz_string):
73
+ try:
74
+ return timezone(tz_string)
75
+ except UnknownTimeZoneError as e:
76
+ for name, info in _tz_offsets:
77
+ if info["regex"].search(" %s" % tz_string):
78
+ return StaticTzInfo(name, info["offset"])
79
+ else:
80
+ raise e
81
+
82
+
83
+ def localize_timezone(date_time, tz_string):
84
+ if date_time.tzinfo:
85
+ return date_time
86
+
87
+ tz = get_timezone_from_tz_string(tz_string)
88
+
89
+ if hasattr(tz, "localize"):
90
+ date_time = tz.localize(date_time)
91
+ else:
92
+ date_time = date_time.replace(tzinfo=tz)
93
+
94
+ return date_time
95
+
96
+
97
+ def apply_tzdatabase_timezone(date_time, pytz_string):
98
+ usr_timezone = timezone(pytz_string)
99
+
100
+ if date_time.tzinfo != usr_timezone:
101
+ date_time = date_time.astimezone(usr_timezone)
102
+
103
+ return date_time
104
+
105
+
106
+ def apply_dateparser_timezone(utc_datetime, offset_or_timezone_abb):
107
+ for name, info in _tz_offsets:
108
+ if info["regex"].search(" %s" % offset_or_timezone_abb):
109
+ tz = StaticTzInfo(name, info["offset"])
110
+ return utc_datetime.astimezone(tz)
111
+
112
+
113
+ def apply_timezone(date_time, tz_string):
114
+ if not date_time.tzinfo:
115
+ if hasattr(UTC, "localize"):
116
+ date_time = UTC.localize(date_time)
117
+ else:
118
+ date_time = date_time.replace(tzinfo=UTC)
119
+
120
+ new_datetime = apply_dateparser_timezone(date_time, tz_string)
121
+
122
+ if not new_datetime:
123
+ new_datetime = apply_tzdatabase_timezone(date_time, tz_string)
124
+
125
+ return new_datetime
126
+
127
+
128
+ def apply_timezone_from_settings(date_obj, settings):
129
+ tz = get_localzone()
130
+ if settings is None:
131
+ return date_obj
132
+
133
+ if "local" in settings.TIMEZONE.lower():
134
+ if hasattr(tz, "localize"):
135
+ date_obj = tz.localize(date_obj)
136
+ else:
137
+ date_obj = date_obj.replace(tzinfo=tz)
138
+ else:
139
+ date_obj = localize_timezone(date_obj, settings.TIMEZONE)
140
+
141
+ if settings.TO_TIMEZONE:
142
+ date_obj = apply_timezone(date_obj, settings.TO_TIMEZONE)
143
+
144
+ if settings.RETURN_AS_TIMEZONE_AWARE is not True:
145
+ date_obj = date_obj.replace(tzinfo=None)
146
+
147
+ return date_obj
148
+
149
+
150
+ def get_last_day_of_month(year, month):
151
+ return calendar.monthrange(year, month)[1]
152
+
153
+
154
+ def get_previous_leap_year(year):
155
+ return _get_leap_year(year, future=False)
156
+
157
+
158
+ def get_next_leap_year(year):
159
+ return _get_leap_year(year, future=True)
160
+
161
+
162
+ def _get_leap_year(year, future):
163
+ """
164
+ Iterate through previous or next years until it gets a valid leap year
165
+ This is performed to avoid missing or including centurial leap years
166
+ """
167
+ step = 1 if future else -1
168
+ leap_year = year + step
169
+ while not calendar.isleap(leap_year):
170
+ leap_year += step
171
+ return leap_year
172
+
173
+
174
+ def set_correct_day_from_settings(date_obj, settings, current_day=None):
175
+ """Set correct day attending the `PREFER_DAY_OF_MONTH` setting."""
176
+ options = {
177
+ "first": 1,
178
+ "last": get_last_day_of_month(date_obj.year, date_obj.month),
179
+ "current": current_day or datetime.now().day,
180
+ }
181
+
182
+ try:
183
+ return date_obj.replace(day=options[settings.PREFER_DAY_OF_MONTH])
184
+ except ValueError:
185
+ return date_obj.replace(day=options["last"])
186
+
187
+
188
+ def set_correct_month_from_settings(date_obj, settings, current_month=None):
189
+ """Set correct month attending the `PREFER_MONTH_OF_YEAR` setting."""
190
+ options = {"first": 1, "last": 12, "current": current_month or datetime.now().month}
191
+
192
+ try:
193
+ return date_obj.replace(month=options[settings.PREFER_MONTH_OF_YEAR])
194
+ except ValueError:
195
+ return date_obj.replace(month=options["last"])
196
+
197
+
198
+ def registry(cls):
199
+ def choose(creator):
200
+ def constructor(cls, *args, **kwargs):
201
+ key = cls.get_key(*args, **kwargs)
202
+
203
+ if not hasattr(cls, "__registry_dict"):
204
+ setattr(cls, "__registry_dict", {})
205
+ registry_dict = getattr(cls, "__registry_dict")
206
+
207
+ if key not in registry_dict:
208
+ registry_dict[key] = creator(cls, *args)
209
+ setattr(registry_dict[key], "registry_key", key)
210
+ return registry_dict[key]
211
+
212
+ return staticmethod(constructor)
213
+
214
+ if not (
215
+ hasattr(cls, "get_key")
216
+ and isinstance(cls.get_key, types.MethodType)
217
+ and cls.get_key.__self__ is cls
218
+ ):
219
+ raise NotImplementedError(
220
+ "Registry classes require to implement class method get_key"
221
+ )
222
+
223
+ setattr(cls, "__new__", choose(cls.__new__))
224
+ return cls
225
+
226
+
227
+ def get_logger():
228
+ setup_logging()
229
+ return logging.getLogger("dateparser")
230
+
231
+
232
+ def setup_logging():
233
+ if len(logging.root.handlers):
234
+ return
235
+
236
+ config = {
237
+ "version": 1,
238
+ "disable_existing_loggers": True,
239
+ "formatters": {
240
+ "console": {
241
+ "format": "%(asctime)s %(levelname)s: [%(name)s] %(message)s",
242
+ },
243
+ },
244
+ "handlers": {
245
+ "console": {
246
+ "level": logging.DEBUG,
247
+ "class": "logging.StreamHandler",
248
+ "formatter": "console",
249
+ "stream": "ext://sys.stdout",
250
+ },
251
+ },
252
+ "root": {
253
+ "level": logging.DEBUG,
254
+ "handlers": ["console"],
255
+ },
256
+ }
257
+ logging.config.dictConfig(config)
@@ -0,0 +1,108 @@
1
+ import importlib.util
2
+ import sys
3
+ from datetime import datetime
4
+
5
+ import regex as re
6
+
7
+ TIME_MATCHER = re.compile(
8
+ r".*?"
9
+ r"(?P<hour>2[0-3]|[0-1]\d|\d):"
10
+ r"(?P<minute>[0-5]\d|\d):"
11
+ r"(?P<second>6[0-1]|[0-5]\d|\d)"
12
+ r"\.(?P<microsecond>[0-9]{1,6})"
13
+ )
14
+
15
+ MS_SEARCHER = re.compile(r"\.(?P<microsecond>[0-9]{1,6})")
16
+
17
+
18
+ def _exec_module(spec, module):
19
+ if hasattr(spec.loader, "exec_module"):
20
+ spec.loader.exec_module(module)
21
+ else:
22
+ # This can happen before Python 3.10
23
+ # if spec.loader is a zipimporter and the Python runtime is in a zipfile
24
+ code = spec.loader.get_code(module.__name__)
25
+ exec(code, module.__dict__)
26
+
27
+
28
+ def patch_strptime():
29
+ """Monkey patching _strptime to avoid problems related with non-english
30
+ locale changes on the system.
31
+
32
+ For example, if system's locale is set to fr_FR. Parser won't recognize
33
+ any date since all languages are translated to english dates.
34
+ """
35
+ _strptime_spec = importlib.util.find_spec("_strptime")
36
+ _strptime = importlib.util.module_from_spec(_strptime_spec)
37
+ _exec_module(_strptime_spec, _strptime)
38
+ sys.modules["strptime_patched"] = _strptime
39
+
40
+ _calendar = importlib.util.module_from_spec(_strptime_spec)
41
+ _exec_module(_strptime_spec, _calendar)
42
+ sys.modules["calendar_patched"] = _calendar
43
+
44
+ _strptime._getlang = lambda: ("en_US", "UTF-8")
45
+ _strptime.calendar = _calendar
46
+ _strptime.calendar.day_abbr = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
47
+ _strptime.calendar.day_name = [
48
+ "monday",
49
+ "tuesday",
50
+ "wednesday",
51
+ "thursday",
52
+ "friday",
53
+ "saturday",
54
+ "sunday",
55
+ ]
56
+ _strptime.calendar.month_abbr = [
57
+ "",
58
+ "jan",
59
+ "feb",
60
+ "mar",
61
+ "apr",
62
+ "may",
63
+ "jun",
64
+ "jul",
65
+ "aug",
66
+ "sep",
67
+ "oct",
68
+ "nov",
69
+ "dec",
70
+ ]
71
+ _strptime.calendar.month_name = [
72
+ "",
73
+ "january",
74
+ "february",
75
+ "march",
76
+ "april",
77
+ "may",
78
+ "june",
79
+ "july",
80
+ "august",
81
+ "september",
82
+ "october",
83
+ "november",
84
+ "december",
85
+ ]
86
+
87
+ return _strptime._strptime_time
88
+
89
+
90
+ __strptime = patch_strptime()
91
+
92
+
93
+ def strptime(date_string, format):
94
+ obj = datetime(*__strptime(date_string, format)[:-3])
95
+
96
+ if "%f" in format:
97
+ try:
98
+ match_groups = TIME_MATCHER.match(date_string).groupdict()
99
+ ms = match_groups["microsecond"]
100
+ ms = ms + ((6 - len(ms)) * "0")
101
+ obj = obj.replace(microsecond=int(ms))
102
+ except AttributeError:
103
+ match_groups = MS_SEARCHER.search(date_string).groupdict()
104
+ ms = match_groups["microsecond"]
105
+ ms = ms + ((6 - len(ms)) * "0")
106
+ obj = obj.replace(microsecond=int(ms))
107
+
108
+ return obj
@@ -0,0 +1,17 @@
1
+ =======
2
+ Credits
3
+ =======
4
+
5
+ Currently, more than 100 committers have contributed to this project, making this
6
+ contributors list really hard to maintain, so we have decided to stop updating
7
+ this list.
8
+
9
+ To see the people behind this code, you can run ``git shortlog -s -n`` or visit the
10
+ contributions section in Github: https://github.com/scrapinghub/dateparser/graphs/contributors
11
+
12
+ We really appreciate **all the people that has contributed to this project with their
13
+ time and ideas**. Special mention to **Waqas Shabir** (waqasshabbir), **Eugene Amirov**
14
+ (Allactaga) and **Artur Sadurski** (asadurski) for creating and maintaining this awesome
15
+ project.
16
+
17
+ To all of you... thank you for building and improving this!
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2014, Scrapinghub
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ * Neither the name of DateParser nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.