1 | """ |
---|
2 | Tests for allmydata.util.time_format. |
---|
3 | """ |
---|
4 | |
---|
5 | import time |
---|
6 | |
---|
7 | from twisted.trial import unittest |
---|
8 | |
---|
9 | from allmydata.test.common_util import TimezoneMixin |
---|
10 | from allmydata.util import time_format |
---|
11 | |
---|
12 | |
---|
13 | class TimeFormat(unittest.TestCase, TimezoneMixin): |
---|
14 | def test_epoch(self): |
---|
15 | return self._help_test_epoch() |
---|
16 | |
---|
17 | def test_epoch_in_London(self): |
---|
18 | # Europe/London is a particularly troublesome timezone. Nowadays, its |
---|
19 | # offset from GMT is 0. But in 1970, its offset from GMT was 1. |
---|
20 | # (Apparently in 1970 Britain had redefined standard time to be GMT+1 |
---|
21 | # and stayed in standard time all year round, whereas today |
---|
22 | # Europe/London standard time is GMT and Europe/London Daylight |
---|
23 | # Savings Time is GMT+1.) The current implementation of |
---|
24 | # time_format.iso_utc_time_to_localseconds() breaks if the timezone is |
---|
25 | # Europe/London. (As soon as this unit test is done then I'll change |
---|
26 | # that implementation to something that works even in this case...) |
---|
27 | |
---|
28 | if not self.have_working_tzset(): |
---|
29 | raise unittest.SkipTest("This test can't be run on a platform without time.tzset().") |
---|
30 | |
---|
31 | self.setTimezone("Europe/London") |
---|
32 | return self._help_test_epoch() |
---|
33 | |
---|
34 | def _help_test_epoch(self): |
---|
35 | origtzname = time.tzname |
---|
36 | s = time_format.iso_utc_time_to_seconds("1970-01-01T00:00:01") |
---|
37 | self.failUnlessEqual(s, 1.0) |
---|
38 | s = time_format.iso_utc_time_to_seconds("1970-01-01_00:00:01") |
---|
39 | self.failUnlessEqual(s, 1.0) |
---|
40 | s = time_format.iso_utc_time_to_seconds("1970-01-01 00:00:01") |
---|
41 | self.failUnlessEqual(s, 1.0) |
---|
42 | |
---|
43 | self.failUnlessEqual(time_format.iso_utc(1.0), "1970-01-01_00:00:01") |
---|
44 | self.failUnlessEqual(time_format.iso_utc(1.0, sep=" "), |
---|
45 | "1970-01-01 00:00:01") |
---|
46 | |
---|
47 | now = time.time() |
---|
48 | isostr = time_format.iso_utc(now) |
---|
49 | timestamp = time_format.iso_utc_time_to_seconds(isostr) |
---|
50 | self.failUnlessEqual(int(timestamp), int(now)) |
---|
51 | |
---|
52 | def my_time(): |
---|
53 | return 1.0 |
---|
54 | self.failUnlessEqual(time_format.iso_utc(t=my_time), |
---|
55 | "1970-01-01_00:00:01") |
---|
56 | e = self.failUnlessRaises(ValueError, |
---|
57 | time_format.iso_utc_time_to_seconds, |
---|
58 | "invalid timestring") |
---|
59 | self.failUnless("not a complete ISO8601 timestamp" in str(e)) |
---|
60 | s = time_format.iso_utc_time_to_seconds("1970-01-01_00:00:01.500") |
---|
61 | self.failUnlessEqual(s, 1.5) |
---|
62 | |
---|
63 | # Look for daylight-savings-related errors. |
---|
64 | thatmomentinmarch = time_format.iso_utc_time_to_seconds("2009-03-20 21:49:02.226536") |
---|
65 | self.failUnlessEqual(thatmomentinmarch, 1237585742.226536) |
---|
66 | self.failUnlessEqual(origtzname, time.tzname) |
---|
67 | |
---|
68 | def test_iso_utc(self): |
---|
69 | when = 1266760143.7841301 |
---|
70 | out = time_format.iso_utc_date(when) |
---|
71 | self.failUnlessEqual(out, "2010-02-21") |
---|
72 | out = time_format.iso_utc_date(t=lambda: when) |
---|
73 | self.failUnlessEqual(out, "2010-02-21") |
---|
74 | out = time_format.iso_utc(when) |
---|
75 | self.failUnlessEqual(out, "2010-02-21_13:49:03.784130") |
---|
76 | out = time_format.iso_utc(when, sep="-") |
---|
77 | self.failUnlessEqual(out, "2010-02-21-13:49:03.784130") |
---|
78 | |
---|
79 | def test_parse_duration(self): |
---|
80 | p = time_format.parse_duration |
---|
81 | DAY = 24*60*60 |
---|
82 | MONTH = 31*DAY |
---|
83 | YEAR = 365*DAY |
---|
84 | |
---|
85 | # seconds |
---|
86 | self.failUnlessEqual(p("1s"), 1) |
---|
87 | self.failUnlessEqual(p("12 s"), 12) |
---|
88 | self.failUnlessEqual(p("333second"), 333) |
---|
89 | self.failUnlessEqual(p(" 333 second "), 333) |
---|
90 | self.failUnlessEqual(p("5 seconds"), 5) |
---|
91 | self.failUnlessEqual(p("60 SECONDS"), 60) |
---|
92 | self.failUnlessEqual(p("86400s"), DAY) |
---|
93 | |
---|
94 | # days |
---|
95 | self.failUnlessEqual(p("1 day"), DAY) |
---|
96 | self.failUnlessEqual(p("2 days"), 2*DAY) |
---|
97 | self.failUnlessEqual(p("5days"), 5*DAY) |
---|
98 | self.failUnlessEqual(p("7days"), 7*DAY) |
---|
99 | self.failUnlessEqual(p("31day"), 31*DAY) |
---|
100 | self.failUnlessEqual(p("60 days"), 60*DAY) |
---|
101 | self.failUnlessEqual(p("70 DAYS"), 70*DAY) |
---|
102 | |
---|
103 | # months |
---|
104 | self.failUnlessEqual(p("4 mo"), 4*MONTH) |
---|
105 | self.failUnlessEqual(p("2mo"), 2*MONTH) |
---|
106 | self.failUnlessEqual(p("3 month"), 3*MONTH) |
---|
107 | self.failUnlessEqual(p("3 months"), 3*MONTH) |
---|
108 | |
---|
109 | # years |
---|
110 | self.failUnlessEqual(p("5 years"), 5*YEAR) |
---|
111 | self.failUnlessEqual(p("8 year"), 8*YEAR) |
---|
112 | self.failUnlessEqual(p("2years"), 2*YEAR) |
---|
113 | self.failUnlessEqual(p("11YEARS"), 11*YEAR) |
---|
114 | |
---|
115 | # errors |
---|
116 | e = self.failUnlessRaises(ValueError, p, "123") |
---|
117 | self.failUnlessIn("No valid unit in",str(e)) |
---|
118 | e = self.failUnlessRaises(ValueError, p, "2kumquats") |
---|
119 | self.failUnlessIn("No valid unit in", str(e)) |
---|
120 | |
---|
121 | def test_parse_date(self): |
---|
122 | p = time_format.parse_date |
---|
123 | self.failUnlessEqual(p("2010-02-21"), 1266710400) |
---|
124 | self.failUnless(isinstance(p("2009-03-18"), int), p("2009-03-18")) |
---|
125 | self.failUnlessEqual(p("2009-03-18"), 1237334400) |
---|
126 | |
---|
127 | def test_format_time(self): |
---|
128 | self.failUnlessEqual(time_format.format_time(time.gmtime(0)), '1970-01-01 00:00:00') |
---|
129 | self.failUnlessEqual(time_format.format_time(time.gmtime(60)), '1970-01-01 00:01:00') |
---|
130 | self.failUnlessEqual(time_format.format_time(time.gmtime(60*60)), '1970-01-01 01:00:00') |
---|
131 | seconds_per_day = 60*60*24 |
---|
132 | leap_years_1970_to_2014_inclusive = ((2012 - 1968) // 4) |
---|
133 | self.failUnlessEqual(time_format.format_time(time.gmtime(seconds_per_day*((2015 - 1970)*365+leap_years_1970_to_2014_inclusive))), '2015-01-01 00:00:00') |
---|
134 | |
---|
135 | def test_format_time_y2038(self): |
---|
136 | seconds_per_day = 60*60*24 |
---|
137 | leap_years_1970_to_2047_inclusive = ((2044 - 1968) // 4) |
---|
138 | t = (seconds_per_day* |
---|
139 | ((2048 - 1970)*365 + leap_years_1970_to_2047_inclusive)) |
---|
140 | try: |
---|
141 | gm_t = time.gmtime(t) |
---|
142 | except ValueError: |
---|
143 | raise unittest.SkipTest("Note: this system cannot handle dates after 2037.") |
---|
144 | self.failUnlessEqual(time_format.format_time(gm_t), |
---|
145 | '2048-01-01 00:00:00') |
---|
146 | |
---|
147 | def test_format_delta(self): |
---|
148 | time_1 = 1389812723 |
---|
149 | time_5s_delta = 1389812728 |
---|
150 | time_28m7s_delta = 1389814410 |
---|
151 | time_1h_delta = 1389816323 |
---|
152 | time_1d21h46m49s_delta = 1389977532 |
---|
153 | |
---|
154 | self.failUnlessEqual( |
---|
155 | time_format.format_delta(time_1, time_1), '0s') |
---|
156 | |
---|
157 | self.failUnlessEqual( |
---|
158 | time_format.format_delta(time_1, time_5s_delta), '5s') |
---|
159 | self.failUnlessEqual( |
---|
160 | time_format.format_delta(time_1, time_28m7s_delta), '28m 7s') |
---|
161 | self.failUnlessEqual( |
---|
162 | time_format.format_delta(time_1, time_1h_delta), '1h 0m 0s') |
---|
163 | self.failUnlessEqual( |
---|
164 | time_format.format_delta(time_1, time_1d21h46m49s_delta), '1d 21h 46m 49s') |
---|
165 | |
---|
166 | self.failUnlessEqual( |
---|
167 | time_format.format_delta(time_1d21h46m49s_delta, time_1), '-') |
---|
168 | |
---|
169 | # time_1 with a decimal fraction will make the delta 1s less |
---|
170 | time_1decimal = 1389812723.383963 |
---|
171 | |
---|
172 | self.failUnlessEqual( |
---|
173 | time_format.format_delta(time_1decimal, time_5s_delta), '4s') |
---|
174 | self.failUnlessEqual( |
---|
175 | time_format.format_delta(time_1decimal, time_28m7s_delta), '28m 6s') |
---|
176 | self.failUnlessEqual( |
---|
177 | time_format.format_delta(time_1decimal, time_1h_delta), '59m 59s') |
---|
178 | self.failUnlessEqual( |
---|
179 | time_format.format_delta(time_1decimal, time_1d21h46m49s_delta), '1d 21h 46m 48s') |
---|