X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=TimeZone.php;h=72a629fb780465257975754526e578e3a62fba2b;hb=refs%2Fheads%2Fmaster;hp=de3784973b90c6df8207ba67c8c5d4f529ff1896;hpb=e674b79b187bb26bef26b62e4408e98419982109;p=Pman.Core diff --git a/TimeZone.php b/TimeZone.php index de378497..bdad4cf4 100644 --- a/TimeZone.php +++ b/TimeZone.php @@ -16,11 +16,12 @@ class Pman_Core_TimeZone extends Pman function get($base, $opts=array()) { - self::getTimezones(); + $this->lang = !empty($_REQUEST['lang']) && in_array($_REQUEST['lang'], array('en', 'zh_CN')) ? $_REQUEST['lang'] : 'en'; + self::getTimezones($this->lang); $data = array(); - foreach(self::$tiemzones as $tz => $o) { + foreach(self::$timezones as $tz => $o) { if(!empty($_REQUEST['region']) && $_REQUEST['region'] != $o['region']) { continue; } @@ -34,6 +35,8 @@ class Pman_Core_TimeZone extends Pman } $data[] = array( 'region' => $o['region'], + 'area' => $o['area'], + 'displayRegion' => $o['displayRegion'], 'displayArea' => $o['displayArea'] ); } @@ -46,6 +49,8 @@ class Pman_Core_TimeZone extends Pman 'totalProperty' => 'total', 'fields' => array( 'region', + 'area', + 'displayRegion', 'displayArea' ) ), @@ -62,50 +67,202 @@ class Pman_Core_TimeZone extends Pman static $timezones = array(); - static function getTimezones() + static function getTimezones($lang) { 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 timeOffset + *, 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 - timeoffset 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']; } - $displayOffset = '(GMT ' . ((substr($ce->timeOffset, 0, 1) == '-') ? '' : '+') . $ce->timeOffset . ')'; - $offsetAr = explode(':', $ce->timeOffset); - $offsetAr[0] + ($offsetAr[1] / 60) - + $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' => $ar[0], - 'area' => $ar[1], - 'displayName' => $ce->Name . ' ' . $displayOffset, - 'displayArea' => $ar[1] . ' ' . $displayOffset + 'region' => $region, + 'area' => $area, + 'displayName' => $ar[0] . '/' . $displayArea . ' ' . $displayOffset, + 'displayRegion' => $displayRegion, + 'displayArea' => $displayArea . ' ' . $displayOffset ); } return self::$timezones; } + static function isValidTimeZone($tz) { + try { + new DateTimeZone($tz); + } + catch (Exception $e) { + return false; + } + + return true; + } + + static function toRegion($tz) + { + if(!self::isValidTimeZone($tz)) { + return ''; + } + + return explode('/', $tz)[0]; + } + + static function toArea($tz) + { + if(!self::isValidTimeZone($tz)) { + return ''; + } + + return explode('/', $tz)[1]; + } + static function toTimeOffset($dt, $tz) + { + if(!self::isValidTimeZone($tz)) { + return ''; + } + + 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