# Path: foil/dates.py
# def parse_date(date_str: str, pattern=_RE_DATE) -> dt.date:
#     """Parse datetime.date from YYYY-MM-DD format."""
# 
#     groups = re.match(pattern, date_str)
# 
#     return dt.date(*_date_to_tuple(groups.groupdict()))
# 
# class DateTimeParser:
# 
#     def __init__(self, pattern=_RE_DATETIMEZONE, tz_mapper=TIMEZONE_MAP):
#         self.pattern = pattern
#         self.tz_mapper = tz_mapper
# 
#     def parse(self, date_str) -> dt.datetime:
#         gd = self.pattern.match(date_str).groupdict()
# 
#         if gd['microsecond'] is not None:
#             gd['microsecond'] = (gd['microsecond'] + '000000')[:6]
# 
#         datetime_ = dt.datetime(*_datetime_to_tuple(gd))
# 
#         if gd.get('timezone') is not None:
#             datetime_ = self.convert_2_utc(datetime_, gd.get('timezone'))
# 
#         return datetime_
# 
#     def convert_2_utc(self, datetime_, timezone):
#         """convert to datetime to UTC offset."""
# 
#         datetime_ = self.tz_mapper[timezone].localize(datetime_)
#         return datetime_.astimezone(pytz.UTC)
# 
# def _datetime_to_tuple(dt_dict):
#     """datetime.datetime components from dictionary to tuple.
# 
#     Example
#     -------
#     dt_dict = {'year': '2014','month': '07','day': '23',
#             'hour': '13','minute': '12','second': '45','microsecond': '321'}
# 
#     _datetime_to_tuple(dt_dict) -> (2014, 7, 23, 13, 12, 45, 321)
#     """
# 
#     year, month, day = _date_to_tuple(dt_dict)
#     hour, minute, second, microsecond = _time_to_tuple(dt_dict)
# 
#     return year, month, day, hour, minute, second, microsecond


from datetime import datetime, date
from foil.dates import parse_date, DateTimeParser, _datetime_to_tuple
import pytz
import unittest
            data = t[0]
            expected = t[1]
            result = date_parser.parse(data)
            with self.subTest(data=data):
                self.assertEqual(expected, result)

    def test_parse_date(self):
        expected = date(2015, 4, 3)
        result = parse_date('2015-04-03')

        self.assertEqual(expected, result)

    def test_all_string_components(self):
        expected = (2014, 7, 3, 13, 2, 45, 321)
        result = _datetime_to_tuple(self.dt_dict)

        self.assertEqual(expected, result)

    def test_null_microsecond(self):
        self.dt_dict['microsecond'] = None

        expected = (2014, 7, 3, 13, 2, 45, 0)
        result = _datetime_to_tuple(self.dt_dict)

        self.assertEqual(expected, result)

    def test_no_microsecond(self):
        self.dt_dict['hour'] = None

        expected = (2014, 7, 3, 0, 2, 45, 321)

# Path: foil/dates.py
# def parse_date(date_str: str, pattern=_RE_DATE) -> dt.date:
#     """Parse datetime.date from YYYY-MM-DD format."""
# 
#     groups = re.match(pattern, date_str)
# 
#     return dt.date(*_date_to_tuple(groups.groupdict()))
# 
# class DateTimeParser:
# 
#     def __init__(self, pattern=_RE_DATETIMEZONE, tz_mapper=TIMEZONE_MAP):
#         self.pattern = pattern
#         self.tz_mapper = tz_mapper
# 
#     def parse(self, date_str) -> dt.datetime:
#         gd = self.pattern.match(date_str).groupdict()
# 
#         if gd['microsecond'] is not None:
#             gd['microsecond'] = (gd['microsecond'] + '000000')[:6]
# 
#         datetime_ = dt.datetime(*_datetime_to_tuple(gd))
# 
#         if gd.get('timezone') is not None:
#             datetime_ = self.convert_2_utc(datetime_, gd.get('timezone'))
# 
#         return datetime_
# 
#     def convert_2_utc(self, datetime_, timezone):
#         """convert to datetime to UTC offset."""
# 
#         datetime_ = self.tz_mapper[timezone].localize(datetime_)
#         return datetime_.astimezone(pytz.UTC)
# 
# def _datetime_to_tuple(dt_dict):
#     """datetime.datetime components from dictionary to tuple.
# 
#     Example
#     -------
#     dt_dict = {'year': '2014','month': '07','day': '23',
#             'hour': '13','minute': '12','second': '45','microsecond': '321'}
# 
#     _datetime_to_tuple(dt_dict) -> (2014, 7, 23, 13, 12, 45, 321)
#     """
# 
#     year, month, day = _date_to_tuple(dt_dict)
#     hour, minute, second, microsecond = _time_to_tuple(dt_dict)
# 
#     return year, month, day, hour, minute, second, microsecond


# Path: tests/test_dates.py
from datetime import datetime, date
from foil.dates import parse_date, DateTimeParser, _datetime_to_tuple
import pytz
import unittest

            data = t[0]
            expected = t[1]
            result = date_parser.parse(data)
            with self.subTest(data=data):
                self.assertEqual(expected, result)

    def test_parse_date(self):
        expected = date(2015, 4, 3)
        result = parse_date('2015-04-03')

        self.assertEqual(expected, result)

    def test_all_string_components(self):
        expected = (2014, 7, 3, 13, 2, 45, 321)
        result = _datetime_to_tuple(self.dt_dict)

        self.assertEqual(expected, result)

    def test_null_microsecond(self):
        self.dt_dict['microsecond'] = None

        expected = (2014, 7, 3, 13, 2, 45, 0)
        result = _datetime_to_tuple(self.dt_dict)

        self.assertEqual(expected, result)

    def test_no_microsecond(self):
        self.dt_dict['hour'] = None

        expected = (2014, 7, 3, 0, 2, 45, 321)

        result = _datetime_to_tuple(self.dt_dict)