PHPで日時のタイムゾーンを変更する

php.iniのdate.timezoneで設定されたタイムゾーンでの現在時刻から、DateTimeクラスを利用してUTC(協定世界時)など、任意のタイムゾーンに変更する場合、

$t = new DateTime();

// UTCへ変換
$t->setTimezone( new Timezone('UTC') );
echo $t->format(DateTime::ISO8601);

// ロンドンのタイムゾーンへの変換
$t->setTimezone( new DateTimeZone('Europe/London') );
echo $t->format(DateTime::ISO8601);

// N.Y.のタイムゾーンへの変換
$t->setTimezone( new DateTimeZone('America/New_York') );
echo $t->format(DateTime::ISO8601);

なお、実際に試した限りではサマータイムをちゃんと認識します。

当たり前といえば当たり前ですが、現在日時でなくてもDateTimeオブジェクトを作成できます。この際、引数で渡した日時にタイムゾーンが含まれている場合はそのタイムゾーンが、そうでない場合はphp.iniのdate.timezoneで設定されたタイムゾーンが適用されます。

$t = new DateTime('09/Sep/2011:09:00:00 +0100');
echo $t_ldn->format(DateTime::ISO8601); // 2011-09-09T09:00:00+0100

$t = new DateTime('2011-09-09T09:00:00Z');
echo $t->format(DateTime::ISO8601); // 2011-09-09T09:00:00+0000

$t = new DateTime('2011-09-09T09:00:00');
echo $t->format(DateTime::ISO8601); // 2011-09-09T09:00:00+0900

引数で渡した日時にタイムゾーンが含まれない場合でも、第二引数でタイムゾーンを指定すれば、任意のタイムゾーンが適用できます。

$t = new DateTime( '2011-09-09T09:00:00', new Timezone('Europe/Paris') );
echo $t->format(DateTime::ISO8601); // 2011-09-09T09:00:00+0200

逆に第一引数で渡した日時にタイムゾーンが含まれている場合、第二引数でタイムゾーンを渡しても、第二引数のタイムゾーンは無視されます。

おまけで手続き型の場合

date_create(), timezone_open()の両関数はそれぞれDateTime::__construct, DateTimeZone::__constructのエイリアスなので、これらを使うと手続き型でも同じことができます。

また、date_default_timezone_set()関数で一時的にタイムゾーンを変更することができるので、例えばphp.iniのdate.timezoneで設定されたタイムゾーン(日本標準時)での現在時刻をUTCに変換するとして、

$date = date('Y-m-d G:i:s');

date_default_timezone_set('UTC');
echo strftime( '%FT%T%z', strtotime($date) );

と書くこともできます。