1#!/usr/bin/env python3
2
3import re
4
5from dateutil.relativedelta import relativedelta
6from datetime import date
7
8from _kosmorro.i18n.utils import _
9
10
11def parse_date(date_arg: str) -> date:
12    if re.match(r"^\d{4}-\d{2}-\d{2}$", date_arg):
13        try:
14            return date.fromisoformat(date_arg)
15        except ValueError as error:
16            raise ValueError(
17                _("The date {date} is not valid: {error}").format(
18                    date=date_arg, error=error.args[0]
19                )
20            ) from error
21    elif re.match(r"^([+-])(([0-9]+)y)?[ ]?(([0-9]+)m)?[ ]?(([0-9]+)d)?$", date_arg):
22
23        def get_offset(date_arg: str, signifier: str):
24            if re.search(r"([0-9]+)" + signifier, date_arg):
25                return abs(
26                    int(re.search(r"[+-]?([0-9]+)" + signifier, date_arg).group(0)[:-1])
27                )
28            return 0
29
30        days = get_offset(date_arg, "d")
31        months = get_offset(date_arg, "m")
32        years = get_offset(date_arg, "y")
33
34        if date_arg[0] == "+":
35            return date.today() + relativedelta(days=days, months=months, years=years)
36        return date.today() - relativedelta(days=days, months=months, years=years)
37
38    else:
39        error_msg = _(
40            "The date {date} does not match the required YYYY-MM-DD format or the offset format."
41        )
42        raise ValueError(error_msg.format(date=date_arg))
43