Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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 core_date class.
  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  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /**
  29   * Tests core_date class.
  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_testcase extends advanced_testcase {
  37      public function test_get_default_php_timezone() {
  38          $this->resetAfterTest();
  39  
  40          $origtz = core_date::get_default_php_timezone();
  41          $this->assertNotEmpty($origtz);
  42  
  43          $this->setTimezone('Pacific/Auckland', 'Europe/Prague');
  44          $this->assertSame('Europe/Prague', core_date::get_default_php_timezone());
  45  
  46          $this->setTimezone('Pacific/Auckland', 'UTC');
  47          $this->assertSame('UTC', core_date::get_default_php_timezone());
  48  
  49          $this->setTimezone('Pacific/Auckland', 'GMT');
  50          $this->assertSame('GMT', core_date::get_default_php_timezone());
  51      }
  52  
  53      public function test_normalise_timezone() {
  54          $this->resetAfterTest();
  55  
  56          $this->setTimezone('Pacific/Auckland');
  57          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone('Pacific/Auckland'));
  58          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone('99'));
  59          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone(99));
  60          $this->assertSame('GMT', core_date::normalise_timezone('GMT'));
  61          $this->assertSame('UTC', core_date::normalise_timezone('UTC'));
  62          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone('xxxxxxxx'));
  63          $this->assertSame('Europe/Berlin', core_date::normalise_timezone('Central European Time'));
  64          $this->assertSame('Etc/GMT', core_date::normalise_timezone('0'));
  65          $this->assertSame('Etc/GMT', core_date::normalise_timezone('0.0'));
  66          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone(2));
  67          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone('2.0'));
  68          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone(-2));
  69          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone('-2.0'));
  70          $this->assertSame('Etc/GMT+4', core_date::normalise_timezone(-4));
  71          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone('UTC+2'));
  72          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone('UTC-2'));
  73          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone('GMT+2'));
  74          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone('GMT-2'));
  75          $this->assertSame('Etc/GMT+12', core_date::normalise_timezone(-12));
  76          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone(-13));
  77          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone(-14));
  78          $this->assertSame('Etc/GMT-12', core_date::normalise_timezone(12));
  79          $this->assertSame('Etc/GMT-13', core_date::normalise_timezone(13));
  80          $this->assertSame('Etc/GMT-14', core_date::normalise_timezone(14));
  81  
  82          $this->assertSame('Asia/Kabul', core_date::normalise_timezone(4.5));
  83          $this->assertSame('Asia/Kolkata', core_date::normalise_timezone(5.5));
  84          $this->assertSame('Asia/Rangoon', core_date::normalise_timezone(6.5));
  85          $this->assertSame('Australia/Darwin', core_date::normalise_timezone('9.5'));
  86  
  87          $this->setTimezone('99', 'Pacific/Auckland');
  88          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone('Pacific/Auckland'));
  89          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone('99'));
  90          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone(99));
  91          $this->assertSame('GMT', core_date::normalise_timezone('GMT'));
  92          $this->assertSame('UTC', core_date::normalise_timezone('UTC'));
  93          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone('xxxxxxxx'));
  94          $this->assertSame('Europe/Berlin', core_date::normalise_timezone('Central European Time'));
  95          $this->assertSame('Etc/GMT', core_date::normalise_timezone('0'));
  96          $this->assertSame('Etc/GMT', core_date::normalise_timezone('0.0'));
  97          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone(2));
  98          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone('2.0'));
  99          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone(-2));
 100          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone('-2.0'));
 101          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone('UTC+2'));
 102          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone('UTC-2'));
 103          $this->assertSame('Etc/GMT-2', core_date::normalise_timezone('GMT+2'));
 104          $this->assertSame('Etc/GMT+2', core_date::normalise_timezone('GMT-2'));
 105          $this->assertSame('Etc/GMT+12', core_date::normalise_timezone(-12));
 106          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone(-13));
 107          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone(-14));
 108          $this->assertSame('Etc/GMT-12', core_date::normalise_timezone(12));
 109          $this->assertSame('Etc/GMT-13', core_date::normalise_timezone(13));
 110          $this->assertSame('Etc/GMT-14', core_date::normalise_timezone(14));
 111  
 112          $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
 113          $tz = new DateTimeZone('Pacific/Auckland');
 114          $this->assertSame('Pacific/Auckland', core_date::normalise_timezone($tz));
 115      }
 116  
 117      public function test_windows_conversion() {
 118          $file = __DIR__ . '/fixtures/timezonewindows.xml';
 119  
 120          $contents = file_get_contents($file);
 121          preg_match_all('/<mapZone other="([^"]+)" territory="001" type="([^"]+)"\/>/', $contents, $matches, PREG_SET_ORDER);
 122  
 123          $this->assertCount(104, $matches); // NOTE: If the file contents change edit the core_date class and update this.
 124  
 125          foreach ($matches as $match) {
 126              $result = core_date::normalise_timezone($match[1]);
 127              if ($result == $match[2]) {
 128                  $this->assertSame($match[2], $result);
 129              } else {
 130                  $data = new DateTime('now', new DateTimeZone($match[2]));
 131                  $expectedoffset = $data->getOffset();
 132                  $data = new DateTime('now', new DateTimeZone($result));
 133                  $resultoffset = $data->getOffset();
 134                  $this->assertSame($expectedoffset, $resultoffset, "$match[1] is expected to be converted to $match[2] not $result");
 135              }
 136          }
 137      }
 138  
 139      /**
 140       * Sanity test for PHP stuff.
 141       */
 142      public function test_php_gmt_offsets() {
 143          $this->resetAfterTest();
 144  
 145          $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
 146  
 147          for ($i = -12; $i < 0; $i++) {
 148              $date = new DateTime('now', new DateTimeZone("Etc/GMT{$i}"));
 149              $this->assertSame(- $i * 60 * 60, $date->getOffset());
 150              $date = new DateTime('now', new DateTimeZone(core_date::normalise_timezone("GMT{$i}")));
 151              $this->assertSame($i * 60 * 60, $date->getOffset());
 152              $date = new DateTime('now', new DateTimeZone(core_date::normalise_timezone("UTC{$i}")));
 153              $this->assertSame($i * 60 * 60, $date->getOffset());
 154          }
 155  
 156          $date = new DateTime('now', new DateTimeZone('Etc/GMT'));
 157          $this->assertSame(0, $date->getOffset());
 158  
 159          for ($i = 1; $i <= 12; $i++) {
 160              $date = new DateTime('now', new DateTimeZone("Etc/GMT+{$i}"));
 161              $this->assertSame(- $i * 60 * 60, $date->getOffset());
 162              $date = new DateTime('now', new DateTimeZone(core_date::normalise_timezone("GMT+{$i}")));
 163              $this->assertSame($i * 60 * 60, $date->getOffset());
 164              $date = new DateTime('now', new DateTimeZone(core_date::normalise_timezone("UTC+{$i}")));
 165              $this->assertSame($i * 60 * 60, $date->getOffset());
 166          }
 167      }
 168  
 169      public function test_timezone_lang_strings() {
 170          $phpzones = DateTimeZone::listIdentifiers();
 171          $manager = get_string_manager();
 172          foreach ($phpzones as $tz) {
 173              $this->assertTrue($manager->string_exists(strtolower($tz), 'core_timezones'),
 174                      'String for timezone ' . strtolower($tz) . ' not found.');
 175          }
 176      }
 177  
 178      public function test_get_localised_timezone() {
 179          $this->resetAfterTest();
 180  
 181          $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
 182  
 183          $result = core_date::get_localised_timezone('Pacific/Auckland');
 184          $this->assertSame('Pacific/Auckland', $result);
 185  
 186          $result = core_date::get_localised_timezone('99');
 187          $this->assertSame('Server timezone (Pacific/Auckland)', $result);
 188  
 189          $result = core_date::get_localised_timezone(99);
 190          $this->assertSame('Server timezone (Pacific/Auckland)', $result);
 191  
 192          $result = core_date::get_localised_timezone('Etc/GMT-1');
 193          $this->assertSame('UTC+1', $result);
 194  
 195          $result = core_date::get_localised_timezone('Etc/GMT+2');
 196          $this->assertSame('UTC-2', $result);
 197  
 198          $result = core_date::get_localised_timezone('GMT');
 199          $this->assertSame('UTC', $result);
 200  
 201          $result = core_date::get_localised_timezone('Etc/GMT');
 202          $this->assertSame('UTC', $result);
 203      }
 204  
 205      public function test_get_list_of_timezones() {
 206          $this->resetAfterTest();
 207  
 208          $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
 209  
 210          $phpzones = DateTimeZone::listIdentifiers();
 211  
 212          $zones = core_date::get_list_of_timezones();
 213          $this->assertSame(count($phpzones), count($zones));
 214          foreach ($zones as $zone => $zonename) {
 215              $this->assertSame($zone, $zonename); // The same in English!
 216              $this->assertContains($zone, $phpzones); // No extras expected.
 217          }
 218  
 219          $this->assertSame($zones, core_date::get_list_of_timezones(null, false));
 220  
 221          $nnzones = core_date::get_list_of_timezones(null, true);
 222          $last = $nnzones['99'];
 223          $this->assertSame('Server timezone (Pacific/Auckland)', $last);
 224          unset($nnzones['99']);
 225          $this->assertSame($zones, $nnzones);
 226  
 227          $nnzones = core_date::get_list_of_timezones('99', false);
 228          $last = $nnzones['99'];
 229          $this->assertSame('Server timezone (Pacific/Auckland)', $last);
 230          unset($nnzones['99']);
 231          $this->assertSame($zones, $nnzones);
 232  
 233          $xxzones = core_date::get_list_of_timezones('xx', false);
 234          $xx = $xxzones['xx'];
 235          $this->assertSame('Invalid timezone "xx"', $xx);
 236          unset($xxzones['xx']);
 237          $this->assertSame($zones, $xxzones);
 238  
 239          $xxzones = core_date::get_list_of_timezones('1', false);
 240          $xx = $xxzones['1'];
 241          $this->assertSame('Invalid timezone "UTC+1.0"', $xx);
 242          unset($xxzones['1']);
 243          $this->assertSame($zones, $xxzones);
 244  
 245          $xxzones = core_date::get_list_of_timezones('-1.5', false);
 246          $xx = $xxzones['-1.5'];
 247          $this->assertSame('Invalid timezone "UTC-1.5"', $xx);
 248          unset($xxzones['-1.5']);
 249          $this->assertSame($zones, $xxzones);
 250  
 251      }
 252  
 253      public function test_get_server_timezone() {
 254          global $CFG;
 255          $this->resetAfterTest();
 256  
 257          $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
 258          $this->assertSame('Pacific/Auckland', core_date::get_server_timezone());
 259  
 260          $this->setTimezone('Pacific/Auckland', 'Europe/Prague');
 261          $this->assertSame('Pacific/Auckland', core_date::get_server_timezone());
 262  
 263          $this->setTimezone('99', 'Pacific/Auckland');
 264          $this->assertSame('Pacific/Auckland', core_date::get_server_timezone());
 265  
 266          $this->setTimezone(99, 'Pacific/Auckland');
 267          $this->assertSame('Pacific/Auckland', core_date::get_server_timezone());
 268  
 269          $this->setTimezone('Pacific/Auckland', 'Pacific/Auckland');
 270          unset($CFG->timezone);
 271          $this->assertSame('Pacific/Auckland', core_date::get_server_timezone());
 272  
 273          // Admin should fix the settings.
 274          $this->setTimezone('xxx/zzzz', 'Europe/Prague');
 275          $this->assertSame('Europe/Prague', core_date::get_server_timezone());
 276      }
 277  
 278      public function test_get_server_timezone_object() {
 279          $this->resetAfterTest();
 280  
 281          $zones = core_date::get_list_of_timezones();
 282          foreach ($zones as $zone) {
 283              $this->setTimezone($zone, 'Pacific/Auckland');
 284              $tz = core_date::get_server_timezone_object();
 285              $this->assertInstanceOf('DateTimeZone', $tz);
 286              $this->assertSame($zone, $tz->getName());
 287          }
 288      }
 289  
 290      public function test_set_default_server_timezone() {
 291          global $CFG;
 292          $this->resetAfterTest();
 293  
 294          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 295          unset($CFG->timezone);
 296          date_default_timezone_set('UTC');
 297          core_date::set_default_server_timezone();
 298          $this->assertSame('Pacific/Auckland', date_default_timezone_get());
 299  
 300          $this->setTimezone('', 'Pacific/Auckland');
 301          date_default_timezone_set('UTC');
 302          core_date::set_default_server_timezone();
 303          $this->assertSame('Pacific/Auckland', date_default_timezone_get());
 304  
 305          $this->setTimezone('99', 'Pacific/Auckland');
 306          date_default_timezone_set('UTC');
 307          core_date::set_default_server_timezone();
 308          $this->assertSame('Pacific/Auckland', date_default_timezone_get());
 309  
 310          $this->setTimezone(99, 'Pacific/Auckland');
 311          date_default_timezone_set('UTC');
 312          core_date::set_default_server_timezone();
 313          $this->assertSame('Pacific/Auckland', date_default_timezone_get());
 314  
 315          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 316          $CFG->timezone = 'UTC';
 317          core_date::set_default_server_timezone();
 318          $this->assertSame('UTC', date_default_timezone_get());
 319  
 320          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 321          $CFG->timezone = 'Australia/Perth';
 322          core_date::set_default_server_timezone();
 323          $this->assertSame('Australia/Perth', date_default_timezone_get());
 324  
 325          $this->setTimezone('0', 'Pacific/Auckland');
 326          date_default_timezone_set('UTC');
 327          core_date::set_default_server_timezone();
 328          $this->assertSame('Etc/GMT', date_default_timezone_get());
 329  
 330          $this->setTimezone('1', 'Pacific/Auckland');
 331          date_default_timezone_set('UTC');
 332          core_date::set_default_server_timezone();
 333          $this->assertSame('Etc/GMT-1', date_default_timezone_get());
 334  
 335          $this->setTimezone(1, 'Pacific/Auckland');
 336          date_default_timezone_set('UTC');
 337          core_date::set_default_server_timezone();
 338          $this->assertSame('Etc/GMT-1', date_default_timezone_get());
 339  
 340          $this->setTimezone('1.0', 'Pacific/Auckland');
 341          date_default_timezone_set('UTC');
 342          core_date::set_default_server_timezone();
 343          $this->assertSame('Etc/GMT-1', date_default_timezone_get());
 344      }
 345  
 346      public function legacyUserTimezoneProvider() {
 347          return [
 348              ['', 'Australia/Perth'],            // Fallback on default timezone.
 349              ['-13.0', 'Australia/Perth'],       // Fallback on default timezone.
 350              ['-12.5', 'Etc/GMT+12'],
 351              ['-12.0', 'Etc/GMT+12'],
 352              ['-11.5', 'Etc/GMT+11'],
 353              ['-11.0', 'Etc/GMT+11'],
 354              ['-10.5', 'Etc/GMT+10'],
 355              ['-10.0', 'Etc/GMT+10'],
 356              ['-9.5', 'Etc/GMT+9'],
 357              ['-9.0', 'Etc/GMT+9'],
 358              ['-8.5', 'Etc/GMT+8'],
 359              ['-8.0', 'Etc/GMT+8'],
 360              ['-7.5', 'Etc/GMT+7'],
 361              ['-7.0', 'Etc/GMT+7'],
 362              ['-6.5', 'Etc/GMT+6'],
 363              ['-6.0', 'Etc/GMT+6'],
 364              ['-5.5', 'Etc/GMT+5'],
 365              ['-5.0', 'Etc/GMT+5'],
 366              ['-4.5', 'Etc/GMT+4'],
 367              ['-4.0', 'Etc/GMT+4'],
 368              ['-3.5', 'Etc/GMT+3'],
 369              ['-3.0', 'Etc/GMT+3'],
 370              ['-2.5', 'Etc/GMT+2'],
 371              ['-2.0', 'Etc/GMT+2'],
 372              ['-1.5', 'Etc/GMT+1'],
 373              ['-1.0', 'Etc/GMT+1'],
 374              ['-0.5', 'Etc/GMT'],
 375              ['0', 'Etc/GMT'],
 376              ['0.0', 'Etc/GMT'],
 377              ['0.5', 'Etc/GMT'],
 378              ['1.0', 'Etc/GMT-1'],
 379              ['1.5', 'Etc/GMT-1'],
 380              ['2.0', 'Etc/GMT-2'],
 381              ['2.5', 'Etc/GMT-2'],
 382              ['3.0', 'Etc/GMT-3'],
 383              ['3.5', 'Etc/GMT-3'],
 384              ['4.0', 'Etc/GMT-4'],
 385              ['4.5', 'Asia/Kabul'],
 386              ['5.0', 'Etc/GMT-5'],
 387              ['5.5', 'Asia/Kolkata'],
 388              ['6.0', 'Etc/GMT-6'],
 389              ['6.5', 'Asia/Rangoon'],
 390              ['7.0', 'Etc/GMT-7'],
 391              ['7.5', 'Etc/GMT-7'],
 392              ['8.0', 'Etc/GMT-8'],
 393              ['8.5', 'Etc/GMT-8'],
 394              ['9.0', 'Etc/GMT-9'],
 395              ['9.5', 'Australia/Darwin'],
 396              ['10.0', 'Etc/GMT-10'],
 397              ['10.5', 'Etc/GMT-10'],
 398              ['11.0', 'Etc/GMT-11'],
 399              ['11.5', 'Etc/GMT-11'],
 400              ['12.0', 'Etc/GMT-12'],
 401              ['12.5', 'Etc/GMT-12'],
 402              ['13.0', 'Etc/GMT-13'],
 403          ];
 404      }
 405  
 406      /**
 407       * @dataProvider legacyUserTimezoneProvider
 408       * @param string $tz The legacy timezone.
 409       * @param string $expected The expected converted timezone.
 410       */
 411      public function test_get_legacy_user_timezone($tz, $expected) {
 412          $this->setTimezone('Australia/Perth', 'Australia/Perth');
 413          $this->assertEquals($expected, core_date::get_user_timezone($tz));
 414      }
 415  
 416      public function test_get_user_timezone() {
 417          global $CFG, $USER;
 418          $this->resetAfterTest();
 419  
 420          // Null parameter.
 421  
 422          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 423          $USER->timezone = 'Pacific/Auckland';
 424          $CFG->forcetimezone = '99';
 425          $this->assertSame('Pacific/Auckland', core_date::get_user_timezone(null));
 426          $this->assertSame('Pacific/Auckland', core_date::get_user_timezone());
 427  
 428          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 429          $USER->timezone = 'Pacific/Auckland';
 430          $CFG->forcetimezone = 'Europe/Berlin';
 431          $this->assertSame('Europe/Berlin', core_date::get_user_timezone(null));
 432          $this->assertSame('Europe/Berlin', core_date::get_user_timezone());
 433  
 434          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 435          $USER->timezone = 'Pacific/Auckland';
 436          $CFG->forcetimezone = 'xxx/yyy';
 437          $this->assertSame('Europe/Prague', core_date::get_user_timezone(null));
 438          $this->assertSame('Europe/Prague', core_date::get_user_timezone());
 439  
 440          $this->setTimezone('Europe/Prague', 'Pacific/Auckland');
 441          $USER->timezone = 'abc/def';
 442          $CFG->forcetimezone = '99';
 443          $this->assertSame('Europe/Prague', core_date::get_user_timezone(null));
 444          $this->assertSame('Europe/Prague', core_date::get_user_timezone());
 445  
 446          $this->setTimezone('xxx/yyy', 'Europe/London');
 447          $USER->timezone = 'abc/def';
 448          $CFG->forcetimezone = 'Europe/Berlin';
 449          $this->assertSame('Europe/Berlin', core_date::get_user_timezone(null));
 450          $this->assertSame('Europe/Berlin', core_date::get_user_timezone());
 451  
 452          $this->setTimezone('xxx/yyy', 'Europe/London');
 453          $USER->timezone = 'abc/def';
 454          $CFG->forcetimezone = 99;
 455          $this->assertSame('Europe/London', core_date::get_user_timezone(null));
 456          $this->assertSame('Europe/London', core_date::get_user_timezone());
 457  
 458          // User object parameter.
 459          $admin = get_admin();
 460  
 461          $this->setTimezone('Europe/London');
 462          $USER->timezone = 'Pacific/Auckland';
 463          $CFG->forcetimezone = '99';
 464          $admin->timezone = 'Australia/Perth';
 465          $this->assertSame('Australia/Perth', core_date::get_user_timezone($admin));
 466  
 467          $this->setTimezone('Europe/Prague');
 468          $USER->timezone = 'Pacific/Auckland';
 469          $CFG->forcetimezone = '99';
 470          $admin->timezone = '99';
 471          $this->assertSame('Europe/Prague', core_date::get_user_timezone($admin));
 472  
 473          $this->setTimezone('99', 'Europe/London');
 474          $USER->timezone = 'Pacific/Auckland';
 475          $CFG->forcetimezone = '99';
 476          $admin->timezone = '99';
 477          $this->assertSame('Europe/London', core_date::get_user_timezone($admin));
 478  
 479          $this->setTimezone('Europe/Prague');
 480          $USER->timezone = 'Pacific/Auckland';
 481          $CFG->forcetimezone = '99';
 482          $admin->timezone = 'xx/zz';
 483          $this->assertSame('Europe/Prague', core_date::get_user_timezone($admin));
 484  
 485          $this->setTimezone('Europe/Prague');
 486          $USER->timezone = 'Pacific/Auckland';
 487          $CFG->forcetimezone = '99';
 488          unset($admin->timezone);
 489          $this->assertSame('Europe/Prague', core_date::get_user_timezone($admin));
 490  
 491          $this->setTimezone('Europe/Prague');
 492          $USER->timezone = 'Pacific/Auckland';
 493          $CFG->forcetimezone = 'Europe/Berlin';
 494          $admin->timezone = 'Australia/Perth';
 495          $this->assertSame('Europe/Berlin', core_date::get_user_timezone($admin));
 496  
 497          // Other scalar parameter.
 498  
 499          $this->setTimezone('Europe/Prague');
 500          $CFG->forcetimezone = '99';
 501  
 502          $USER->timezone = 'Pacific/Auckland';
 503          $this->assertSame('Pacific/Auckland', core_date::get_user_timezone('99'));
 504          $this->assertSame('Etc/GMT-1', core_date::get_user_timezone('1'));
 505          $this->assertSame('Etc/GMT+1', core_date::get_user_timezone(-1));
 506          $this->assertSame('Europe/London', core_date::get_user_timezone('Europe/London'));
 507          $USER->timezone = '99';
 508          $this->assertSame('Europe/Prague', core_date::get_user_timezone('99'));
 509          $this->assertSame('Europe/London', core_date::get_user_timezone('Europe/London'));
 510          $this->assertSame('Europe/Prague', core_date::get_user_timezone('xxx/zzz'));
 511          $USER->timezone = 'xxz/zzz';
 512          $this->assertSame('Europe/Prague', core_date::get_user_timezone('99'));
 513  
 514          $this->setTimezone('99', 'Europe/Prague');
 515          $CFG->forcetimezone = '99';
 516  
 517          $USER->timezone = 'Pacific/Auckland';
 518          $this->assertSame('Pacific/Auckland', core_date::get_user_timezone('99'));
 519          $this->assertSame('Europe/London', core_date::get_user_timezone('Europe/London'));
 520          $USER->timezone = '99';
 521          $this->assertSame('Europe/Prague', core_date::get_user_timezone('99'));
 522          $this->assertSame('Europe/London', core_date::get_user_timezone('Europe/London'));
 523          $this->assertSame('Europe/Prague', core_date::get_user_timezone('xxx/zzz'));
 524          $USER->timezone = 99;
 525          $this->assertSame('Europe/London', core_date::get_user_timezone('Europe/London'));
 526          $this->assertSame('Europe/Prague', core_date::get_user_timezone('xxx/zzz'));
 527          $USER->timezone = 'xxz/zzz';
 528          $this->assertSame('Europe/Prague', core_date::get_user_timezone('99'));
 529  
 530          $this->setTimezone('xxx', 'Europe/Prague');
 531          $CFG->forcetimezone = '99';
 532          $USER->timezone = 'xxx';
 533          $this->assertSame('Europe/Prague', core_date::get_user_timezone('99'));
 534          $this->assertSame('Europe/Prague', core_date::get_user_timezone(99));
 535          $this->assertSame('Etc/GMT-1', core_date::get_user_timezone(1));
 536  
 537          $this->setTimezone('Europe/Prague');
 538          $CFG->forcetimezone = 'Pacific/Auckland';
 539          $USER->timezone = 'Europe/London';
 540          $this->assertSame('Pacific/Auckland', core_date::get_user_timezone(99));
 541          $this->assertSame('Europe/Berlin', core_date::get_user_timezone('Europe/Berlin'));
 542  
 543          // TZ object param.
 544  
 545          $this->setTimezone('UTC');
 546          $USER->timezone = 'Europe/London';
 547          $CFG->forcetimezone = 99;
 548          $tz = new DateTimeZone('Pacific/Auckland');
 549          $this->assertSame('Pacific/Auckland', core_date::get_user_timezone($tz));
 550      }
 551  
 552      public function test_get_user_timezone_object() {
 553          global $CFG, $USER;
 554          $this->resetAfterTest();
 555  
 556          $this->setTimezone('Pacific/Auckland');
 557          $CFG->forcetimezone = '99';
 558  
 559          $zones = core_date::get_list_of_timezones();
 560          foreach ($zones as $zone) {
 561              $USER->timezone = $zone;
 562              $tz = core_date::get_user_timezone_object();
 563              $this->assertInstanceOf('DateTimeZone', $tz);
 564              $this->assertSame($zone, $tz->getName());
 565          }
 566      }
 567  }