如何在PHP中获得格林威治标准时间?

我有一个设置为EST的服务器,数据库中的所有logging均设置为EST。 我想知道如何将其设置为GMT。 我想为我的用户提供一个时区选项。

无论服务器在哪个GMT时区,这里都是非常简单的获取时区的时间和date的方法。 这是用time()gmdate()函数完成的。 gmdate()函数通常会给我们GMT时间,但是通过使用time()函数,我们可以得到GMT + N或GMT-N,这意味着我们可以得到任何GMT时区的时间。

例如,如果您必须获取GMT + 5的时间,您可以按如下所示进行

 <?php $offset=5*60*60; //converting 5 hours to seconds. $dateFormat="dmY H:i"; $timeNdate=gmdate($dateFormat, time()+$offset); ?> 

现在,如果你必须得到GMT-5的时间,你可以从time()减去偏移量,而不是增加它,就像在下面的例子中,我们得到GMT-4的时间

 <?php $offset=4*60*60; //converting 4 hours to seconds. $dateFormat="dmY H:i"; //set the date format $timeNdate=gmdate($dateFormat, time()-$offset); //get GMT date - 4 ?> 

强烈build议避免使用UNIX时间戳来使它看起来像一个不同的时区。 这是我学到的一个教训,太多次了。

时间戳是1970年1月1日午夜以来的秒数。 不pipe你在世界的什么地方,一个给定的时间戳代表的是同一时刻,不pipe时区。 是的,时间戳“0”意味着在澳大利亚上午10点,在伦敦1/1/70上午的午夜和在洛杉矶的31/12/69下午5点,但这并不意味着您可以简单地加上或减去数值并保证准确性。

每年都会把我塞满太长时间的一个黄金例子就是夏时制的到来。 夏令时意味着有世界某些地方不存在的“时钟”。 例如,在美国大部分地区,2006年4月2日凌晨2时01分没有这样的时间。

尽pipe已经足够准意识地咆哮了。 我的build议是将您的date作为时间戳存储在数据库中,然后…

  • 如果您需要服务器的本地时间,请使用date()
  • 如果你需要得到GMT,那么使用gmdate()
  • 如果您需要获取不同的时区,请使用date_default_timezone_set() ,然后使用date()

例如,

 $timestamp = time(); echo "BRISBANE: " . date('r', $timestamp) . "\n"; echo " UTC: " . gmdate('r', $timestamp) . "\n"; date_default_timezone_set('Africa/Johannesburg'); echo " JOBURG: " . date('r', $timestamp) . "\n"; // BRISBANE: Tue, 12 May 2009 18:28:20 +1000 // UTC: Tue, 12 May 2009 08:28:20 +0000 // JOBURG: Tue, 12 May 2009 10:28:20 +0200 

这将保持你的价值清洁(你不必担心添加偏移,然后在保存之前扣除),它将遵守所有的夏令时规则,而且你也不必查找该地点的时区你要。

需要注意的是,如果使用date('Z')转换存储在数据库中的date,那么将date时间戳记作为第二个参数,否则结果将不准确。

例如

在英国,有时date('Z')会给3600,有时会给0。

 echo date('Z', strtotime('2012-01-01')); 

给0

 echo date('Z', strtotime('2012-07-01')); 

给3600

所以纯粹使用strtotime($ dbDateValue) – date('Z')可能是错误的

而是使用:

 $dbDateTimestamp = strtotime($dbDateValue); // where $dbDateValue something like 2012-01-01 22:34:00 $utcTimestamp = strtotime($dbDateTimestamp) - date('Z', $dbDateTimestamp); 

这当然依赖于PHP和数据库都被设置为相同的时区。

这里是与GMT不同的时区列表,希望这有帮助!

 echo '<pre>'; $zones_array = array(); $timestamp = time(); # to maintain the original timezone, store before $default_timezone = date_default_timezone_get(); foreach (timezone_identifiers_list() as $key => $zone) { date_default_timezone_set($zone); $zones_array[$key]['zone'] = $zone; $zones_array[$key]['diff_from_GMT'] = date('P', $timestamp); } # to maintain the original timezone, re-set after date_default_timezone_set($default_timezone); print_r($zones_array); 

谢谢!

我受到这个问题的启发,编写了一个替代函数来将时间戳转换为所需的时区。

所以,CORRECT程序步骤来logging,显示(转换)时间:

 1) record timestamp with time() 2) If you need to get a different timezone, use: 2.1) Class based: 2.1.1) DateTime class + setTimezone or 2.1.2) date_default_timezone_set() and then date() 2.1.1) is better and more flexible than 2.1.2) Function: function getLTime_class($ts, $uTZ, $format_str="Ymd H:i", $sTZ="America/Toronto"){ // $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); // $uTZ - TZ string (ex: 'America/Toronto'); convert timestamp to this TimeZone // $sTZ - TZ string (ex: 'America/Toronto'); convert timestamp from this TimeZone $TimeZone_server=new DateTimeZone($sTZ); $date_obj=new DateTime("@$ts", $TimeZone_server); $TimeZone_local=new DateTimeZone($uTZ); $date_obj->setTimeZone($TimeZone_local); return $date_obj->format($format_str); } Usage: $date_input=$_POST['date_input']; //read from POST $ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); $userTZ='America/Toronto'; //read from user params $result=getLTime_class($ts, $userTZ, 'Ymd H:i:s'); 2.2) Non-Class based: Function: //this function replaces the function with DateTime class. It's faster. $uTZoffset is integer. function getLTime_nonclass($ts, $uTZoffset, $format_str="Ymd H:i"){ // $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); // $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5) $ts_offset=date('Z',$ts); if ($uTZoffset) $add_offset=$ts_offset-date('Z'); //when not UTC else $add_offset=0; //when UTC return date($format_str,$ts-$ts_offset+$uTZoffset*3600+$add_offset); } Usage: $date_input=$_POST['date_input']; //read from POST $ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone); $uTZoffset=-4; //read from user params. $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5) $result=getLTime_nonclass($ts, $uTZoffset, 'Ymd H:i:s'); 

结果:

$ date_input = 2012-08-17 12:00:00

 Server date: summer (2013-08-26) getLTime_class => $userTZ='America/Toronto' => 2012-08-17 12:00:00 getLTime_nonclass => $uTZoffset=-4 => 2012-08-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-08-17 16:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-08-17 16:00:00 Server date: winter (2013-02-26) getLTime_class => $userTZ='America/Toronto' => 2012-08-17 12:00:00 getLTime_nonclass => $uTZoffset=-5 => 2012-08-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-08-17 16:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-08-17 16:00:00 

$ date_input = 2012-02-17 12:00:00

 Server date: summer (2013-08-26) getLTime_class => $userTZ='America/Toronto' => 2012-02-17 12:00:00 getLTime_nonclass => $uTZoffset=-4 => 2012-02-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-02-17 17:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-02-17 17:00:00 Server date: winter (2013-02-26) getLTime_class => $userTZ='America/Toronto' => 2012-02-17 12:00:00 getLTime_nonclass => $uTZoffset=-5 => 2012-02-17 12:00:00 getLTime_class => $userTZ='UTC' => 2012-02-17 17:00:00 getLTime_nonclass => $uTZoffset=0 => 2012-02-17 17:00:00 

我决定让LTime_nonclass希望使转换比使用类更快。 我所要求的是确认getLTime_nonclass是getLTime_class的有效替代。 请随时发表您的意见。 谢谢

很多时候在GMT + 0的DB中有必要的logging时间有任务,而函数time()会返回服务器的时间。 下一个function可能解决的问题:

 /** * Converts a local Unix timestamp to GMT * * @param int Unix timestamp * @return int */ function local_to_gmt($time = '') { if ($time === '') { $time = time(); } return mktime( gmdate('G', $time), gmdate('i', $time), gmdate('s', $time), gmdate('n', $time), gmdate('j', $time), gmdate('Y', $time) ); }