from datetime import date, datetime from django.forms import DateTimeField, ValidationError from django.test import SimpleTestCase from django.utils.timezone import get_fixed_timezone, utc class DateTimeFieldTest(SimpleTestCase): def test_datetimefield_clean(self): tests = [ (date(2006, 10, 25), datetime(2006, 10, 25, 0, 0)), (datetime(2006, 10, 25, 14, 30), datetime(2006, 10, 25, 14, 30)), (datetime(2006, 10, 25, 14, 30, 59), datetime(2006, 10, 25, 14, 30, 59)), ( datetime(2006, 10, 25, 14, 30, 59, 200), datetime(2006, 10, 25, 14, 30, 59, 200), ), ('2006-10-25 14:30:45.000200', datetime(2006, 10, 25, 14, 30, 45, 200)), ('2006-10-25 14:30:45.0002', datetime(2006, 10, 25, 14, 30, 45, 200)), ('2006-10-25 14:30:45', datetime(2006, 10, 25, 14, 30, 45)), ('2006-10-25 14:30:00', datetime(2006, 10, 25, 14, 30)), ('2006-10-25 14:30', datetime(2006, 10, 25, 14, 30)), ('2006-10-25', datetime(2006, 10, 25, 0, 0)), ('10/25/2006 14:30:45.000200', datetime(2006, 10, 25, 14, 30, 45, 200)), ('10/25/2006 14:30:45', datetime(2006, 10, 25, 14, 30, 45)), ('10/25/2006 14:30:00', datetime(2006, 10, 25, 14, 30)), ('10/25/2006 14:30', datetime(2006, 10, 25, 14, 30)), ('10/25/2006', datetime(2006, 10, 25, 0, 0)), ('10/25/06 14:30:45.000200', datetime(2006, 10, 25, 14, 30, 45, 200)), ('10/25/06 14:30:45', datetime(2006, 10, 25, 14, 30, 45)), ('10/25/06 14:30:00', datetime(2006, 10, 25, 14, 30)), ('10/25/06 14:30', datetime(2006, 10, 25, 14, 30)), ('10/25/06', datetime(2006, 10, 25, 0, 0)), # ISO 8601 formats. ( '2014-09-23T22:34:41.614804', datetime(2014, 9, 23, 22, 34, 41, 614804), ), ('2014-09-23T22:34:41', datetime(2014, 9, 23, 22, 34, 41)), ('2014-09-23T22:34', datetime(2014, 9, 23, 22, 34)), ('2014-09-23', datetime(2014, 9, 23, 0, 0)), ('2014-09-23T22:34Z', datetime(2014, 9, 23, 22, 34, tzinfo=utc)), ( '2014-09-23T22:34+07:00', datetime(2014, 9, 23, 22, 34, tzinfo=get_fixed_timezone(420)), ), # Whitespace stripping. (' 2006-10-25 14:30:45 ', datetime(2006, 10, 25, 14, 30, 45)), (' 2006-10-25 ', datetime(2006, 10, 25, 0, 0)), (' 10/25/2006 14:30:45 ', datetime(2006, 10, 25, 14, 30, 45)), (' 10/25/2006 14:30 ', datetime(2006, 10, 25, 14, 30)), (' 10/25/2006 ', datetime(2006, 10, 25, 0, 0)), (' 10/25/06 14:30:45 ', datetime(2006, 10, 25, 14, 30, 45)), (' 10/25/06 ', datetime(2006, 10, 25, 0, 0)), ( ' 2014-09-23T22:34:41.614804 ', datetime(2014, 9, 23, 22, 34, 41, 614804), ), (' 2014-09-23T22:34Z ', datetime(2014, 9, 23, 22, 34, tzinfo=utc)), ] f = DateTimeField() for value, expected_datetime in tests: with self.subTest(value=value): self.assertEqual(f.clean(value), expected_datetime) def test_datetimefield_clean_invalid(self): f = DateTimeField() msg = "'Enter a valid date/time.'" with self.assertRaisesMessage(ValidationError, msg): f.clean('hello') with self.assertRaisesMessage(ValidationError, msg): f.clean('2006-10-25 4:30 p.m.') with self.assertRaisesMessage(ValidationError, msg): f.clean(' ') with self.assertRaisesMessage(ValidationError, msg): f.clean('2014-09-23T28:23') f = DateTimeField(input_formats=['%Y %m %d %I:%M %p']) with self.assertRaisesMessage(ValidationError, msg): f.clean('2006.10.25 14:30:45') def test_datetimefield_clean_input_formats(self): tests = [ ('%Y %m %d %I:%M %p', ( (date(2006, 10, 25), datetime(2006, 10, 25, 0, 0)), (datetime(2006, 10, 25, 14, 30), datetime(2006, 10, 25, 14, 30)), ( datetime(2006, 10, 25, 14, 30, 59), datetime(2006, 10, 25, 14, 30, 59), ), ( datetime(2006, 10, 25, 14, 30, 59, 200), datetime(2006, 10, 25, 14, 30, 59, 200), ), ('2006 10 25 2:30 PM', datetime(2006, 10, 25, 14, 30)), # ISO-like formats are always accepted. ('2006-10-25 14:30:45', datetime(2006, 10, 25, 14, 30, 45)), )), ('%Y.%m.%d %H:%M:%S.%f', ( ( '2006.10.25 14:30:45.0002', datetime(2006, 10, 25, 14, 30, 45, 200), ), )), ] f = DateTimeField() for input_format, values in tests: f = DateTimeField(input_formats=[input_format]) for value, expected_datetime in values: with self.subTest(value=value, input_format=input_format): self.assertEqual(f.clean(value), expected_datetime) def test_datetimefield_not_required(self): f = DateTimeField(required=False) self.assertIsNone(f.clean(None)) self.assertEqual('None', repr(f.clean(None))) self.assertIsNone(f.clean('')) self.assertEqual('None', repr(f.clean(''))) def test_datetimefield_changed(self): f = DateTimeField(input_formats=['%Y %m %d %I:%M %p']) d = datetime(2006, 9, 17, 14, 30, 0) self.assertFalse(f.has_changed(d, '2006 09 17 2:30 PM'))