web-dev-qa-db-ja.com

PHPでグリニッジ標準時を取得するにはどうすればよいですか?

サーバーがESTに設定されており、データベース内のすべてのレコードがESTに設定されています。 GMTに設定する方法を知りたいです。ユーザーにタイムゾーンオプションを提供したい。

44
drikoda

サーバーがどのGMTタイムゾーンであっても、任意のタイムゾーンの日時を取得する非常に簡単な方法を次に示します。これは、time()およびgmdate()関数を使用して行われます。 gmdate()関数は通常GMT時間を提供しますが、time()関数でトリックを行うことでGMT + NまたはGMT-Nを取得できます。つまり、すべてのGMTの時間を取得できますタイムゾーン。

たとえば、GMT + 5の時刻を取得する必要がある場合、次のように実行できます。

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

GMT-5の時刻を取得する必要がある場合は、GMT-4の時刻を取得する次の例のように、time()に追加する代わりに、オフセットを単に減算することができます。

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

私は強く、UNIXタイムスタンプを台無しにして別のタイムゾーンのように見せることをお勧めします。これは私が苦労して学んだ教訓です。

タイムスタンプは、1970年1月1日午前0時(GMT)からの秒数です。世界のどこにいても、タイムゾーンに関係なく、特定のタイムスタンプはまったく同じ瞬間を表します。はい、タイムスタンプ「0」は、オーストラリアでは午前10時1月70日、ロンドンでは午前1時70分1日、ロサンゼルスでは69年12月31日午後5時を意味します。正確さ。

毎年あまりにも長い間私を困惑させた黄金の例は、夏時間が節約されることでした。夏時間とは、世界の特定の地域には存在しない「時刻」があることを意味します。たとえば、米国のほとんどの地域では、2006年4月2日午前2時1分などの時間はありませんでした。

しかし、十分に準明瞭な暴言。私のアドバイスは、日付をタイムスタンプとしてデータベースに保存することです...

  • サーバーで現地時間が必要な場合は、 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

これにより、値がクリーンに保たれ(オフセットを追加してから保存する前に減算することを心配する必要はありません)、すべての夏時間規則を尊重し、場所のタイムゾーンを調べる必要もありませんあなたが欲しい。

69
nickf

Date( 'Z')を使用してデータベースに保存されている日付を変換する場合、日付に2番目の引数としてタイムスタンプを指定すると、結果が正確にならないことに注意することが重要です。

例えば.

英国では、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とデータベースが両方とも同じタイムゾーンに設定されていることに依存しています。

4
Alistair Burns

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);

ありがとう!

4
Ahmad Tahboub

この質問に触発されて、タイムスタンプを必要なタイムゾーンに変換する代替関数を作成しました。

そのため、時間を記録、表示(変換)する正しい手順は次のとおりです。

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="Y.m.d 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, 'Y-m-d 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="Y.m.d 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, 'Y-m-d 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 

クラスを使用するよりも高速に変換できるように、getLTime_nonclassを使用することにしました。私が尋ねるのは、getLTime_nonclassがgetLTime_classの有効な代替品であることを確認することだけです。ご意見をお聞かせください。ありがとう

1
ihtus

GMT + 0でDBに時間を記録する必要があるときに多くの時間がありますが、関数time()はサーバーの時間を返します。次の機能による解決の可能性:

/**
     * 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)
        );
    }
0
realmag777