MDL-54008 tests: clarify comment in tz test
[moodle.git] / lib / tests / date_legacy_test.php
CommitLineData
e19b3710
PS
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Tests legacy Moodle date/time functions.
19 *
20 * @package core
21 * @copyright 2015 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 * @author Petr Skoda <petr.skoda@totaralms.com>
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28/**
29 * Tests legacy Moodle date/time functions.
d6e7a63d
PS
30 *
31 * @package core
32 * @copyright 2015 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34 * @author Petr Skoda <petr.skoda@totaralms.com>
e19b3710
PS
35 */
36class core_date_legacy_testcase extends advanced_testcase {
d6e7a63d
PS
37 public function test_settings() {
38 global $CFG;
39 $this->resetAfterTest();
40
41 $this->assertNotEmpty($CFG->timezone);
42
43 $this->assertSame('99', $CFG->forcetimezone);
44
45 $user = $this->getDataGenerator()->create_user();
46 $this->assertSame('99', $user->timezone);
47 }
48
e19b3710
PS
49 public function test_get_user_timezone() {
50 global $CFG, $USER;
51
52 $this->resetAfterTest();
53
54 $user = $this->getDataGenerator()->create_user();
55 $this->setUser($user);
56
57 // All set to something.
58
d6e7a63d 59 $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
e19b3710
PS
60 $USER->timezone = 'Europe/Prague';
61
62 $tz = get_user_timezone();
63 $this->assertSame('Europe/Prague', $tz);
64
65 $tz = get_user_timezone(99);
66 $this->assertSame('Europe/Prague', $tz);
67 $tz = get_user_timezone('99');
68 $this->assertSame('Europe/Prague', $tz);
69
70 $tz = get_user_timezone('Europe/Berlin');
71 $this->assertSame('Europe/Berlin', $tz);
72
73 // User timezone not set.
74
d6e7a63d 75 $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
e19b3710
PS
76 $USER->timezone = '99';
77
78 $tz = get_user_timezone();
79 $this->assertSame('Pacific/Auckland', $tz);
80
81 $tz = get_user_timezone(99);
82 $this->assertSame('Pacific/Auckland', $tz);
83 $tz = get_user_timezone('99');
84 $this->assertSame('Pacific/Auckland', $tz);
85
86 $tz = get_user_timezone('Europe/Berlin');
87 $this->assertSame('Europe/Berlin', $tz);
88
89 // Server timezone not set.
90
d6e7a63d 91 $this->setTimezone('99', 'Pacific/Auckland');
e19b3710
PS
92 $USER->timezone = 'Europe/Prague';
93
94 $tz = get_user_timezone();
95 $this->assertSame('Europe/Prague', $tz);
96
97 $tz = get_user_timezone(99);
98 $this->assertSame('Europe/Prague', $tz);
99 $tz = get_user_timezone('99');
100 $this->assertSame('Europe/Prague', $tz);
101
102 $tz = get_user_timezone('Europe/Berlin');
103 $this->assertSame('Europe/Berlin', $tz);
104
105 // Server and user timezone not set.
106
d6e7a63d 107 $this->setTimezone('99', 'Pacific/Auckland');
e19b3710
PS
108 $USER->timezone = '99';
109
110 $tz = get_user_timezone();
111 $this->assertSame(99.0, $tz);
112
113 $tz = get_user_timezone(99);
114 $this->assertSame(99.0, $tz);
115 $tz = get_user_timezone('99');
116 $this->assertSame(99.0, $tz);
117
118 $tz = get_user_timezone('Europe/Berlin');
119 $this->assertSame('Europe/Berlin', $tz);
120 }
121
e19b3710
PS
122 public function test_dst_offset_on() {
123 $time = gmmktime(1, 1, 1, 3, 1, 2015);
124 $this->assertSame(3600, dst_offset_on($time, 'Pacific/Auckland'));
125 $this->assertSame(0, dst_offset_on($time, 'Australia/Perth'));
126 $this->assertSame(1800, dst_offset_on($time, 'Australia/Lord_Howe'));
127 $this->assertSame(0, dst_offset_on($time, 'Europe/Prague'));
128 $this->assertSame(0, dst_offset_on($time, 'America/New_York'));
129
130 $time = gmmktime(1, 1, 1, 5, 1, 2015);
131 $this->assertSame(0, dst_offset_on($time, 'Pacific/Auckland'));
132 $this->assertSame(0, dst_offset_on($time, 'Australia/Perth'));
133 $this->assertSame(0, dst_offset_on($time, 'Australia/Lord_Howe'));
134 $this->assertSame(3600, dst_offset_on($time, 'Europe/Prague'));
135 $this->assertSame(3600, dst_offset_on($time, 'America/New_York'));
136 }
137
138 public function test_make_timestamp() {
139 global $CFG;
140
141 $this->resetAfterTest();
142
143 // There are quite a lot of problems, let's pick some less problematic zones for now.
e19b3710
PS
144 $timezones = array('Europe/Prague', 'Europe/London', 'Australia/Perth', 'Pacific/Auckland', 'America/New_York', '99');
145
146 $dates = array(
147 array(2, 1, 0, 40, 40),
148 array(4, 3, 0, 30, 22),
149 array(9, 5, 0, 20, 19),
150 array(11, 28, 0, 10, 45),
151 );
152 $years = array(1999, 2009, 2014, 2018);
153
d6e7a63d 154 $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
e19b3710
PS
155 foreach ($timezones as $tz) {
156 foreach ($years as $year) {
157 foreach ($dates as $date) {
158 $result = make_timestamp($year, $date[0], $date[1], $date[2], $date[3], $date[4], $tz, true);
159 $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
160 $expected->setDate($year, $date[0], $date[1]);
161 $expected->setTime($date[2], $date[3], $date[4]);
d6e7a63d
PS
162 $this->assertSame($expected->getTimestamp(), $result,
163 'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
e19b3710
PS
164 }
165 }
166 }
167
d6e7a63d 168 $this->setTimezone('99', 'Pacific/Auckland');
e19b3710
PS
169 foreach ($timezones as $tz) {
170 foreach ($years as $year) {
171 foreach ($dates as $date) {
172 $result = make_timestamp($year, $date[0], $date[1], $date[2], $date[3], $date[4], $tz, true);
173 $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
174 $expected->setDate($year, $date[0], $date[1]);
175 $expected->setTime($date[2], $date[3], $date[4]);
d6e7a63d
PS
176 $this->assertSame($expected->getTimestamp(), $result,
177 'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
e19b3710
PS
178 }
179 }
180 }
181 }
182
183 public function test_usergetdate() {
184 global $CFG;
185
186 $this->resetAfterTest();
187
188 // There are quite a lot of problems, let's pick some less problematic zones for now.
e19b3710
PS
189 $timezones = array('Europe/Prague', 'Europe/London', 'Australia/Perth', 'Pacific/Auckland', 'America/New_York', '99');
190
191 $dates = array(
192 array(2, 1, 0, 40, 40),
193 array(4, 3, 0, 30, 22),
194 array(9, 5, 0, 20, 19),
195 array(11, 28, 0, 10, 45),
196 );
197 $years = array(1999, 2009, 2014, 2018);
198
d6e7a63d 199 $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
e19b3710
PS
200 foreach ($timezones as $tz) {
201 foreach ($years as $year) {
202 foreach ($dates as $date) {
203 $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
204 $expected->setDate($year, $date[0], $date[1]);
205 $expected->setTime($date[2], $date[3], $date[4]);
206 $result = usergetdate($expected->getTimestamp(), $tz);
d6e7a63d 207 unset($result[0]); // Extra introduced by getdate().
e19b3710
PS
208 $ex = array(
209 'seconds' => $date[4],
210 'minutes' => $date[3],
211 'hours' => $date[2],
212 'mday' => $date[1],
213 'wday' => (int)$expected->format('w'),
214 'mon' => $date[0],
215 'year' => $year,
216 'yday' => (int)$expected->format('z'),
217 'weekday' => $expected->format('l'),
218 'month' => $expected->format('F'),
219 );
d6e7a63d
PS
220 $this->assertSame($ex, $result,
221 'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
e19b3710
PS
222 }
223 }
224 }
225
d6e7a63d 226 $this->setTimezone('99', 'Pacific/Auckland');
e19b3710
PS
227 foreach ($timezones as $tz) {
228 foreach ($years as $year) {
229 foreach ($dates as $date) {
230 $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
231 $expected->setDate($year, $date[0], $date[1]);
232 $expected->setTime($date[2], $date[3], $date[4]);
233 $result = usergetdate($expected->getTimestamp(), $tz);
d6e7a63d 234 unset($result[0]); // Extra introduced by getdate().
e19b3710
PS
235 $ex = array(
236 'seconds' => $date[4],
237 'minutes' => $date[3],
238 'hours' => $date[2],
239 'mday' => $date[1],
240 'wday' => (int)$expected->format('w'),
241 'mon' => $date[0],
242 'year' => $year,
243 'yday' => (int)$expected->format('z'),
244 'weekday' => $expected->format('l'),
245 'month' => $expected->format('F'),
246 );
d6e7a63d
PS
247 $this->assertSame($ex, $result,
248 'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
e19b3710
PS
249 }
250 }
251 }
252 }
253
254 public function test_userdate() {
255 global $CFG;
256
257 $this->resetAfterTest();
258
259 $dates = array(
260 array(2, 1, 0, 40, 40),
261 array(4, 3, 0, 30, 22),
262 array(9, 5, 0, 20, 19),
263 array(11, 28, 0, 10, 45),
264 );
265 $years = array(1999, 2009, 2014, 2018);
266
267 $users = array();
268 $users[] = $this->getDataGenerator()->create_user(array('timezone' => 99));
269 $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'Europe/Prague'));
270 $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'Pacific/Auckland'));
271 $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'Australia/Perth'));
272 $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'America/New_York'));
273
274 $format = get_string('strftimedaydatetime', 'langconfig');
275
d6e7a63d 276 $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
e19b3710
PS
277 foreach ($years as $year) {
278 foreach ($dates as $date) {
279 $expected = new DateTime('now', new DateTimeZone('UTC'));
280 $expected->setDate($year, $date[0], $date[1]);
281 $expected->setTime($date[2], $date[3], $date[4]);
282
283 foreach ($users as $user) {
284 $this->setUser($user);
285 $expected->setTimezone(new DateTimeZone(($user->timezone == 99 ? 'Pacific/Auckland' : $user->timezone)));
286 $result = userdate($expected->getTimestamp(), '', 99, false, false);
287 date_default_timezone_set($expected->getTimezone()->getName());
288 $ex = strftime($format, $expected->getTimestamp());
289 date_default_timezone_set($CFG->timezone);
290 $this->assertSame($ex, $result);
291 }
292 }
293 }
294 }
295
296 public function test_usertime() {
297 // This is a useless bad hack, it needs to be completely eliminated.
298
299 $time = gmmktime(1, 1, 1, 3, 1, 2015);
300 $this->assertSame($time - (60 * 60 * 1), usertime($time, '1'));
301 $this->assertSame($time - (60 * 60 * -1), usertime($time, '-1'));
302 $this->assertSame($time - (60 * 60 * 1), usertime($time, 'Europe/Prague'));
303 $this->assertSame($time - (60 * 60 * 8), usertime($time, 'Australia/Perth'));
304 $this->assertSame($time - (60 * 60 * 12), usertime($time, 'Pacific/Auckland'));
305 $this->assertSame($time - (60 * 60 * -5), usertime($time, 'America/New_York'));
306
307 $time = gmmktime(1, 1, 1, 5, 1, 2015);
308 $this->assertSame($time - (60 * 60 * 1), usertime($time, '1'));
309 $this->assertSame($time - (60 * 60 * -1), usertime($time, '-1'));
310 $this->assertSame($time - (60 * 60 * 1), usertime($time, 'Europe/Prague'));
311 $this->assertSame($time - (60 * 60 * 8), usertime($time, 'Australia/Perth'));
312 $this->assertSame($time - (60 * 60 * 12), usertime($time, 'Pacific/Auckland'));
313 $this->assertSame($time - (60 * 60 * -5), usertime($time, 'America/New_York'));
314 }
d6e7a63d
PS
315
316 public function test_usertimezone() {
317 global $USER;
318 $this->resetAfterTest();
319
320 $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
321
322 $USER->timezone = 'Europe/Prague';
323 $this->assertSame('Europe/Prague', usertimezone());
324
325 $USER->timezone = '1';
3fa072a1 326 $this->assertSame('UTC+1', usertimezone());
d6e7a63d
PS
327
328 $USER->timezone = '0';
3fa072a1 329 $this->assertSame('UTC', usertimezone());
d6e7a63d
PS
330
331 $USER->timezone = '99';
332 $this->assertSame('Pacific/Auckland', usertimezone());
333
334 $USER->timezone = '99';
335 $this->assertSame('Europe/Berlin', usertimezone('Europe/Berlin'));
336
337 $USER->timezone = '99';
338 $this->assertSame('Pacific/Auckland', usertimezone('99'));
339
340 $USER->timezone = 'Europe/Prague';
341 $this->assertSame('Europe/Prague', usertimezone('99'));
143f410a 342
ed3a47aa
DP
343 // When passed an unknown non-whole hour TZ, verify we round to closest
344 // hour. (Possible for legacy reasons when old timezones go away).
143f410a
DM
345 $USER->timezone = '-9.23';
346 $this->assertSame('UTC-9', usertimezone('99'));
d6e7a63d 347 }
e19b3710 348}