PHP 日期()与时区?

因此,我已经检查了 PHP 支持的时区的列表,我想知道如何将它们包括在 date()函数中? 谢谢!

我不想要一个默认的时区,每个用户有他们的时区存储在数据库中,我采取该用户的时区,并使用它。怎么做到的?我知道怎么从数据库里找,但不知道怎么用。

213604 次浏览

Use the DateTime class instead, as it supports timezones. The DateTime equivalent of date() is DateTime::format.

An extremely helpful wrapper for DateTime is Carbon - definitely give it a look.

You'll want to store in the database as UTC and convert on the application level.

If I understood correct,You need to set time zone first like:

date_default_timezone_set('UTC');

And than you can use date function:

// Prints something like: Monday 8th of August 2005 03:12:46 PM
echo date('l jS \of F Y h:i:s A');

It should like this:

date_default_timezone_set('America/New_York');

For such task, you should really be using PHP's DateTime class. Please ignore all of the answers advising you to use date() or date_set_time_zone, it's simply bad and outdated.

I'll use pseudocode to demonstrate, so try to adjust the code to suit your needs.

Assuming that variable $tz contains string name of a valid time zone and variable $timestamp contains the timestamp you wish to format according to time zone, the code would look like this:

$tz = 'Europe/London';
$timestamp = time();
$dt = new DateTime("now", new DateTimeZone($tz)); //first argument "must" be a string
$dt->setTimestamp($timestamp); //adjust the object to correct timestamp
echo $dt->format('d.m.Y, H:i:s');

DateTime class is powerful, and to grasp all of its capabilities - you should devote some of your time reading about it at php.net. To answer your question fully - yes, you can adjust the time zone parameter dynamically (on each iteration while reading from db, you can create a new DateTimeZone() object).

You can replace database value in date_default_timezone_set function, date_default_timezone_set(SOME_PHP_VARIABLE); but just needs to take care of exact values relevant to the timezones.

Try this. You can pass either unix timestamp, or datetime string

public static function convertToTimezone($timestamp, $fromTimezone, $toTimezone, $format='Y-m-d H:i:s')
{
$datetime = is_numeric($timestamp) ?
DateTime::createFromFormat ('U' , $timestamp, new DateTimeZone($fromTimezone)) :
new DateTime($timestamp, new DateTimeZone($fromTimezone));


$datetime->setTimezone(new DateTimeZone($toTimezone));


return $datetime->format($format);
}

The answer above caused me to jump through some hoops/gotchas, so just posting the cleaner code that worked for me:

$dt = new DateTime();
$dt->setTimezone(new DateTimeZone('America/New_York'));
$dt->setTimestamp(123456789);


echo $dt->format('F j, Y @ G:i');

I have created this very straightforward function, and it works like a charm:

function ts2time($timestamp,$timezone){ /* input: 1518404518,America/Los_Angeles */
$date = new DateTime(date("d F Y H:i:s",$timestamp));
$date->setTimezone(new DateTimeZone($timezone));
$rt=$date->format('M d, Y h:i:s a'); /* output: Feb 11, 2018 7:01:58 pm */
return $rt;
}

this works perfectly in 2019:

date('Y-m-d H:i:s',strtotime($date. ' '.$timezone));

U can just add, timezone difference to unix timestamp. Example for Moscow (UTC+3)

echo date('d.m.Y H:i:s', time() + 3 * 60 * 60);

Not mentioned above. You could also crate a DateTime object by providing a timestamp as string in the constructor with a leading @ sign.

$dt = new DateTime('@123456789');
$dt->setTimezone(new DateTimeZone('America/New_York'));
echo $dt->format('F j, Y - G:i');

See the documentation about compound formats: https://www.php.net/manual/en/datetime.formats.compound.php

If you use Team EJ's answer, using T in the format string for DateTime will display a three-letter abbreviation, but you can get the long name of the timezone like this:

$date = new DateTime('2/3/2022 02:11:17');
$date->setTimezone(new DateTimeZone('America/Chicago'));


echo "\n" . $date->format('Y-m-d h:i:s T');
/* Displays 2022-02-03 02:11:17 CST "; */


$t = $date->getTimezone();
echo "\nTimezone: " . $t->getName();
/* Displays Timezone: America/Chicago */
$now = new DateTime();
$now->format('d-m-Y H:i:s T')

Will output:

29-12-2021 12:38:15 UTC

I have tried the answers based on the DateTime class. While they are working, I found a much simpler solution that makes a DateTime object timezone aware at the time of creation.

$dt = new DateTime("now", new DateTimeZone('Asia/Jakarta'));
echo $dt->format("Y-m-d H:i:s");

This returns the current local time in Jakarta, Indonesia.

Based on other answers I built a one-liner, where I suppose you need current date time. It's easy to adjust if you need a different timestamp.

$dt = (new DateTime("now", new DateTimeZone('Europe/Rome')))->format('d-m-Y_His');

I had a weird problem on a hosting. The timezone was set correctly, when I checked it with the following code.

echo ini_get('date.timezone');

However, the time it returned was UTC.

The solution was using the following code since the timezone was set correctly in the PHP configuration.

date_default_timezone_set(ini_get('date.timezone'));