From e0b2aae64cd63e692fc0a3c564c58bda69e0e3e4 Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Tue, 24 Feb 2015 14:55:53 +1300 Subject: [PATCH] MDL-49273 improve timezone creation process --- admin/tool/timezoneimport/cli/build_timezone.php | 134 +++++++++++++++++++++++ lib/olson.php | 17 ++- 2 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 admin/tool/timezoneimport/cli/build_timezone.php diff --git a/admin/tool/timezoneimport/cli/build_timezone.php b/admin/tool/timezoneimport/cli/build_timezone.php new file mode 100644 index 0000000..46a8ff5 --- /dev/null +++ b/admin/tool/timezoneimport/cli/build_timezone.php @@ -0,0 +1,134 @@ +. + +/** + * This script builds lib/timezone.txt, it is not intended for admins. + * + * @package tool_timezoneimport + * @copyright 2015 Totara Learning Solutions Ltd {@link http://www.totaralms.com/} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Petr Skoda + */ + +define('CLI_SCRIPT', true); + +require(__DIR__.'/../../../../config.php'); +require_once($CFG->libdir.'/clilib.php'); +require_once($CFG->libdir.'/olson.php'); + +$help = + "This script builds lib/timezone.txt + +Steps: + 1/ download tzdata file form http://www.iana.org/time-zones + 2/ extract the archive contents into $CFG->tempdir/tzdata/ + 3/ run this tool + 4/ create pull requests and update timezone file at download.moodle.org + +NOTE: This tool is intended for Moodle developers only + because lib/timezone.txt file is overridden by web updates. + +Options: +-h, --help Print out this help. + +Example: +\$ sudo -u www-data /usr/bin/php admin/tool/timezoneimport/cli/build_timezone.php +"; + +list($options, $unrecognized) = cli_get_params( + array('help' => false), array('h' => 'help')); + +if ($options['help']) { + echo $help; + exit(0); +} + +// Force debugging. +$CFG->debug = (E_ALL | E_STRICT); +$CFG->debugdisplay = true; + +$datadir = "$CFG->tempdir/tzdata/"; + +if (!file_exists($datadir)) { + cli_error("$datadir is not present - this tool is not intended for admins"); +} + +$makefile = $datadir . 'Makefile'; +if (!file_exists($makefile)) { + cli_error("$datadir does not contain timezone data files, cannot continue"); +} +preg_match('/^VERSION\s*=\s*([0-9a-zA-Z]+)\s*$/m', file_get_contents($makefile), $matches); +if (isset($matches[1])) { + echo "Processing timezone data version: {$matches[1]}\n"; +} else { + echo "Unknown timezone data version\n"; +} + +$files = array('africa', 'antarctica', 'asia', 'australasia', 'europe', 'northamerica', 'southamerica', 'etcetera'); +$concat = ''; +foreach ($files as $file) { + $path = $datadir . $file; + if (!file_exists($path)) { + cli_error("$path is not present, cannot continue"); + } + $concat .= file_get_contents($path); +} + +$olsonfile = $datadir . 'olson.txt'; +@unlink($olsonfile); +file_put_contents($olsonfile, $concat); +unset($concat); + +$timezones = olson_to_timezones($olsonfile); +unlink($olsonfile); + +if (!$timezones) { + cli_error('Error parsing olson file'); +} + +update_timezone_records($timezones); + +$fields = array( + 'name', + 'year', + 'tzrule', + 'gmtoff', + 'dstoff', + 'dst_month', + 'dst_startday', + 'dst_weekday', + 'dst_skipweeks', + 'dst_time', + 'std_month', + 'std_startday', + 'std_weekday', + 'std_skipweeks', + 'std_time', +); + +$records = $DB->get_records('timezone', null, 'id ASC'); + +$content = implode(',', $fields) . "\n"; +foreach ($records as $record) { + $line = array(); + foreach ($fields as $field) { + $line[] = $record->$field; + } + $content .= implode(',', $line) . "\n"; +} + +file_put_contents($CFG->libdir . '/timezone.txt', $content); +echo "File updated: {$CFG->libdir}/timezone.txt\n"; diff --git a/lib/olson.php b/lib/olson.php index 2150f86..859a4bc 100644 --- a/lib/olson.php +++ b/lib/olson.php @@ -440,7 +440,7 @@ function olson_simple_zone_parser($filename, $maxyear) { if (preg_match('/^#/', $line)) { continue; } - if (preg_match('/^(?:Rule|Link|Leap)/',$line)) { + if (preg_match('/^(?:Rule|Leap)/',$line)) { $lastzone = NULL; // reset lastzone continue; } @@ -473,7 +473,20 @@ function olson_simple_zone_parser($filename, $maxyear) { *** We remove "until" from the data we keep, but preserve *** it in $lastzone. */ - if (preg_match('/^Zone/', $line)) { // a new zone + if (preg_match('/^Link/', $line)) { + $lastzone = null; + $line = trim($line); + $line = preg_split('/\s+/', $line); + if (count($line) >= 3) { + if (isset($zones[$line[1]])) { + foreach ($zones[$line[1]] as $k => $v) { + $v['name'] = $line[2]; + $zones[$line[2]][$k] = $v; + } + } + } + continue; + } else if (preg_match('/^Zone/', $line)) { // a new zone $line = trim($line); $line = preg_split('/\s+/', $line); $zone = array(); -- 2.3.5