1from test import test_support 2import time 3import unittest 4import sys 5import sysconfig 6 7 8# Max year is only limited by the size of C int. 9SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4 10TIME_MAXYEAR = (1 << 8 * SIZEOF_INT - 1) - 1 11 12 13class TimeTestCase(unittest.TestCase): 14 15 def setUp(self): 16 self.t = time.time() 17 18 def test_data_attributes(self): 19 time.altzone 20 time.daylight 21 time.timezone 22 time.tzname 23 24 def test_clock(self): 25 time.clock() 26 27 def test_conversions(self): 28 self.assertTrue(time.ctime(self.t) 29 == time.asctime(time.localtime(self.t))) 30 self.assertTrue(long(time.mktime(time.localtime(self.t))) 31 == long(self.t)) 32 33 def test_sleep(self): 34 time.sleep(1.2) 35 36 def test_strftime(self): 37 tt = time.gmtime(self.t) 38 for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', 39 'j', 'm', 'M', 'p', 'S', 40 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): 41 format = ' %' + directive 42 try: 43 time.strftime(format, tt) 44 except ValueError: 45 self.fail('conversion specifier: %r failed.' % format) 46 47 # Issue #10762: Guard against invalid/non-supported format string 48 # so that Python don't crash (Windows crashes when the format string 49 # input to [w]strftime is not kosher. 50 if sys.platform.startswith('win'): 51 with self.assertRaises(ValueError): 52 time.strftime('%f') 53 54 def _bounds_checking(self, func): 55 # Make sure that strftime() checks the bounds of the various parts 56 # of the time tuple (0 is valid for *all* values). 57 58 # The year field is tested by other test cases above 59 60 # Check month [1, 12] + zero support 61 func((1900, 0, 1, 0, 0, 0, 0, 1, -1)) 62 func((1900, 12, 1, 0, 0, 0, 0, 1, -1)) 63 self.assertRaises(ValueError, func, 64 (1900, -1, 1, 0, 0, 0, 0, 1, -1)) 65 self.assertRaises(ValueError, func, 66 (1900, 13, 1, 0, 0, 0, 0, 1, -1)) 67 # Check day of month [1, 31] + zero support 68 func((1900, 1, 0, 0, 0, 0, 0, 1, -1)) 69 func((1900, 1, 31, 0, 0, 0, 0, 1, -1)) 70 self.assertRaises(ValueError, func, 71 (1900, 1, -1, 0, 0, 0, 0, 1, -1)) 72 self.assertRaises(ValueError, func, 73 (1900, 1, 32, 0, 0, 0, 0, 1, -1)) 74 # Check hour [0, 23] 75 func((1900, 1, 1, 23, 0, 0, 0, 1, -1)) 76 self.assertRaises(ValueError, func, 77 (1900, 1, 1, -1, 0, 0, 0, 1, -1)) 78 self.assertRaises(ValueError, func, 79 (1900, 1, 1, 24, 0, 0, 0, 1, -1)) 80 # Check minute [0, 59] 81 func((1900, 1, 1, 0, 59, 0, 0, 1, -1)) 82 self.assertRaises(ValueError, func, 83 (1900, 1, 1, 0, -1, 0, 0, 1, -1)) 84 self.assertRaises(ValueError, func, 85 (1900, 1, 1, 0, 60, 0, 0, 1, -1)) 86 # Check second [0, 61] 87 self.assertRaises(ValueError, func, 88 (1900, 1, 1, 0, 0, -1, 0, 1, -1)) 89 # C99 only requires allowing for one leap second, but Python's docs say 90 # allow two leap seconds (0..61) 91 func((1900, 1, 1, 0, 0, 60, 0, 1, -1)) 92 func((1900, 1, 1, 0, 0, 61, 0, 1, -1)) 93 self.assertRaises(ValueError, func, 94 (1900, 1, 1, 0, 0, 62, 0, 1, -1)) 95 # No check for upper-bound day of week; 96 # value forced into range by a ``% 7`` calculation. 97 # Start check at -2 since gettmarg() increments value before taking 98 # modulo. 99 self.assertEqual(func((1900, 1, 1, 0, 0, 0, -1, 1, -1)), 100 func((1900, 1, 1, 0, 0, 0, +6, 1, -1))) 101 self.assertRaises(ValueError, func, 102 (1900, 1, 1, 0, 0, 0, -2, 1, -1)) 103 # Check day of the year [1, 366] + zero support 104 func((1900, 1, 1, 0, 0, 0, 0, 0, -1)) 105 func((1900, 1, 1, 0, 0, 0, 0, 366, -1)) 106 self.assertRaises(ValueError, func, 107 (1900, 1, 1, 0, 0, 0, 0, -1, -1)) 108 self.assertRaises(ValueError, func, 109 (1900, 1, 1, 0, 0, 0, 0, 367, -1)) 110 111 def test_strftime_bounding_check(self): 112 self._bounds_checking(lambda tup: time.strftime('', tup)) 113 114 def test_strftime_bounds_checking(self): 115 # Make sure that strftime() checks the bounds of the various parts 116 #of the time tuple (0 is valid for *all* values). 117 118 # Check year [1900, max(int)] 119 self.assertRaises(ValueError, time.strftime, '', 120 (1899, 1, 1, 0, 0, 0, 0, 1, -1)) 121 if time.accept2dyear: 122 self.assertRaises(ValueError, time.strftime, '', 123 (-1, 1, 1, 0, 0, 0, 0, 1, -1)) 124 self.assertRaises(ValueError, time.strftime, '', 125 (100, 1, 1, 0, 0, 0, 0, 1, -1)) 126 # Check month [1, 12] + zero support 127 self.assertRaises(ValueError, time.strftime, '', 128 (1900, -1, 1, 0, 0, 0, 0, 1, -1)) 129 self.assertRaises(ValueError, time.strftime, '', 130 (1900, 13, 1, 0, 0, 0, 0, 1, -1)) 131 # Check day of month [1, 31] + zero support 132 self.assertRaises(ValueError, time.strftime, '', 133 (1900, 1, -1, 0, 0, 0, 0, 1, -1)) 134 self.assertRaises(ValueError, time.strftime, '', 135 (1900, 1, 32, 0, 0, 0, 0, 1, -1)) 136 # Check hour [0, 23] 137 self.assertRaises(ValueError, time.strftime, '', 138 (1900, 1, 1, -1, 0, 0, 0, 1, -1)) 139 self.assertRaises(ValueError, time.strftime, '', 140 (1900, 1, 1, 24, 0, 0, 0, 1, -1)) 141 # Check minute [0, 59] 142 self.assertRaises(ValueError, time.strftime, '', 143 (1900, 1, 1, 0, -1, 0, 0, 1, -1)) 144 self.assertRaises(ValueError, time.strftime, '', 145 (1900, 1, 1, 0, 60, 0, 0, 1, -1)) 146 # Check second [0, 61] 147 self.assertRaises(ValueError, time.strftime, '', 148 (1900, 1, 1, 0, 0, -1, 0, 1, -1)) 149 # C99 only requires allowing for one leap second, but Python's docs say 150 # allow two leap seconds (0..61) 151 self.assertRaises(ValueError, time.strftime, '', 152 (1900, 1, 1, 0, 0, 62, 0, 1, -1)) 153 # No check for upper-bound day of week; 154 # value forced into range by a ``% 7`` calculation. 155 # Start check at -2 since gettmarg() increments value before taking 156 # modulo. 157 self.assertRaises(ValueError, time.strftime, '', 158 (1900, 1, 1, 0, 0, 0, -2, 1, -1)) 159 # Check day of the year [1, 366] + zero support 160 self.assertRaises(ValueError, time.strftime, '', 161 (1900, 1, 1, 0, 0, 0, 0, -1, -1)) 162 self.assertRaises(ValueError, time.strftime, '', 163 (1900, 1, 1, 0, 0, 0, 0, 367, -1)) 164 165 def test_default_values_for_zero(self): 166 # Make sure that using all zeros uses the proper default values. 167 # No test for daylight savings since strftime() does not change output 168 # based on its value. 169 expected = "2000 01 01 00 00 00 1 001" 170 result = time.strftime("%Y %m %d %H %M %S %w %j", (0,)*9) 171 self.assertEqual(expected, result) 172 173 def test_strptime(self): 174 # Should be able to go round-trip from strftime to strptime without 175 # raising an exception. 176 tt = time.gmtime(self.t) 177 for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', 178 'j', 'm', 'M', 'p', 'S', 179 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): 180 format = '%' + directive 181 strf_output = time.strftime(format, tt) 182 try: 183 time.strptime(strf_output, format) 184 except ValueError: 185 self.fail("conversion specifier %r failed with '%s' input." % 186 (format, strf_output)) 187 188 def test_asctime(self): 189 time.asctime(time.gmtime(self.t)) 190 self.assertRaises(TypeError, time.asctime, 0) 191 self.assertRaises(TypeError, time.asctime, ()) 192 193 # Max year is only limited by the size of C int. 194 asc = time.asctime((TIME_MAXYEAR, 6, 1) + (0,) * 6) 195 self.assertEqual(asc[-len(str(TIME_MAXYEAR)):], str(TIME_MAXYEAR)) 196 self.assertRaises(OverflowError, time.asctime, 197 (TIME_MAXYEAR + 1,) + (0,) * 8) 198 self.assertRaises(TypeError, time.asctime, 0) 199 self.assertRaises(TypeError, time.asctime, ()) 200 self.assertRaises(TypeError, time.asctime, (0,) * 10) 201 202 @unittest.skipIf(not hasattr(time, "tzset"), 203 "time module has no attribute tzset") 204 def test_tzset(self): 205 206 from os import environ 207 208 # Epoch time of midnight Dec 25th 2002. Never DST in northern 209 # hemisphere. 210 xmas2002 = 1040774400.0 211 212 # These formats are correct for 2002, and possibly future years 213 # This format is the 'standard' as documented at: 214 # http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html 215 # They are also documented in the tzset(3) man page on most Unix 216 # systems. 217 eastern = 'EST+05EDT,M4.1.0,M10.5.0' 218 victoria = 'AEST-10AEDT-11,M10.5.0,M3.5.0' 219 utc='UTC+0' 220 221 org_TZ = environ.get('TZ',None) 222 try: 223 # Make sure we can switch to UTC time and results are correct 224 # Note that unknown timezones default to UTC. 225 # Note that altzone is undefined in UTC, as there is no DST 226 environ['TZ'] = eastern 227 time.tzset() 228 environ['TZ'] = utc 229 time.tzset() 230 self.assertEqual( 231 time.gmtime(xmas2002), time.localtime(xmas2002) 232 ) 233 self.assertEqual(time.daylight, 0) 234 self.assertEqual(time.timezone, 0) 235 self.assertEqual(time.localtime(xmas2002).tm_isdst, 0) 236 237 # Make sure we can switch to US/Eastern 238 environ['TZ'] = eastern 239 time.tzset() 240 self.assertNotEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) 241 self.assertEqual(time.tzname, ('EST', 'EDT')) 242 self.assertEqual(len(time.tzname), 2) 243 self.assertEqual(time.daylight, 1) 244 self.assertEqual(time.timezone, 18000) 245 self.assertEqual(time.altzone, 14400) 246 self.assertEqual(time.localtime(xmas2002).tm_isdst, 0) 247 self.assertEqual(len(time.tzname), 2) 248 249 # Now go to the southern hemisphere. 250 environ['TZ'] = victoria 251 time.tzset() 252 self.assertNotEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) 253 254 # Issue #11886: Australian Eastern Standard Time (UTC+10) is called 255 # "EST" (as Eastern Standard Time, UTC-5) instead of "AEST" on some 256 # operating systems (e.g. FreeBSD), which is wrong. See for example 257 # this bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=93810 258 self.assertIn(time.tzname[0], ('AEST' 'EST'), time.tzname[0]) 259 self.assertTrue(time.tzname[1] == 'AEDT', str(time.tzname[1])) 260 self.assertEqual(len(time.tzname), 2) 261 self.assertEqual(time.daylight, 1) 262 self.assertEqual(time.timezone, -36000) 263 self.assertEqual(time.altzone, -39600) 264 self.assertEqual(time.localtime(xmas2002).tm_isdst, 1) 265 266 finally: 267 # Repair TZ environment variable in case any other tests 268 # rely on it. 269 if org_TZ is not None: 270 environ['TZ'] = org_TZ 271 elif environ.has_key('TZ'): 272 del environ['TZ'] 273 time.tzset() 274 275 def test_insane_timestamps(self): 276 # It's possible that some platform maps time_t to double, 277 # and that this test will fail there. This test should 278 # exempt such platforms (provided they return reasonable 279 # results!). 280 for func in time.ctime, time.gmtime, time.localtime: 281 for unreasonable in -1e200, 1e200: 282 self.assertRaises(ValueError, func, unreasonable) 283 284 def test_ctime_without_arg(self): 285 # Not sure how to check the values, since the clock could tick 286 # at any time. Make sure these are at least accepted and 287 # don't raise errors. 288 time.ctime() 289 time.ctime(None) 290 291 def test_gmtime_without_arg(self): 292 gt0 = time.gmtime() 293 gt1 = time.gmtime(None) 294 t0 = time.mktime(gt0) 295 t1 = time.mktime(gt1) 296 self.assertTrue(0 <= (t1-t0) < 0.2) 297 298 def test_localtime_without_arg(self): 299 lt0 = time.localtime() 300 lt1 = time.localtime(None) 301 t0 = time.mktime(lt0) 302 t1 = time.mktime(lt1) 303 self.assertTrue(0 <= (t1-t0) < 0.2) 304 305 def test_mktime(self): 306 # Issue #1726687 307 for t in (-2, -1, 0, 1): 308 try: 309 tt = time.localtime(t) 310 except (OverflowError, ValueError): 311 pass 312 else: 313 self.assertEqual(time.mktime(tt), t) 314 315 316def test_main(): 317 test_support.run_unittest(TimeTestCase) 318 319 320if __name__ == "__main__": 321 test_main() 322