summaryrefslogtreecommitdiff
path: root/src/third_party/timelib/zones/create-timezonedb.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/timelib/zones/create-timezonedb.php')
-rw-r--r--src/third_party/timelib/zones/create-timezonedb.php171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/third_party/timelib/zones/create-timezonedb.php b/src/third_party/timelib/zones/create-timezonedb.php
new file mode 100644
index 00000000000..679a7c047d7
--- /dev/null
+++ b/src/third_party/timelib/zones/create-timezonedb.php
@@ -0,0 +1,171 @@
+<?php
+function readZoneTab( string $tabFile ) : array
+{
+ $tab = [];
+
+ // process extra info
+ $f = file( 'code/zone.tab' );
+
+ foreach ( $f as $line )
+ {
+ $line = trim( $line );
+ $comments = '';
+
+ if ( strlen( $line ) < 5 || $line[0] == '#' )
+ {
+ continue;
+ }
+ $fields = explode( "\t", $line );
+ list( $countryCode, $coordinates, $tzid ) = $fields;
+ if ( sizeof( $fields ) > 3 ) {
+ $comments = $fields[3];
+ }
+
+ // format lang/lat
+ if ( strlen( $coordinates ) == 11 )
+ {
+ sscanf( $coordinates, '%c%2d%2d%c%3d%2d', $xSign, $xH, $xM, $ySign, $yH, $yM );
+ $xS = $yS = 0;
+ }
+ else
+ {
+ sscanf( $coordinates, '%c%2d%2d%2d%c%3d%2d%2d', $xSign, $xH, $xM, $xS, $ySign, $yH, $yM, $yS );
+ }
+ $lat = $xH + ( $xM / 60 ) + ( $xS / 3600 );
+ $long = $yH + ( $yM / 60 ) + ( $yS / 3600 );
+ $lat = $xSign == '+' ? $lat : -$lat;
+ $long = $ySign == '+' ? $long : -$long;
+
+ $tab[$tzid] = [
+ 'cc' => $countryCode,
+ 'lat' => ($lat + 90) * 100000,
+ 'lng' => ($long + 180) * 100000,
+ 'desc' => $comments ?: '',
+ ];
+ }
+
+ return $tab;
+}
+
+function readDataFile( string $tzid, array $tab ) : array
+{
+ $originalHeaderSize = 20;
+
+ // obtain data from tz files
+ $fatData = file_get_contents( "code/data/{$tzid}", false, NULL, $originalHeaderSize );
+ $slimData = file_get_contents( "code/data-slim/{$tzid}", false, NULL, $originalHeaderSize );
+
+ $tabData = array_key_exists( $tzid, $tab ) ? $tab[$tzid] : null;
+
+ if ( $tabData ) {
+ $header = pack( 'a4ca2a13', 'PHP2', true, $tabData['cc'], '' );
+ $footer = pack( 'NNNa*', $tabData['lat'], $tabData['lng'], strlen( $tabData['desc'] ), $tabData['desc'] );
+ } else {
+ $header = pack( 'a4ca2a13', 'PHP2', $tzid == 'UTC', '??', '' );
+ $footer = pack( 'NNNa*', 0, 0, 0, '' );
+ }
+
+ $fatData = $header . $fatData . $footer;
+ $slimData = $header . $slimData . $footer;
+
+ return [ $fatData, $slimData ];
+}
+
+function createDataAndIndex(array $tab)
+{
+ $files = array_merge(glob("code/data/*"), glob("code/data/*/*"), glob("code/data/*/*/*"));
+ usort($files, 'strcasecmp');
+
+ $fatIndex = [];
+ $slimIndex = [];
+ $fatData = $slimData = '';
+
+ foreach ($files as $fileName) {
+ if (is_dir($fileName)) {
+ continue;
+ }
+
+ $tzid = preg_replace('@code/data/@', '', $fileName);
+ list($tzFatData, $tzSlimData) = readDataFile($tzid, $tab);
+
+ $fatIndex[$tzid] = strlen($fatData);
+ $slimIndex[$tzid] = strlen($slimData);
+
+ $fatData .= $tzFatData;
+ $slimData .= $tzSlimData;
+ }
+
+ return [$fatIndex, $fatData, $slimIndex, $slimData];
+}
+
+function getVersion() : string
+{
+ $version_info = file( 'version-info.txt' );
+ $version = trim( $version_info[1] );
+
+ return $version;
+}
+
+function addData(array $index, string $data)
+{
+ $elements = count( $index );
+ $flipIndex = array_flip( $index );
+ $dataSize = strlen( $data );
+
+ $str = "const timelib_tzdb_index_entry timezonedb_idx_builtin[$elements] = {\n";
+ foreach ( $index as $tzid => $start )
+ {
+ $str .= sprintf( "\t{ (char*) %-36s, 0x%06X },\n", "\"{$tzid}\"", $start );
+ }
+ $str .= "};\n";
+
+ $pos = 0;
+
+ $str .= "\n\nconst unsigned char timelib_timezone_db_data_builtin[{$dataSize}] = {";
+ for ( $i = 0; $i < $dataSize; $i++ )
+ {
+ if ( isset( $flipIndex[$i] ) )
+ {
+ $str .= "\n\n/* {$flipIndex[$i] } */\n";
+ $pos = 0;
+ }
+ $str .= sprintf( "0x%02X,", ord( $data[$i] ) );
+ if ( $pos % 16 == 15) {
+ $str .= "\n";
+ } else {
+ $str .= " ";
+ }
+ $pos++;
+ }
+ $str .= "\n};\n";
+
+ return $str;
+}
+
+function writeTimelibH(array $fatIndex, string $fatData, array $slimIndex, string $slimData )
+{
+ $elements = count( $fatIndex );
+
+ $data = "/* This is a generated file, do not modify */\n";
+
+ /* Error out if TIMELIB_SUPPORTS_V2DATA isn't set */
+ $data .= "#ifndef TIMELIB_SUPPORTS_V2DATA\n";
+ $data .= "#error Your version of timelib does not understand the timzonedb data format, please upgrade\n";
+ $data .= "#endif\n\n";
+
+ $data .= "#ifdef TIMELIB_SUPPORT_SLIM_FILE\n";
+ $data .= addData( $slimIndex, $slimData );
+ $data .= "#else\n";
+ $data .= addData( $fatIndex, $fatData );
+ $data .= "#endif\n\n";
+
+ $version = getVersion();
+ $data .= "const timelib_tzdb timezonedb_builtin = { \"{$version}\", {$elements}, timezonedb_idx_builtin, timelib_timezone_db_data_builtin };\n";
+
+ file_put_contents( 'timezonedb.h', $data );
+}
+
+$tab = readZoneTab( 'code/zone.tab' );
+list( $fatIndex, $fatData, $slimIndex, $slimData ) = createDataAndIndex( $tab );
+writeTimelibH( $fatIndex, $fatData, $slimIndex, $slimData );
+?>