Improve internal timezone handling

This commit is contained in:
Kijin Sung 2016-02-04 09:11:56 +09:00
parent e971e7a725
commit d5ba13d7e1
4 changed files with 112 additions and 11 deletions

View file

@ -10,7 +10,7 @@
class Context class Context
{ {
/** /**
* Allow rewrite * Allow rewritel
* @var bool TRUE: using rewrite mod, FALSE: otherwise * @var bool TRUE: using rewrite mod, FALSE: otherwise
*/ */
public $allow_rewrite = FALSE; public $allow_rewrite = FALSE;
@ -532,7 +532,6 @@ class Context
$db_info->time_zone = sprintf('%s%02d%02d', $db_info->time_zone >= 0 ? '+' : '-', abs($db_info->time_zone) / 3600, (abs($db_info->time_zone) % 3600 / 60)); $db_info->time_zone = sprintf('%s%02d%02d', $db_info->time_zone >= 0 ? '+' : '-', abs($db_info->time_zone) / 3600, (abs($db_info->time_zone) % 3600 / 60));
$GLOBALS['_time_zone'] = $db_info->time_zone; $GLOBALS['_time_zone'] = $db_info->time_zone;
$GLOBALS['_time_zone_offset'] = $config['locale']['internal_timezone']; $GLOBALS['_time_zone_offset'] = $config['locale']['internal_timezone'];
$GLOBALS['_qmail_compatibility'] = 'N';
$db_info->delay_session = $config['session']['delay'] ? 'Y' : 'N'; $db_info->delay_session = $config['session']['delay'] ? 'Y' : 'N';
$db_info->use_db_session = $config['session']['use_db'] ? 'Y' : 'N'; $db_info->use_db_session = $config['session']['use_db'] ? 'Y' : 'N';
$db_info->minify_scripts = $config['view']['minify_scripts'] ? 'Y' : 'N'; $db_info->minify_scripts = $config['view']['minify_scripts'] ? 'Y' : 'N';
@ -547,7 +546,13 @@ class Context
$db_info->use_prepared_statements = $config['use_prepared_statements'] ? 'Y' : 'N'; $db_info->use_prepared_statements = $config['use_prepared_statements'] ? 'Y' : 'N';
$db_info->use_rewrite = $config['use_rewrite'] ? 'Y' : 'N'; $db_info->use_rewrite = $config['use_rewrite'] ? 'Y' : 'N';
$db_info->use_sso = $config['use_sso'] ? 'Y' : 'N'; $db_info->use_sso = $config['use_sso'] ? 'Y' : 'N';
// Save old format to Context instance.
self::$_instance->db_info = $db_info; self::$_instance->db_info = $db_info;
// Set the internal timezone.
$internal_timezone = Rhymix\Framework\DateTime::getTimezoneNameByOffset($config['locale']['internal_timezone']);
date_default_timezone_set($internal_timezone);
} }
/** /**

View file

@ -257,15 +257,13 @@ class Config
$config['locale']['enabled_lang'] = array_values($lang_selected); $config['locale']['enabled_lang'] = array_values($lang_selected);
// Convert timezone configuration. // Convert timezone configuration.
$old_timezone = intval(get_time_zone_offset($db_info->time_zone ?: '+0900') / 3600); $old_timezone = get_time_zone_offset($db_info->time_zone ?: '+0900');
switch ($old_timezone) switch ($old_timezone)
{ {
case 9: case 32400:
$config['locale']['default_timezone'] = 'Asia/Seoul'; break; $config['locale']['default_timezone'] = 'Asia/Seoul'; break;
case 0:
$config['locale']['default_timezone'] = 'Etc/UTC'; break;
default: default:
$config['locale']['default_timezone'] = 'Etc/GMT' . ($old_timezone > 0 ? '-' : '+') . abs($old_timezone); $config['locale']['default_timezone'] = DateTime::getTimezoneNameByOffset($old_timezone);
} }
$config['locale']['internal_timezone'] = intval(date('Z')); $config['locale']['internal_timezone'] = intval(date('Z'));

View file

@ -0,0 +1,101 @@
<?php
namespace Rhymix\Framework;
/**
* The datetime class.
*/
class DateTime
{
/**
* Time zone objects and settings are cached here.
*/
protected static $_timezones = array();
/**
* Get the timezone to display for the current user.
*
* @return string
*/
public static function getCurrentUserTimezone()
{
if (isset($_SESSION['timezone']))
{
return $_SESSION['timezone'];
}
else
{
return Config::get('locale.default_timezone');
}
}
/**
* Get the list of time zones supported on this server.
*
* @return array
*/
public static function getTimezoneList()
{
$result = array();
$tzlist = \DateTimeZone::listIdentifiers();
foreach ($tzlist as $tzid)
{
if (!preg_match('/^(?:A|Europe|Indian|Pacific)/', $tzid)) continue;
$name = str_replace('_', ' ', $tzid);
$datetime = new \DateTime(null, new \DateTimeZone($tzid));
$offset = $datetime->getOffset();
$offset = ($offset >= 0 ? '+' : '-') . sprintf('%02d', floor(abs($offset) / 3600)) . ':' . sprintf('%02d', (abs($offset) % 3600) / 60);
unset($datetime);
$result[$tzid] = "$name ($offset)";
}
asort($result);
$result['Etc/UTC'] = 'GMT/UTC (+00:00)';
return $result;
}
/**
* Get the absolute (UTC) offset of a timezone.
*
* @param string $timezone Timezone identifier, e.g. Asia/Seoul
* @param int $timestamp Unix timestamp (optional, default is now)
* @return int
*/
public static function getTimezoneOffset($timezone, $timestamp = null)
{
if (!isset(self::$_timezones[$timezone]))
{
self::$_timezones[$timezone] = new \DateTimeZone($timezone);
}
$datetime = new \DateTime();
$datetime->setTimestamp($timestamp ?: time());
$datetime->setTimezone(self::$_timezones[$timezone]);
return $datetime->getOffset();
}
/**
* Get the relative offset between a timezone and Rhymix's internal timezone.
*
* @param string $timezone Timezone identifier, e.g. Asia/Seoul
* @param int $timestamp Unix timestamp (optional, default is now)
* @return int
*/
public static function getTimezoneOffsetFromInternal($timezone, $timestamp = null)
{
return self::getTimezoneOffset($timezone, $timestamp) - Config::get('locale.internal_timezone');
}
/**
* Get a PHP time zone by UTC offset.
*
* @param int $offset
* @return bool
*/
public static function getTimezoneNameByOffset($offset)
{
switch ($offset)
{
case 0: return 'Etc/UTC';
default: return 'Etc/GMT' . ($offset > 0 ? '-' : '+') . intval(abs($offset / 3600));
}
}
}

View file

@ -146,10 +146,7 @@ class installView extends install
} }
// Get list of time zones. // Get list of time zones.
$timezones = DateTimeZone::listIdentifiers(); Context::set('timezones', Rhymix\Framework\DateTime::getTimezoneList());
natcasesort($timezones);
$timezones = array_combine($timezones, $timezones);
Context::set('timezones', $timezones);
// Automatically select a time zone for the user. // Automatically select a time zone for the user.
Context::set('selected_timezone', $this->detectUserTimeZone()); Context::set('selected_timezone', $this->detectUserTimeZone());