DateTime::setTimezone

date_timezone_set

(PHP 5 >= 5.2.0, PHP 7, PHP 8)

DateTime::setTimezone -- date_timezone_set设置 DateTime 对象的时区

说明

面向对象风格

public DateTime::setTimezone(DateTimeZone $timezone): DateTime

过程化风格

DateTime object 设置新时区。

DateTimeImmutable::setTimezone() 一样,但适用于 DateTime

过程化版本将 DateTime 对象作为第一个参数。

参数

object

仅过程化风格:由 date_create() 返回的 DateTime 类型的对象。此函数会修改这个对象。

timezone

代表所需时区的 DateTimeZone 对象。

返回值

返回链式调用的 DateTime 对象。调用此方法时,底层的时间点不会更改。

示例

示例 #1 DateTime::setTimeZone() 示例

面向对象风格

<?php
$date
= new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo
$date->format('Y-m-d H:i:sP') . "\n";

$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo
$date->format('Y-m-d H:i:sP') . "\n";
?>

过程化风格

<?php
$date
= date_create('2000-01-01', timezone_open('Pacific/Nauru'));
echo
date_format($date, 'Y-m-d H:i:sP') . "\n";

date_timezone_set($date, timezone_open('Pacific/Chatham'));
echo
date_format($date, 'Y-m-d H:i:sP') . "\n";
?>

以上示例会输出:

2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45

参见

add a note add a note

User Contributed Notes 6 notes

up
53
jamsilver at gmail dot com
9 years ago
In response to the other comments expressing surprise that changing the timezone does not affect the timestamp:

A UNIX timestamp is defined as the number of seconds that have elapsed since 00:00:00 (UTC), Thursday, 1 January 1970.

So: with respect to UTC. Always.

Calling setTimezone() never changes the actual "absolute", underlying, moment-in-time itself. It only changes the timezone you wish to "view" that moment "from". Consider the following:

<?php
// A time in London.
$datetime = new DateTime('2015-06-22T10:40:25', new DateTimeZone('Europe/London'));

// I wonder how that SAME moment-in-time would
// be described in other places around the world.
$datetime->setTimezone(new DateTimeZone('Australia/Sydney'));
print
$datetime->format('Y-m-d H:i:s (e)');
 
// 2015-06-22 19:40:25 (Australia/Sydney)

$datetime->setTimezone(new DateTimeZone('America/New_York'));
print
$datetime->format('Y-m-d H:i:s (e)');
 
// 2015-06-22 05:40:25 (America/New_York)

$datetime->setTimezone(new DateTimeZone('Asia/Calcutta'));
print
$datetime->format('Y-m-d H:i:s (e)');
 
// 2015-06-22 15:10:25 (Asia/Calcutta)
?>

Please note that ALL of these date strings unambiguously represent the exact same moment-in-time. Therefore, calling getTimestamp() at any stage will return the same result:

<?php
$datetime
->getTimestamp();
 
// 1434966025
?>
up
4
Alex
8 years ago
Surprising that the timezone works only specified in the separated method in case if you'll use ->format('U').

this does NOT apply timezone +0200 in the $timestamp:

<?php
    $date
= new \DateTime(strtotime(time()), new DateTimeZone(system('date +%z')));
   
$timestamp = $date->format('U');
?>

this will apply timezone +0200 in the $timestamp:

<?php
    $date
= new \DateTime(strtotime(time()));
   
$date->setTimezone(new DateTimeZone(system('date +%z')));
   
$timestamp = $date->format('U');
?>
up
5
keithm at aoeex dot com
14 years ago
The timestamp value represented by the DateTime object is not modified when you set the timezone using this method.  Only the timezone, and thus the resulting display formatting, is affected.

This can be seen using the following test code:
<?php
$MNTTZ
= new DateTimeZone('America/Denver');
$ESTTZ = new DateTimeZone('America/New_York');

$dt = new DateTime('11/24/2009 2:00 pm', $MNTTZ);
var_dump($dt->format(DATE_RFC822), $dt->format('U'));
$dt->setTimezone($ESTTZ);
var_dump($dt->format(DATE_RFC822), $dt->format('U'));

/** Output:
string(29) "Tue, 24 Nov 09 14:00:00 -0700"
string(10) "1259096400"
string(29) "Tue, 24 Nov 09 16:00:00 -0500"
string(10) "1259096400"
**/
?>

As such, you can use this to easily convert between timezones for display purposes.
up
1
forzi at mail333 dot com
10 years ago
<?php
$MNTTZ
= new DateTimeZone('America/Denver');
$ESTTZ = new DateTimeZone('America/New_York');

$dt = new DateTime('11/24/2009 2:00 pm', $MNTTZ);
var_dump($dt->format(DATE_RFC822), $dt->format('U'));
$dt->setTimezone($ESTTZ);
var_dump($dt->format(DATE_RFC822), $dt->format('U'));
?>
doesn't changes timestamp
But
<?php
$MNTTZ
= new DateTimeZone('America/Denver');
$ESTTZ = new DateTimeZone('-0500');

$dt = new DateTime('11/24/2009 2:00 pm', $MNTTZ);
var_dump($dt->format(DATE_RFC822), $dt->format('U'));
$dt->setTimezone($ESTTZ);
var_dump($dt->format(DATE_RFC822), $dt->format('U'));
?>
changes timestamp

It is possible to fix that by:
<?php
$timestamp
= $date->getTimestamp();
$date->setTimezone($value);
$date->setTimestamp($timestamp);
?>
But WTF???
up
0
balbuf
8 years ago
It appears that what forzi at mail333 dot com said is correct.

When you reset the timezone on a DateTime object using a timezone that was instantiated with a GMT offset (e.g. <?php new DateTimeZone('-0500'); ?>) the timestamp as reported by <?php $dt->format('U'); ?> changes.

However, the value reported by <?php $dt->getTimestamp(); ?> does _not_ change. Interestingly, once <?php $dt->getTimestamp(); is called, the value from <?php $dt->format('U'); ?> starts returning the correct timestamp. This appears to be a bug.

In any case, other output values from format() seem to be accurate, and the true timestamp is always accessible via getTimestamp().
up
-2
salladin
12 years ago
I found unexpected behaviour when passing a timestamp.
timezone seems to always be GMT+0000 unless setTimezone() is set.

<?php

$MNTTZ
= new DateTimeZone('America/Denver');
$ts = 1336476757;

$dt = new DateTime("@$ts", $MNTTZ);
var_dump($dt->format('T'), $dt->format('U'));

$dt->setTimezone($MNTTZ);
var_dump($dt->format('T'), $dt->format('U'));

/** Output:
string(8) "GMT+0000"
string(10) "1336476757"
string(3) "MDT"
string(10) "1336476757"
**/

?>
To Top