Файл: silawar.ru/protected/components/LocalTime.php
Строк: 365
<?php
class LocalTime extends CApplicationComponent
{
/*
* Notes
* 1. Column field types must be timestamp not date, time, datetime
* This is because timestamp columns are stored as UTC then converted to the specified timezone
* date, time and datetime columns don't save the timezone
* 2. Set the timezone to UTC in protected/config/main.php
* so that all retrieved times are in the UTC timezone for consistency
* 'db'=>array(
* ...
* 'initSQLs'=>array("set names utf8;set time_zone='+00:00';"),
* ),
* 3. When using phpMyAdmin, just use "set time_zone='+00:00'"
* or whatever timezone you require to display timestamps in your zone
* 4. Yii::app()->setTimeZone() and setLanguage() is not saved globally
* So this class is used to save the users timezone and locale
* 5. After a user logs in call Yii::app()->localtime->setLocale('en_gb');
* and Yii->app()->localtime->setTimeZone('Europe/London');
* 6. All date/time formats default to 'short' eg: dd/mm/yyyy hh:mm - no seconds
*/
// Used for setting/getting the global variable - change this if there are conflicts
const _globalTimeZone = 'LocalTime_timezone';
const _globalLocale = 'LocalTime_locale';
// Default server time
const _utc = 'UTC';
// Set the timezone - usually after the user has logged in
// Use one of the supported timezones, eg: Europe/London as this will calculate daylight saving hours
// http://php.net/manual/en/timezones.php
public function setTimezone($timezone)
{
// Save the timezone for the session
Yii::app()->setGlobalState(self::_globalTimeZone,$timezone);
}
// Return the current timezone
public function getTimezone()
{
// Get the localDateTimeZone if its been set
$timezone=Yii::app()->getGlobalState(self::_globalTimeZone);
// Default to UTC if it hasn't
if ($timezone===null)
$timezone=self::_utc;
return($timezone);
}
// Set the locale - usually after the user has logged in
// Use one of the supported locales, eg: en_gb
// http://php.net/manual/en/timezones.php
public function setLocale($locale)
{
// Save the timezone for the session
Yii::app()->setGlobalState(self::_globalLocale,$locale);
}
// Return the current locale
public function getLocale()
{
// Get the localDateTimeZone if its been set
$locale=Yii::app()->getGlobalState(self::_globalLocale);
// Default to yii language if it isn't - note that Yii::app()->setLanguage doesn't save globally
if ($locale===null)
$locale=Yii::app()->language;
return($locale);
}
// Local now() function
// Can use any of the php date() formats to return the local date/time value
// http://php.net/manual/en/function.date.php
public function getLocalNow($format=DATE_ISO8601)
{
$localnow=new DateTime(null,$this->localDateTimeZone);
return $localnow->format($format);
}
// UTC Now() function
// Can use any of the php date() formats to return the UTC date/time value
// http://php.net/manual/en/function.date.php
public function getUTCNow($format=DATE_ISO8601)
{
$utcnow=new DateTime(null,$this->serverDateTimeZone);
return $utcnow->format($format);
}
// Return a datetimezone object for the local time
public function getLocalDateTimeZone($timezone=null)
{
if ($timezone===null)
$timezone = $this->timezone;
// Create a local datetimezone object
$datetimezone = new DateTimeZone($timezone);
return($datetimezone);
}
// Return a datetimezone object for UTC
public function getServerDateTimeZone()
{
// Create a local datetimezone object
$datetimezone = new DateTimeZone(self::_utc);
return($datetimezone);
}
// Converts a timestamp from UTC to a local time
// Expects a date in Y-m-d H:i:s type format and assumes it is UTC
// Returns a date in the local time zone
public function fromUTC($servertimestamp)
{
// Its okay if an ISO8601 time is passed because the timezone in the string will be used and the _serverDateTimeZone object is ignored
$localtime = new DateTime($servertimestamp,$this->serverDateTimeZone);
// Then set the timezone to local and it will be automagically updated, even allowing for daylight saving
$localtime->setTimeZone($this->localDateTimeZone);
// Return as 2010-08-15 15:52:01 for use in the yii app
return($localtime->format('Y-m-d H:i:s'));
}
// Converts a local timestamp to UTC
// Expects a date in Y-m-d H:i:s format and assumes it is the local time zone
// Returns an ISO date in the UTC zone
public function toUTC($localtimestamp)
{
// Create an object using the local time zone - this will account for daylight saving
$servertime = new DateTime($localtimestamp,$this->localDateTimeZone);
// Then set the timezone to UTC and it will be automagically updated
// In theory this step isn't needed if using the ISO8601 format.
$servertime->setTimeZone($this->serverDateTimeZone);
// Return as 2010-08-15T15:52:01+0000 so the timestamp column is properly updated
return($servertime->format(DATE_ISO8601));
}
// Use in afterFind
// Ensure that the SQL "set time_zone='+00:00'" has been set
// Returns a date/time combination based on the current locale
// Expects a date/time in the yyyy-mm-dd hh:mm:ss type format
public function toLocalDateTime($servertimestamp,$datewidth='short',$timewidth='short')
{
// Create a server datetime object
$localtime = new DateTime($servertimestamp,$this->serverDateTimeZone);
// Then set the timezone to local and it will be automagically updated, even allowing for daylight saving
$localtime->setTimeZone($this->localDateTimeZone);
// Get the local yii date+time format
$localformat = $this->getLocalDateTimeFormat($datewidth,$timewidth);
// Convert to php date format
$localformat = $this->YiitoPHPDateFormat($localformat);
// Return as a local datetime
return($localtime->format($localformat));
}
// Use in afterFind
// Ensure that the SQL "set time_zone='+00:00'" has been set
// Returns the date based on the current locale
// Expects a date string in the yyyy-mm-dd hh:mm:ss type format
public function toLocalDate($servertimestamp,$datewidth='short')
{
// Create a server datetime object
$localtime = new DateTime($servertimestamp,$this->serverDateTimeZone);
// Then set the timezone to local and it will be automagically updated, even allowing for daylight saving
$localtime->setTimeZone($this->localDateTimeZone);
// Get the local yii date only format
$localformat = $this->getLocalDateFormat($datewidth);
// Convert to php date format
$localformat = $this->YiitoPHPDateFormat($localformat);
// Return as a local datetime
return($localtime->format($localformat));
}
// Use in beforeSave
// Converts a date/time string in the locale format to an ISO time for saving to the server
// eg 31/12/2011 will become 2011-12-31T00:00:00+0000
public function fromLocalDateTime($localtime,$datewidth='short',$timewidth='short')
{
// Local datetime format
$localformat = $this->getLocalDateTimeFormat($datewidth,$timewidth);
// Uses a modified CDateTimeParser that defaults the time values rather than return false
// Also returns a time string rather than a timestamp just in case the timestamp is the wrong timezone
$defaults = array('year'=>$this->getLocalNow('Y'), 'month'=>$this->getLocalNow('m'), 'day'=>$this->getLocalNow('d'), 'hour'=>0, 'minute'=>0, 'second'=>0 );
$timevalues = DefaultDateTimeParser::parse($localtime, $localformat, $defaults);
// Create a new date time in the local timezone
$servertime = new DateTime($timevalues,$this->localDateTimeZone);
// Set the timezone to UTC
$servertime = $servertime->setTimeZone($this->serverDateTimeZone);
// Return it as an iso date ready for saving
return($servertime->format(DATE_ISO8601));
}
// Returns the local date time format from yii
public function getLocalDateTimeFormat($datewidth='short',$timewidth='short')
{
// Set the language so the local date/time format is returned
// This assumes the locale has already been set
Yii::app()->setLanguage($this->locale);
// This returns the order of the date time combination, eg {1} {0}
$localformat = Yii::app()->locale->getDateTimeFormat();
// Get the local date format - eg dd/MM/yyyy
$localformat = str_replace('{1}', Yii::app()->locale->getDateFormat($datewidth), $localformat);
// Get the local time format with seconds - eg hh:mm:ss
$localformat = str_replace('{0}', Yii::app()->locale->getTimeFormat($timewidth), $localformat);
return $localformat;
}
// Just a wrapper of the yii getDateFormat function
public function getLocalDateFormat($width='short')
{
// Set the language so the local date format is returned
// Assumes the locale has been set
Yii::app()->setLanguage($this->locale);
// Get the local date format - eg dd/MM/yyyy
$localformat = Yii::app()->locale->getDateFormat($width);
return $localformat;
}
// Converts a yii date format to a php date format
// Eg dd/MM/yyyy HH:mm:ss will be converted to d/m/Y H:i:s
public function YiitoPHPDateFormat($dateformat)
{
$patterns = array(
// 'ampm'=>array('a'=>'a','A'=>'A'),
'microseconds'=>array('zzzz'=>'u','z'=>'u'),
'seconds'=>array('ss'=>'s','s'=>'s'),
'minutes'=>array('mm'=>'i','m'=>'i'),
'24hours'=>array('HH'=>'H','H'=>'G'),
'12hours'=>array('hh'=>'h','h'=>'g'),
'years'=>array('yyyy'=>'Y','yy'=>'y'),
'months'=>array('MM'=>'m','M'=>'n'),
'days'=>array('dd'=>'d','d'=>'j'),
);
// Run through each time pattern
foreach($patterns as $pattern)
{
foreach($pattern as $search=>$replace)
{
if (strpos($dateformat,$search)!==false)
{
// We have a winner!
// Replace the first pattern found and then get out of here
$dateformat = str_replace($search, $replace, $dateformat);
break;
}
}
}
return($dateformat);
}
}