diff options
| -rw-r--r-- | docs/field_types.rst | 4 | ||||
| -rw-r--r-- | lesana/types.py | 51 | ||||
| -rw-r--r-- | tests/test_types.py | 57 | 
3 files changed, 109 insertions, 3 deletions
| diff --git a/docs/field_types.rst b/docs/field_types.rst index baf2c5e..81e86ab 100644 --- a/docs/field_types.rst +++ b/docs/field_types.rst @@ -14,6 +14,10 @@ decimal:      .  timestamp:      . +datetime: +    . +date: +    .  boolean:      .  file: diff --git a/lesana/types.py b/lesana/types.py index 4d3910c..e5c556c 100644 --- a/lesana/types.py +++ b/lesana/types.py @@ -105,16 +105,39 @@ class LesanaDecimal(LesanaType):  class LesanaTimestamp(LesanaType):      """ -    A datetime +    A unix timestamp      """      name = "timestamp"      def load(self, data):          if not data:              return data -        if isinstance(data, datetime.datetime) or \ -                isinstance(data, datetime.date): +        if isinstance(data, datetime.datetime): +            return data +        try: +            return datetime.datetime.fromtimestamp(int(data)) +        except (TypeError, ValueError): +            raise LesanaValueError( +                "Invalid value for timestamp field: {}".format(data) +            ) + +    def empty(self): +        return None + + +class LesanaDatetime(LesanaType): +    """ +    A datetime +    """ +    name = "datetime" + +    def load(self, data): +        if not data: +            return data +        if isinstance(data, datetime.datetime):              return data +        if isinstance(data, datetime.date): +            return datetime.datetime(data.year, data.month, data.day)          try:              return dateutil.parser.parse(data)          except dateutil.parser.ParserError: @@ -126,6 +149,28 @@ class LesanaTimestamp(LesanaType):          return None +class LesanaDate(LesanaType): +    """ +    A date +    """ +    name = "date" + +    def load(self, data): +        if not data: +            return data +        if isinstance(data, datetime.date): +            return data +        try: +            return dateutil.parser.parse(data) +        except dateutil.parser.ParserError: +            raise LesanaValueError( +                "Invalid value for date field: {}".format(data) +            ) + +    def empty(self): +        return None + +  class LesanaBoolean(LesanaType):      """      A boolean value diff --git a/tests/test_types.py b/tests/test_types.py index cc2ff3b..2d6b744 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -119,6 +119,63 @@ class testTypes(unittest.TestCase):          v = checker.load(now)          self.assertEqual(v, now) +        v = checker.load("1600000000") +        self.assertEqual(v, datetime.datetime(2020, 9, 13, 14, 26, 40)) + +        today = datetime.date.today() +        for d in ( +            today, +            "today", +            "2020-13-01", "2020-01-01", +            "2020-01-01 10:00" +        ): +            with self.assertRaises(types.LesanaValueError): +                checker.load(d) + +        v = checker.load(None) +        self.assertEqual(v, None) + +    def test_datetime(self): +        checker = types.LesanaDatetime() + +        v = checker.empty() +        self.assertEqual(v, None) + +        now = datetime.datetime.now() +        v = checker.load(now) +        self.assertEqual(v, now) + +        today = datetime.date.today() +        v = checker.load(today) +        self.assertIsInstance(v, datetime.datetime) +        for part in ('year', 'month', 'day'): +            self.assertEqual(getattr(v, part), getattr(today, part)) + +        v = checker.load("2020-01-01") +        self.assertEqual(v, datetime.datetime(2020, 1, 1)) + +        v = checker.load("2020-01-01 10:00") +        self.assertEqual(v, datetime.datetime(2020, 1, 1, 10, 0)) + +        for d in ("today", "2020-13-01"): +            with self.assertRaises(types.LesanaValueError): +                checker.load(d) + +        v = checker.load(None) +        self.assertEqual(v, None) + +    def test_date(self): +        checker = types.LesanaDate() + +        v = checker.empty() +        self.assertEqual(v, None) + +        now = datetime.datetime.now() +        v = checker.load(now) +        self.assertIsInstance(v, datetime.date) +        for part in ('year', 'month', 'day'): +            self.assertEqual(getattr(v, part), getattr(now, part)) +          today = datetime.date.today()          v = checker.load(today)          self.assertEqual(v, today) | 
