PHP DateTime Timezones - Constructor vs Setter met

2019-02-22 16:46发布

When using the PHP DateTime class and try to set a DateTimeZone I get different results depending on how I set it: using the DateTime::__construct or using the DateTime::setTimezone method.

here is an example:

$date = '2014-08-01'

$dateTimeOne = new DateTime($date, new DateTimeZone('America/Los_Angeles'));
echo $dateTimeOne->format('Y-m-d\TH:i:sP'); 
// 2014-08-01T00:00:00-07:00

$dateTimeTwo = new DateTime($date);
$dateTimeTwo->setTimezone(new DateTimeZone('America/Los_Angeles'));
echo $dateTimeTwo->format('Y-m-d\TH:i:sP'); 
// 2014-07-31T17:00:00-07:00

See also http://3v4l.org/LrZfM

I have looked around and have not found an adequate explanation that addresses these particular behavior other than the following comment in the php docs: datetime.settimezone and the book php|architect's Guide to Date and Time Programming: Dealing with Timezones - DateTimeZone.

The comment states that the DateTime::setTimezone method will change the timezone for a particular point in time (a time stamp) but the Unix time stamp remains unchanged.

In the other hand the DateTime::__construct DateTimeZone parameter is used to "overwrite the current default timezone with a user defined one" Chapter 3: Dealing with Timezones - DateTimeZone.

Other than these there isn't much on the subject (that I was able to find).

This is what I would like to know:

  • Further explanation of these two ways to set the timezones
  • When should I use the DateTime::__construct to set the timezone
  • When should I use the DateTime::setTimezone to set the timezone
  • A clear example of using one vs the other or how to using them in conjunction

1条回答
Anthone
2楼-- · 2019-02-22 16:48

This is normal behaviour.

When you don't specify the timezone in the constructor, the default timezone is used, i.e what was set using date_default_timezone_set().

When you then call:

$dateTimeTwo->setTimezone(new DateTimeZone('America/Los_Angeles'));

It moves the date set in the default timezone into the new timezone.


1) (constructor) set date in 'America/Los_Angeles'
2) (setter) set date in default timezone, move date to 'America/Los_Angeles'


Your default timezone was probably UTC or something close. You told the computer to set 2014-08-01 at UTC. You then asked to switch to the 'America/Los_Angeles' timezone which is 7 hours earlier thus by changing the date to 2014-07-31 at 17:00.

查看更多
登录 后发表回答