Add meta types.
[librarian.git] / src / librarian / meta / types / date.py
1 from datetime import date
2 import re
3 import time
4 from .base import MetaValue
5
6
7 class DateValue(MetaValue):
8     @classmethod
9     def from_text(cls, text):
10         """
11         Dates for digitization of pictures. It seems we need the following:
12         ranges:         '1350-1450',
13         centuries:      "XVIII w.'
14         half centuries/decades: '2 poł. XVIII w.', 'XVII w., l. 20'
15         later-then: 'po 1450'
16         circa 'ok. 1813-1814', 'ok.1876-ok.1886
17         turn: 1893/1894
18
19         For now we will translate this to some single date
20         losing information of course.
21         """
22         try:
23             # check out the "N. poł X w." syntax
24             century_format = (
25                 "(?:([12]) *poł[.]? +)?([MCDXVI]+) *w[.,]*(?: *l[.]? *([0-9]+))?"
26             )
27             vague_format = "(?:po *|ok. *)?([0-9]{4})(-[0-9]{2}-[0-9]{2})?"
28
29             m = re.match(century_format, text)
30             m2 = re.match(vague_format, text)
31             if m:
32                 half = m.group(1)
33                 decade = m.group(3)
34                 century = roman_to_int(m.group(2))
35                 if half is not None:
36                     if decade is not None:
37                         raise ValueError(
38                             "Bad date format. "
39                             "Cannot specify both half and decade of century."
40                         )
41                     half = int(half)
42                     t = ((century*100 + (half-1)*50), 1, 1)
43                 else:
44                     decade = int(decade or 0)
45                     t = ((century*100 + decade), 1, 1)
46             elif m2:
47                 year = m2.group(1)
48                 mon_day = m2.group(2)
49                 if mon_day:
50                     t = time.strptime(year + mon_day, "%Y-%m-%d")
51                 else:
52                     t = time.strptime(year, '%Y')
53             else:
54                 raise ValueError
55
56             return cls(date(t[0], t[1], t[2]))
57         except ValueError:
58             raise ValueError("Unrecognized date format. Try YYYY-MM-DD or YYYY.")