MDL-51893 core_date: Stop using Pacific/Norfolk as 11.5 replacement
[moodle.git] / lib / tests / date_legacy_test.php
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/>.
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  */
26 defined('MOODLE_INTERNAL') || die();
28 /**
29  * Tests legacy Moodle date/time functions.
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>
35  */
36 class core_date_legacy_testcase extends advanced_testcase {
37     public function test_settings() {
38         global $CFG;
39         $this->resetAfterTest();
41         $this->assertNotEmpty($CFG->timezone);
43         $this->assertSame('99', $CFG->forcetimezone);
45         $user = $this->getDataGenerator()->create_user();
46         $this->assertSame('99', $user->timezone);
47     }
49     public function test_get_list_of_timezones() {
50         // Use timezones that are not problematic, this way we may test before
51         // and after the big tz rewrite.
52         $list = get_list_of_timezones();
53         $this->assertDebuggingCalled();
54         $this->assertArrayHasKey('Europe/London', $list);
55         $this->assertArrayHasKey('Pacific/Auckland', $list);
56         $this->assertArrayHasKey('America/New_York', $list);
57         $this->assertArrayHasKey('Europe/Berlin', $list);
58         $this->assertArrayHasKey('Europe/Prague', $list);
59         $this->assertArrayHasKey('Australia/Perth', $list);
60         $this->assertArrayHasKey('Australia/Lord_Howe', $list);
61     }
63     public function test_get_user_timezone() {
64         global $CFG, $USER;
66         $this->resetAfterTest();
68         $user = $this->getDataGenerator()->create_user();
69         $this->setUser($user);
71         // All set to something.
73         $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
74         $USER->timezone = 'Europe/Prague';
76         $tz = get_user_timezone();
77         $this->assertSame('Europe/Prague', $tz);
79         $tz = get_user_timezone(99);
80         $this->assertSame('Europe/Prague', $tz);
81         $tz = get_user_timezone('99');
82         $this->assertSame('Europe/Prague', $tz);
84         $tz = get_user_timezone('Europe/Berlin');
85         $this->assertSame('Europe/Berlin', $tz);
87         // User timezone not set.
89         $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
90         $USER->timezone = '99';
92         $tz = get_user_timezone();
93         $this->assertSame('Pacific/Auckland', $tz);
95         $tz = get_user_timezone(99);
96         $this->assertSame('Pacific/Auckland', $tz);
97         $tz = get_user_timezone('99');
98         $this->assertSame('Pacific/Auckland', $tz);
100         $tz = get_user_timezone('Europe/Berlin');
101         $this->assertSame('Europe/Berlin', $tz);
103         // Server timezone not set.
105         $this->setTimezone('99', 'Pacific/Auckland');
106         $USER->timezone = 'Europe/Prague';
108         $tz = get_user_timezone();
109         $this->assertSame('Europe/Prague', $tz);
111         $tz = get_user_timezone(99);
112         $this->assertSame('Europe/Prague', $tz);
113         $tz = get_user_timezone('99');
114         $this->assertSame('Europe/Prague', $tz);
116         $tz = get_user_timezone('Europe/Berlin');
117         $this->assertSame('Europe/Berlin', $tz);
119         // Server and user timezone not set.
121         $this->setTimezone('99', 'Pacific/Auckland');
122         $USER->timezone = '99';
124         $tz = get_user_timezone();
125         $this->assertSame(99.0, $tz);
127         $tz = get_user_timezone(99);
128         $this->assertSame(99.0, $tz);
129         $tz = get_user_timezone('99');
130         $this->assertSame(99.0, $tz);
132         $tz = get_user_timezone('Europe/Berlin');
133         $this->assertSame('Europe/Berlin', $tz);
134     }
136     public function test_get_timezone_offset() {
137         // This is a useless function, the timezone offset may be changing!
138         $this->assertSame(60 * 60 * -5, get_timezone_offset('America/New_York'));
139         $this->assertDebuggingCalled();
140         $this->assertSame(60 * 60 * -1, get_timezone_offset(-1));
141         $this->assertSame(60 * 60 * 1, get_timezone_offset(1));
142         $this->assertSame(60 * 60 * 1, get_timezone_offset('Europe/Prague'));
143         $this->assertSame(60 * 60 * 8, get_timezone_offset('Australia/Perth'));
144         $this->assertSame(60 * 60 * 12, get_timezone_offset('Pacific/Auckland'));
146         // Known half an hour offsets.
147         $this->assertEquals(60 * 60 * -4.5, get_timezone_offset('-4.5'));
148         $this->assertEquals(60 * 60 * -4.5, get_timezone_offset('America/Caracas'));
149         $this->assertEquals(60 * 60 * 4.5, get_timezone_offset('4.5'));
150         $this->assertEquals(60 * 60 * 4.5, get_timezone_offset('Asia/Kabul'));
151         $this->assertEquals(60 * 60 * 5.5, get_timezone_offset('5.5'));
152         $this->assertEquals(60 * 60 * 5.5, get_timezone_offset('Asia/Kolkata'));
153         $this->assertEquals(60 * 60 * 6.5, get_timezone_offset('6.5'));
154         $this->assertEquals(60 * 60 * 6.5, get_timezone_offset('Asia/Rangoon'));
155         $this->assertEquals(60 * 60 * 9.5, get_timezone_offset('9.5'));
156         $this->assertEquals(60 * 60 * 9.5, get_timezone_offset('Australia/Darwin'));
158         $this->resetDebugging();
159     }
161     public function test_get_user_timezone_offset() {
162         // This is a useless function, the timezone offset may be changing!
163         $this->assertSame(-5.0, get_user_timezone_offset('America/New_York'));
164         $this->assertDebuggingCalled();
165         $this->assertSame(-1.0, get_user_timezone_offset(-1));
166         $this->assertSame(1.0, get_user_timezone_offset(1));
167         $this->assertSame(1.0, get_user_timezone_offset('Europe/Prague'));
168         $this->assertSame(8.0, get_user_timezone_offset('Australia/Perth'));
169         $this->assertSame(12.0, get_user_timezone_offset('Pacific/Auckland'));
171         $this->resetDebugging();
172     }
174     public function test_dst_offset_on() {
175         $time = gmmktime(1, 1, 1, 3, 1, 2015);
176         $this->assertSame(3600, dst_offset_on($time, 'Pacific/Auckland'));
177         $this->assertSame(0, dst_offset_on($time, 'Australia/Perth'));
178         $this->assertSame(1800, dst_offset_on($time, 'Australia/Lord_Howe'));
179         $this->assertSame(0, dst_offset_on($time, 'Europe/Prague'));
180         $this->assertSame(0, dst_offset_on($time, 'America/New_York'));
182         $time = gmmktime(1, 1, 1, 5, 1, 2015);
183         $this->assertSame(0, dst_offset_on($time, 'Pacific/Auckland'));
184         $this->assertSame(0, dst_offset_on($time, 'Australia/Perth'));
185         $this->assertSame(0, dst_offset_on($time, 'Australia/Lord_Howe'));
186         $this->assertSame(3600, dst_offset_on($time, 'Europe/Prague'));
187         $this->assertSame(3600, dst_offset_on($time, 'America/New_York'));
188     }
190     public function test_make_timestamp() {
191         global $CFG;
193         $this->resetAfterTest();
195         // There are quite a lot of problems, let's pick some less problematic zones for now.
196         $timezones = array('Europe/Prague', 'Europe/London', 'Australia/Perth', 'Pacific/Auckland', 'America/New_York', '99');
198         $dates = array(
199             array(2, 1, 0, 40, 40),
200             array(4, 3, 0, 30, 22),
201             array(9, 5, 0, 20, 19),
202             array(11, 28, 0, 10, 45),
203         );
204         $years = array(1999, 2009, 2014, 2018);
206         $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
207         foreach ($timezones as $tz) {
208             foreach ($years as $year) {
209                 foreach ($dates as $date) {
210                     $result = make_timestamp($year, $date[0], $date[1], $date[2], $date[3], $date[4], $tz, true);
211                     $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
212                     $expected->setDate($year, $date[0], $date[1]);
213                     $expected->setTime($date[2], $date[3], $date[4]);
214                     $this->assertSame($expected->getTimestamp(), $result,
215                         'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
216                 }
217             }
218         }
220         $this->setTimezone('99', 'Pacific/Auckland');
221         foreach ($timezones as $tz) {
222             foreach ($years as $year) {
223                 foreach ($dates as $date) {
224                     $result = make_timestamp($year, $date[0], $date[1], $date[2], $date[3], $date[4], $tz, true);
225                     $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
226                     $expected->setDate($year, $date[0], $date[1]);
227                     $expected->setTime($date[2], $date[3], $date[4]);
228                     $this->assertSame($expected->getTimestamp(), $result,
229                         'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
230                 }
231             }
232         }
233     }
235     public function test_usergetdate() {
236         global $CFG;
238         $this->resetAfterTest();
240         // There are quite a lot of problems, let's pick some less problematic zones for now.
241         $timezones = array('Europe/Prague', 'Europe/London', 'Australia/Perth', 'Pacific/Auckland', 'America/New_York', '99');
243         $dates = array(
244             array(2, 1, 0, 40, 40),
245             array(4, 3, 0, 30, 22),
246             array(9, 5, 0, 20, 19),
247             array(11, 28, 0, 10, 45),
248         );
249         $years = array(1999, 2009, 2014, 2018);
251         $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
252         foreach ($timezones as $tz) {
253             foreach ($years as $year) {
254                 foreach ($dates as $date) {
255                     $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
256                     $expected->setDate($year, $date[0], $date[1]);
257                     $expected->setTime($date[2], $date[3], $date[4]);
258                     $result = usergetdate($expected->getTimestamp(), $tz);
259                     unset($result[0]); // Extra introduced by getdate().
260                     $ex = array(
261                         'seconds' => $date[4],
262                         'minutes' => $date[3],
263                         'hours' => $date[2],
264                         'mday' => $date[1],
265                         'wday' => (int)$expected->format('w'),
266                         'mon' => $date[0],
267                         'year' => $year,
268                         'yday' => (int)$expected->format('z'),
269                         'weekday' => $expected->format('l'),
270                         'month' => $expected->format('F'),
271                     );
272                     $this->assertSame($ex, $result,
273                         'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
274                 }
275             }
276         }
278         $this->setTimezone('99', 'Pacific/Auckland');
279         foreach ($timezones as $tz) {
280             foreach ($years as $year) {
281                 foreach ($dates as $date) {
282                     $expected = new DateTime('now', new DateTimeZone(($tz == 99 ? 'Pacific/Auckland' : $tz)));
283                     $expected->setDate($year, $date[0], $date[1]);
284                     $expected->setTime($date[2], $date[3], $date[4]);
285                     $result = usergetdate($expected->getTimestamp(), $tz);
286                     unset($result[0]); // Extra introduced by getdate().
287                     $ex = array(
288                         'seconds' => $date[4],
289                         'minutes' => $date[3],
290                         'hours' => $date[2],
291                         'mday' => $date[1],
292                         'wday' => (int)$expected->format('w'),
293                         'mon' => $date[0],
294                         'year' => $year,
295                         'yday' => (int)$expected->format('z'),
296                         'weekday' => $expected->format('l'),
297                         'month' => $expected->format('F'),
298                     );
299                     $this->assertSame($ex, $result,
300                         'Incorrect result for data ' . $expected->format("D, d M Y H:i:s O") . ' ' . $tz);
301                 }
302             }
303         }
304     }
306     public function test_userdate() {
307         global $CFG;
309         $this->resetAfterTest();
311         $dates = array(
312             array(2, 1, 0, 40, 40),
313             array(4, 3, 0, 30, 22),
314             array(9, 5, 0, 20, 19),
315             array(11, 28, 0, 10, 45),
316         );
317         $years = array(1999, 2009, 2014, 2018);
319         $users = array();
320         $users[] = $this->getDataGenerator()->create_user(array('timezone' => 99));
321         $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'Europe/Prague'));
322         $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'Pacific/Auckland'));
323         $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'Australia/Perth'));
324         $users[] = $this->getDataGenerator()->create_user(array('timezone' => 'America/New_York'));
326         $format = get_string('strftimedaydatetime', 'langconfig');
328         $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
329         foreach ($years as $year) {
330             foreach ($dates as $date) {
331                 $expected = new DateTime('now', new DateTimeZone('UTC'));
332                 $expected->setDate($year, $date[0], $date[1]);
333                 $expected->setTime($date[2], $date[3], $date[4]);
335                 foreach ($users as $user) {
336                     $this->setUser($user);
337                     $expected->setTimezone(new DateTimeZone(($user->timezone == 99 ? 'Pacific/Auckland' : $user->timezone)));
338                     $result = userdate($expected->getTimestamp(), '', 99, false, false);
339                     date_default_timezone_set($expected->getTimezone()->getName());
340                     $ex = strftime($format, $expected->getTimestamp());
341                     date_default_timezone_set($CFG->timezone);
342                     $this->assertSame($ex, $result);
343                 }
344             }
345         }
346     }
348     public function test_usertime() {
349         // This is a useless bad hack, it needs to be completely eliminated.
351         $time = gmmktime(1, 1, 1, 3, 1, 2015);
352         $this->assertSame($time - (60 * 60 * 1), usertime($time, '1'));
353         $this->assertSame($time - (60 * 60 * -1), usertime($time, '-1'));
354         $this->assertSame($time - (60 * 60 * 1), usertime($time, 'Europe/Prague'));
355         $this->assertSame($time - (60 * 60 * 8), usertime($time, 'Australia/Perth'));
356         $this->assertSame($time - (60 * 60 * 12), usertime($time, 'Pacific/Auckland'));
357         $this->assertSame($time - (60 * 60 * -5), usertime($time, 'America/New_York'));
359         $time = gmmktime(1, 1, 1, 5, 1, 2015);
360         $this->assertSame($time - (60 * 60 * 1), usertime($time, '1'));
361         $this->assertSame($time - (60 * 60 * -1), usertime($time, '-1'));
362         $this->assertSame($time - (60 * 60 * 1), usertime($time, 'Europe/Prague'));
363         $this->assertSame($time - (60 * 60 * 8), usertime($time, 'Australia/Perth'));
364         $this->assertSame($time - (60 * 60 * 12), usertime($time, 'Pacific/Auckland'));
365         $this->assertSame($time - (60 * 60 * -5), usertime($time, 'America/New_York'));
366     }
368     public function test_usertimezone() {
369         global $USER;
370         $this->resetAfterTest();
372         $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
374         $USER->timezone = 'Europe/Prague';
375         $this->assertSame('Europe/Prague', usertimezone());
377         $USER->timezone = '1';
378         $this->assertSame('UTC+1', usertimezone());
380         $USER->timezone = '0';
381         $this->assertSame('UTC', usertimezone());
383         $USER->timezone = '99';
384         $this->assertSame('Pacific/Auckland', usertimezone());
386         $USER->timezone = '99';
387         $this->assertSame('Europe/Berlin', usertimezone('Europe/Berlin'));
389         $USER->timezone = '99';
390         $this->assertSame('Pacific/Auckland', usertimezone('99'));
392         $USER->timezone = 'Europe/Prague';
393         $this->assertSame('Europe/Prague', usertimezone('99'));
394     }