1import datetime 2from email import utils 3import test.support 4import time 5import unittest 6import sys 7import os.path 8 9class DateTimeTests(unittest.TestCase): 10 11 datestring = 'Sun, 23 Sep 2001 20:10:55' 12 dateargs = (2001, 9, 23, 20, 10, 55) 13 offsetstring = ' -0700' 14 utcoffset = datetime.timedelta(hours=-7) 15 tz = datetime.timezone(utcoffset) 16 naive_dt = datetime.datetime(*dateargs) 17 aware_dt = datetime.datetime(*dateargs, tzinfo=tz) 18 19 def test_naive_datetime(self): 20 self.assertEqual(utils.format_datetime(self.naive_dt), 21 self.datestring + ' -0000') 22 23 def test_aware_datetime(self): 24 self.assertEqual(utils.format_datetime(self.aware_dt), 25 self.datestring + self.offsetstring) 26 27 def test_usegmt(self): 28 utc_dt = datetime.datetime(*self.dateargs, 29 tzinfo=datetime.timezone.utc) 30 self.assertEqual(utils.format_datetime(utc_dt, usegmt=True), 31 self.datestring + ' GMT') 32 33 def test_usegmt_with_naive_datetime_raises(self): 34 with self.assertRaises(ValueError): 35 utils.format_datetime(self.naive_dt, usegmt=True) 36 37 def test_usegmt_with_non_utc_datetime_raises(self): 38 with self.assertRaises(ValueError): 39 utils.format_datetime(self.aware_dt, usegmt=True) 40 41 def test_parsedate_to_datetime(self): 42 self.assertEqual( 43 utils.parsedate_to_datetime(self.datestring + self.offsetstring), 44 self.aware_dt) 45 46 def test_parsedate_to_datetime_naive(self): 47 self.assertEqual( 48 utils.parsedate_to_datetime(self.datestring + ' -0000'), 49 self.naive_dt) 50 51 def test_parsedate_to_datetime_with_invalid_raises_valueerror(self): 52 # See also test_parsedate_returns_None_for_invalid_strings in test_email. 53 invalid_dates = [ 54 '', 55 ' ', 56 '0', 57 'A Complete Waste of Time', 58 'Wed, 3 Apr 2002 12.34.56.78+0800' 59 'Tue, 06 Jun 2017 27:39:33 +0600', 60 'Tue, 06 Jun 2017 07:39:33 +2600', 61 'Tue, 06 Jun 2017 27:39:33', 62 '17 June , 2022', 63 'Friday, -Nov-82 16:14:55 EST', 64 'Friday, Nov--82 16:14:55 EST', 65 'Friday, 19-Nov- 16:14:55 EST', 66 ] 67 for dtstr in invalid_dates: 68 with self.subTest(dtstr=dtstr): 69 self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr) 70 71class LocaltimeTests(unittest.TestCase): 72 73 def test_localtime_is_tz_aware_daylight_true(self): 74 test.support.patch(self, time, 'daylight', True) 75 t = utils.localtime() 76 self.assertIsNotNone(t.tzinfo) 77 78 def test_localtime_is_tz_aware_daylight_false(self): 79 test.support.patch(self, time, 'daylight', False) 80 t = utils.localtime() 81 self.assertIsNotNone(t.tzinfo) 82 83 def test_localtime_daylight_true_dst_false(self): 84 test.support.patch(self, time, 'daylight', True) 85 t0 = datetime.datetime(2012, 3, 12, 1, 1) 86 t1 = utils.localtime(t0, isdst=-1) 87 t2 = utils.localtime(t1) 88 self.assertEqual(t1, t2) 89 90 def test_localtime_daylight_false_dst_false(self): 91 test.support.patch(self, time, 'daylight', False) 92 t0 = datetime.datetime(2012, 3, 12, 1, 1) 93 t1 = utils.localtime(t0, isdst=-1) 94 t2 = utils.localtime(t1) 95 self.assertEqual(t1, t2) 96 97 @test.support.run_with_tz('Europe/Minsk') 98 def test_localtime_daylight_true_dst_true(self): 99 test.support.patch(self, time, 'daylight', True) 100 t0 = datetime.datetime(2012, 3, 12, 1, 1) 101 t1 = utils.localtime(t0, isdst=1) 102 t2 = utils.localtime(t1) 103 self.assertEqual(t1, t2) 104 105 @test.support.run_with_tz('Europe/Minsk') 106 def test_localtime_daylight_false_dst_true(self): 107 test.support.patch(self, time, 'daylight', False) 108 t0 = datetime.datetime(2012, 3, 12, 1, 1) 109 t1 = utils.localtime(t0, isdst=1) 110 t2 = utils.localtime(t1) 111 self.assertEqual(t1, t2) 112 113 @test.support.run_with_tz('EST+05EDT,M3.2.0,M11.1.0') 114 def test_localtime_epoch_utc_daylight_true(self): 115 test.support.patch(self, time, 'daylight', True) 116 t0 = datetime.datetime(1990, 1, 1, tzinfo = datetime.timezone.utc) 117 t1 = utils.localtime(t0) 118 t2 = t0 - datetime.timedelta(hours=5) 119 t2 = t2.replace(tzinfo = datetime.timezone(datetime.timedelta(hours=-5))) 120 self.assertEqual(t1, t2) 121 122 @test.support.run_with_tz('EST+05EDT,M3.2.0,M11.1.0') 123 def test_localtime_epoch_utc_daylight_false(self): 124 test.support.patch(self, time, 'daylight', False) 125 t0 = datetime.datetime(1990, 1, 1, tzinfo = datetime.timezone.utc) 126 t1 = utils.localtime(t0) 127 t2 = t0 - datetime.timedelta(hours=5) 128 t2 = t2.replace(tzinfo = datetime.timezone(datetime.timedelta(hours=-5))) 129 self.assertEqual(t1, t2) 130 131 def test_localtime_epoch_notz_daylight_true(self): 132 test.support.patch(self, time, 'daylight', True) 133 t0 = datetime.datetime(1990, 1, 1) 134 t1 = utils.localtime(t0) 135 t2 = utils.localtime(t0.replace(tzinfo=None)) 136 self.assertEqual(t1, t2) 137 138 def test_localtime_epoch_notz_daylight_false(self): 139 test.support.patch(self, time, 'daylight', False) 140 t0 = datetime.datetime(1990, 1, 1) 141 t1 = utils.localtime(t0) 142 t2 = utils.localtime(t0.replace(tzinfo=None)) 143 self.assertEqual(t1, t2) 144 145 # XXX: Need a more robust test for Olson's tzdata 146 @unittest.skipIf(sys.platform.startswith('win'), 147 "Windows does not use Olson's TZ database") 148 @unittest.skipUnless(os.path.exists('/usr/share/zoneinfo') or 149 os.path.exists('/usr/lib/zoneinfo'), 150 "Can't find the Olson's TZ database") 151 @test.support.run_with_tz('Europe/Kiev') 152 def test_variable_tzname(self): 153 t0 = datetime.datetime(1984, 1, 1, tzinfo=datetime.timezone.utc) 154 t1 = utils.localtime(t0) 155 self.assertEqual(t1.tzname(), 'MSK') 156 t0 = datetime.datetime(1994, 1, 1, tzinfo=datetime.timezone.utc) 157 t1 = utils.localtime(t0) 158 self.assertEqual(t1.tzname(), 'EET') 159 160# Issue #24836: The timezone files are out of date (pre 2011k) 161# on Mac OS X Snow Leopard. 162@test.support.requires_mac_ver(10, 7) 163class FormatDateTests(unittest.TestCase): 164 165 @test.support.run_with_tz('Europe/Minsk') 166 def test_formatdate(self): 167 timeval = time.mktime((2011, 12, 1, 18, 0, 0, 4, 335, 0)) 168 string = utils.formatdate(timeval, localtime=False, usegmt=False) 169 self.assertEqual(string, 'Thu, 01 Dec 2011 15:00:00 -0000') 170 string = utils.formatdate(timeval, localtime=False, usegmt=True) 171 self.assertEqual(string, 'Thu, 01 Dec 2011 15:00:00 GMT') 172 173 @test.support.run_with_tz('Europe/Minsk') 174 def test_formatdate_with_localtime(self): 175 timeval = time.mktime((2011, 1, 1, 18, 0, 0, 6, 1, 0)) 176 string = utils.formatdate(timeval, localtime=True) 177 self.assertEqual(string, 'Sat, 01 Jan 2011 18:00:00 +0200') 178 # Minsk moved from +0200 (with DST) to +0300 (without DST) in 2011 179 timeval = time.mktime((2011, 12, 1, 18, 0, 0, 4, 335, 0)) 180 string = utils.formatdate(timeval, localtime=True) 181 self.assertEqual(string, 'Thu, 01 Dec 2011 18:00:00 +0300') 182 183if __name__ == '__main__': 184 unittest.main() 185