|
1 | 1 | """ |
2 | 2 | Shared functions. |
3 | 3 | """ |
4 | | -from datetime import datetime |
| 4 | +import functools |
5 | 5 | import locale |
| 6 | +import os |
6 | 7 | import re |
| 8 | +from datetime import datetime |
7 | 9 | from typing import Union |
8 | | -import os |
9 | 10 |
|
10 | 11 |
|
11 | 12 | LRU_CACHE_SIZE = 32 |
12 | 13 | MAX_ATTEMPT_NUMBER = 5 |
13 | 14 |
|
14 | 15 |
|
| 16 | +@functools.lru_cache(maxsize=365) |
15 | 17 | def to_datetime(date_string: str, language: str) -> Union[datetime, str]: |
16 | 18 | """ Converts a date string to a datetime object """ |
17 | | - locales = {"pt": "pt_BR.utf-8", "en": "en_US.utf-8"} |
18 | | - |
19 | | - """ correct problem with locale in Windows platform """ |
20 | | - if os.name == 'nt': |
21 | | - locales = {"pt": "Portuguese_Brazil.1252", "en": "Portuguese_Brazil.1252"} |
22 | | - |
23 | | - locale.setlocale(locale.LC_TIME, locales[language]) |
24 | | - |
25 | | - dd_mm_aaaa = "%d/%m/%Y" |
26 | | - mmm_aaaa = "%b/%Y" |
27 | 19 |
|
28 | | - formats = [dd_mm_aaaa, mmm_aaaa] |
29 | | - |
30 | | - for fmt in formats: |
31 | | - try: |
32 | | - date = datetime.strptime(date_string, fmt) |
33 | | - break |
34 | | - except ValueError: |
35 | | - continue |
| 20 | + yyyy = "[0-9]{4}" |
| 21 | + mmm_yyyy = r"[a-z]{3}/[0-9]{4}" |
| 22 | + |
| 23 | + if re.match(yyyy, date_string): |
| 24 | + date = datetime(int(date_string), 12, 31) |
| 25 | + elif re.match(mmm_yyyy, date_string): |
| 26 | + month_text, year_text = date_string.split("/") |
| 27 | + months = [ |
| 28 | + ("jan", "jan"), ("fev", "feb"), ("mar", "mar"), |
| 29 | + ("abr", "apr"), ("mai", "may"), ("jun", "jun"), |
| 30 | + ("jul", "jul"), ("ago", "aug"), ("set", "sep"), |
| 31 | + ("out", "oct"), ("nov", "nov"), ("dez", "dec") |
| 32 | + ] |
| 33 | + for n, month_names in enumerate(months, 1): |
| 34 | + if month_text in month_names: |
| 35 | + month_number = n |
| 36 | + break |
| 37 | + date = datetime(int(year_text), month_number, 1) |
36 | 38 | else: |
37 | | - yyyy = "[0-9]{4}" |
38 | | - if re.match(yyyy, date_string): |
39 | | - year = int(date_string) |
40 | | - month = 12 |
41 | | - day = 31 |
| 39 | + try: |
| 40 | + day, month, year = [int(date_part) for date_part in date_string.split("/")] |
42 | 41 | date = datetime(year, month, day) |
43 | | - else: |
44 | | - return date_string # returns original value if cant parse |
45 | | - |
| 42 | + except ValueError: |
| 43 | + # return the original value if we cant parse it |
| 44 | + return date_string |
46 | 45 | return date |
0 commit comments