X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=TimeZone.php;h=72a629fb780465257975754526e578e3a62fba2b;hb=refs%2Fheads%2Fmaster;hp=290942029f9f373340051f67474094545c347726;hpb=06e281e43a81ec043f1871a8b7d06ddadfa8c993;p=Pman.Core diff --git a/TimeZone.php b/TimeZone.php index 29094202..bdad4cf4 100644 --- a/TimeZone.php +++ b/TimeZone.php @@ -16,24 +16,28 @@ class Pman_Core_TimeZone extends Pman function get($base, $opts=array()) { - self::getOffsets(); + $this->lang = !empty($_REQUEST['lang']) && in_array($_REQUEST['lang'], array('en', 'zh_CN')) ? $_REQUEST['lang'] : 'en'; + self::getTimezones($this->lang); $data = array(); - foreach(self::$offsets as $tz => $o) { - $arr = explode('/', $tz); - - if(!empty($_REQUEST['region']) && $_REQUEST['region'] != $arr[0]) { + foreach(self::$timezones as $tz => $o) { + if(!empty($_REQUEST['region']) && $_REQUEST['region'] != $o['region']) { continue; } - if(!empty($_REQUEST['query']['area_start'])){ + if( + !empty($_REQUEST['query']['area_start']) + && + substr(strtolower($o['area']), 0, strlen($_REQUEST['query']['area_start'])) != strtolower($_REQUEST['query']['area_start']) + ){ + continue; } $data[] = array( - 'region' => $arr[0], - 'area' => $arr[1], - 'offset' => $o, - 'displayArea' => self::getDisplayArea($tz) + 'region' => $o['region'], + 'area' => $o['area'], + 'displayRegion' => $o['displayRegion'], + 'displayArea' => $o['displayArea'] ); } @@ -46,7 +50,7 @@ class Pman_Core_TimeZone extends Pman 'fields' => array( 'region', 'area', - 'offset', + 'displayRegion', 'displayArea' ) ), @@ -61,57 +65,204 @@ class Pman_Core_TimeZone extends Pman die('Invalid post'); } - static $offsets = array(); + static $timezones = array(); - static function getOffsets() + static function getTimezones($lang) { - if(!empty(self::$offsets)) { - return self::$offsets; + if(!empty(self::$timezones)) { + return self::$timezones; } - - $ce = DB_DataObject::factory('core_enum'); - $ce->query(' + $ce = DB_DataObject::factory('core_enum'); + $ce->query(" SELECT - *, TIME_FORMAT(TIMEDIFF(NOW(), CONVERT_TZ(NOW(), Name, "UTC")), "%H:%i") as offset + *, TIME_FORMAT(TIMEDIFF(NOW(), CONVERT_TZ(NOW(), Name, 'UTC')), '%H:%i') as timeOffset FROM mysql.time_zone_name + WHERE + Name LIKE '%/%' + AND + Name NOT LIKE '%/%/%' + AND + Name NOT LIKE 'right%' + AND + Name NOT LIKE 'posix%' + AND + Name NOT LIKE 'Etc%' ORDER BY - offset DESC, - Name DESC - '); + SUBSTRING_INDEX(Name, '/', 1) ASC, + timeoffset ASC, + Name ASC + "); - while($ce->fetch()) { - // ignroe timezone such as 'CET' and 'America/Argentina/Buenos_Aires' - if(substr_count($ce->Name, '/') != 1) { + $regions = DB_DataObject::factory('core_enum'); + $regions->setFrom(array( + 'etype' => 'Timezone.Region', + 'active' => 1 + )); + $regionIds = $regions->fetchAll('display_name', 'id'); + + $areas = DB_DataObject::factory('core_enum'); + $areas->setFrom(array( + 'etype' => 'Timezone.Area', + 'active' => 1 + )); + $areaIds = $areas->fetchAll('display_name', 'id'); + + + $ct = DB_DataObject::factory('core_templatestr'); + $ct->lang = $lang; + $ct->on_table = 'core_enum'; + $ct->active = 1; + $translations = array(); + foreach($ct->fetchAll() as $t) { + if(empty($t->txt)) { continue; } + $translations[$t->on_id][$t->on_col] = $t->txt; + } + + while($ce->fetch()) { + // ignroe timezone such as 'CET' and 'America/Argentina/Buenos_Aires' + $ar = explode('/', $ce->Name); // ignore timezone such as 'Etc/GMT+8' - if($ar[0] == 'Etc') { - continue; + + $region = $displayRegion = $ar[0]; + + if(!empty($translations[$regionIds[$region]]['display_name'])) { + $displayRegion = $translations[$regionIds[$region]]['display_name']; } - self::$offsets[$ce->Name] = substr($ce->offset, 0, 1) == '-' ? $ce->offset : '+' . $ce->offset; + $area = $ar[1]; + $displayArea = str_replace('_', ' ', $area); + + if(!empty($translations[$areaIds[$displayArea]]['display_name'])) { + $displayArea = $translations[$areaIds[$displayArea]]['display_name']; + } + + $timeOffset = ((substr($ce->timeOffset, 0, 1) == '-') ? '' : '+') . $ce->timeOffset; + $displayOffset = '(GMT ' . $timeOffset . ')'; + + self::$timezones[$ce->Name] = array( + 'region' => $region, + 'area' => $area, + 'displayName' => $ar[0] . '/' . $displayArea . ' ' . $displayOffset, + 'displayRegion' => $displayRegion, + 'displayArea' => $displayArea . ' ' . $displayOffset + ); } - return self::$offsets; + return self::$timezones; } - static function getDisplayArea($timezone) + static function isValidTimeZone($tz) { + try { + new DateTimeZone($tz); + } + catch (Exception $e) { + return false; + } + + return true; + } + + static function toRegion($tz) { - self::getOffsets(); + if(!self::isValidTimeZone($tz)) { + return ''; + } + + return explode('/', $tz)[0]; + } - // invalid timezone - if(!isset(self::$offsets[$timezone])) { + static function toArea($tz) + { + if(!self::isValidTimeZone($tz)) { return ''; } - $ar = explode('/', $timezone); + return explode('/', $tz)[1]; + } + + static function toTimeOffset($dt, $tz) + { + if(!self::isValidTimeZone($tz)) { + return ''; + } - // e.g. 'Hong_Kong (GMT +08:00)' - return $ar[1] . ' (GMT ' . self::$offsets[$timezone] . ')'; + if($dt == '0000-00-00 00:00:00' || $dt == '') { + $dt = 'NOW'; + } + + $date = new DateTime($dt, new DateTimeZone($tz)); + return $date->format('P'); } - + static function toDisplayRegion($lang, $tz) + { + $region = explode('/', $tz)[0]; + + $ce = DB_DataObject::factory('core_enum'); + $ce->setFrom(array( + 'etype' => 'Timezone.Region', + 'active' => 1, + 'name' => $region, + 'display_name' => $region + )); + if(!$ce->find(true)) { + return $region; + } + + $ct = DB_DataObject::factory('core_templatestr'); + $ct->setFrom(array( + 'lang' => $lang, + 'on_table' => 'core_enum', + 'on_id' => $ce->id, + 'on_col' => 'display_name', + 'active' => 1 + )); + if(!$ct->find(true) || empty($ct->txt)) { + return $region; + } + return $ct->txt; + } + + static function toDisplayArea($lang, $dt, $tz) + { + $displayArea = str_replace('_', ' ', self::toArea($tz)); + $displayOffset = '(GMT ' . self::toTimeOffset($dt,$tz) . ')'; + + $ce = DB_DataObject::factory('core_enum'); + $ce->setFrom(array( + 'etype' => 'Timezone.Area', + 'active' => 1, + 'name' => $displayArea, + 'display_name' => $displayArea + )); + + if(!$ce->find(true)) { + return $displayArea . ' ' . $displayOffset; + } + + $ct = DB_DataObject::factory('core_templatestr'); + $ct->setFrom(array( + 'lang' => $lang, + 'on_table' => 'core_enum', + 'on_id' => $ce->id, + 'on_col' => 'display_name', + 'active' => 1 + )); + if(!$ct->find(true) || empty($ct->txt)) { + return $displayArea . ' ' . $displayOffset; + } + + return $ct->txt . ' ' . $displayOffset; + + } + + static function toDisplayName($lang, $dt, $tz) + { + return self::toDisplayRegion($lang, $tz) . '/' . self::toDisplayArea($lang, $dt, $tz); + } } \ No newline at end of file