如何通过 PHP 从 UTC 轻松转换日期?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/952975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I easily convert dates from UTC via PHP?
提问by Chad Johnson
I am storing dates in a MySQL database in datetime fields in UTC. I'm using PHP, and I've called date_timezone_set('UTC') so that all calls to date() (without timestamp) return the date in UTC.
我将日期存储在 MySQL 数据库中的 UTC 日期时间字段中。我正在使用 PHP,并且我调用了 date_timezone_set('UTC') 以便所有对 date()(不带时间戳)的调用都返回 UTC 中的日期。
I then have it so a given web site can select its timezone. Now I want dates to display in the site's timezone. So, if I have a date stored as '2009-04-01 15:36:13', it should display for a user in the PDT timezone (-7 hours) as '2009-04-01 08:36:13'.
然后我拥有它,以便给定的网站可以选择其时区。现在我希望日期显示在站点的时区中。因此,如果我将日期存储为“2009-04-01 15:36:13”,它应该为 PDT 时区(-7 小时)中的用户显示为“2009-04-01 08:36:13” .
What is the easiest (least code) method for doing this via PHP? So far all I've thought of is
通过 PHP 执行此操作的最简单(最少代码)方法是什么?到目前为止我想到的只有
date('Y-m-d H:i:s', strtotime($Site->getUTCOffset() . ' hours', strtotime(date($utcDate))));
Is there a shorter way?
有没有更短的方法?
采纳答案by PCheese
Here's what we did with our servers. We set everything to use UTC, and we display in the user's time zone by converting from UTC on the fly. The code at the bottom of this post is an example of how to get this to work; you should confirm that it works in all cases with your setup (i.e. daylight savings, etc).
这是我们对服务器所做的。我们将所有内容都设置为使用 UTC,并通过即时从 UTC 转换来显示在用户的时区中。这篇文章底部的代码是一个如何让它工作的例子;您应该确认它在所有情况下都适用于您的设置(即夏令时等)。
Configuring CentOS
配置 CentOS
- Edit
/etc/sysconfig/clockand setZONEtoUTC ln -sf /usr/share/zoneinfo/UTC /etc/localtime
- 编辑
/etc/sysconfig/clock并设置ZONE为UTC ln -sf /usr/share/zoneinfo/UTC /etc/localtime
Configuring MySQL
配置 MySQL
Import timezones into MySQL if necessary:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysqlEdit my.cnf and add the following within the [mysqld] section:
default-time-zone = 'UTC'
如有必要,将时区导入 MySQL:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql编辑 my.cnf 并在 [mysqld] 部分中添加以下内容:
default-time-zone = 'UTC'
PHP Code
PHP代码
<?php
/*
Example usage:
$unixtime = TimeUtil::dateTimeToTimestamp('2009-04-01 15:36:13');
echo TimeUtil::UTCToPST("M d, Y - H:i:s", $unixtime);
*/
// You should move this to your regular init method
date_default_timezone_set('UTC'); // make this match the server timezone
class TimeUtil {
public static function timestampToDateTime($timestamp) {
return gmdate('Y-m-d H:i:s', $timestamp);
}
public static function dateTimeToTimestamp($dateTime) {
// dateTimeToTimestamp expects MySQL format
// If it gets a fully numeric value, we'll assume it's a timestamp
// You can comment out this if block if you don't want this behavior
if(is_numeric($dateTime)) {
// You should probably log an error here
return $dateTime;
}
$date = new DateTime($dateTime);
$ret = $date->format('U');
return ($ret < 0 ? 0 : $ret);
}
public static function UTCToPST($format, $time) {
$dst = intval(date("I", $time));
$tzOffset = intval(date('Z', time()));
return date($format, $time + $tzOffset - 28800 + $dst * 3600);
}
}
回答by Jordan S. Jones
Why not use the built in DateTime/TimeZonefunctionality?
为什么不使用内置的DateTime/TimeZone功能?
<?php
$mysqlDate = '2009-04-01 15:36:13';
$dateTime = new DateTime ($mysqlDate);
$dateTime->setTimezone(new DateTimeZone('America/Los_Angeles'));
?>
DateTime Class: http://us3.php.net/manual/en/class.datetime.phpDateTimeZone Class: http://us3.php.net/manual/en/class.datetimezone.php
日期时间类:http: //us3.php.net/manual/en/class.datetime.phpDateTimeZone 类:http: //us3.php.net/manual/en/class.datetimezone.php
PHP's supported Timezones: http://php.net/manual/en/timezones.php
PHP 支持的时区:http: //php.net/manual/en/timezones.php
回答by Richard Williams
What you're doing is the right way of doing things. I'd recommend sticking with working in only UTC and just converting at the last minute for the display.
你正在做的是正确的做事方式。我建议坚持只使用 UTC 并在最后一分钟进行显示转换。
Here's a quick function I put together for time zone conversion using the DateTime class that comes with PHP. It's a bit more code than you have but I think it's easier and a better way to structure things...
这是我使用 PHP 附带的 DateTime 类组合在一起进行时区转换的快速函数。它比你拥有的代码多一点,但我认为它更容易并且是一种更好的结构方式......
function convert_time_zone($date_time, $from_tz, $to_tz)
{
$time_object = new DateTime($date_time, new DateTimeZone($from_tz));
$time_object->setTimezone(new DateTimeZone($to_tz));
return $time_object->format('Y-m-d H:i:s');
}
http://richardwillia.ms/blog/2011/04/time-zone-conversion-using-datetime-class/
http://richardwillia.ms/blog/2011/04/time-zone-conversion-using-datetime-class/
Hope that helps.
希望有帮助。
回答by razzed
Having spent a lot of time dealing with this issue, do not attempt to implement time zone translation yourself.It's a royal PIA, fraught with difficulties, and it's very hard to get it right internationally.
花了很多时间处理这个问题后,不要尝试自己实现时区转换。这是一个皇家PIA,充满困难,在国际上很难做到正确。
That said, the best option is to convert your datetimes in MySQL to timestamps, and just use the database to convert times:
也就是说,最好的选择是将MySQL 中的datetimes转换为timestamps,然后使用数据库来转换时间:
mysql> set time_zone='America/New_York';
timestamps in MySQL are smaller, and support time zone translation. datetimedoes not.
MySQL 中的timestamp较小,并且支持时区转换。日期时间没有。
Before you display the site information on the page, just invoke the above command, and it will display correctly without any PHP code changes at all.
在页面上显示站点信息之前,只需调用上面的命令,它就会正确显示,无需任何 PHP 代码更改。
Caveats:
注意事项:
- If you use NOW()or any local time functions, you should update them to UTC_TIMESTAMP()
- timestamps have interesting update and insert properties which you may want to turn off.
- 如果您使用NOW()或任何本地时间函数,您应该将它们更新为UTC_TIMESTAMP()
- timestamps 具有有趣的更新和插入属性,您可能希望将其关闭。
To turn off timestampproperties:
要关闭时间戳属性:
ALTER TABLE mytable CHANGE COLUMN Created Created timestamp NULL DEFAULT 0;
The DEFAULT 0disables the column being updated when you update other columns.
该默认值0禁止在更新其他列的列被更新。
回答by WwebMaster
<?php
function getNoteDateTimeZone($date = null, $from_dtz = 'US/Central', $to_dtz = null) {
//$from_zt = 'US/Central'; // Time Zone = -06:00
if (is_null($date) == FALSE && is_null($from_dtz) == FALSE && is_null($to_dtz) == FALSE) {
// set TimeZone from
$time_object = new DateTime($date, new DateTimeZone($from_dtz));
$time_now_object = new DateTime("now", new DateTimeZone($from_dtz));
// Change TimeZone
$time_object->setTimezone(new DateTimeZone(trim($to_dtz)));
$time_now_object->setTimezone(new DateTimeZone(trim($to_dtz)));
// Is day = day in $time_now_object, $time_object..?
if ($time_now_object->format('d') == $time_object->format('d')) {
return $time_object->format('H:i:s');
} else {
return $time_object->format('Y-m-d H:i:s');
}
} else {
return '';
}
}
?>
Use sample:
使用示例:
<?php
$date = '2008-06-02 20:32:46';
$dtz = 'America/Argentina/Buenos_Aires';
echo getNoteDateTimeZone($date, 'US/Central', $dtz); // Out = 2008-06-02 23:32:46
?>
回答by saada
This worked for me and it's pretty clean
这对我有用,而且很干净
function convert_to_user_date($date, $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
$dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
}
function convert_to_server_date($date, $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
$dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
$dateTime->setTimezone(new DateTimeZone($serverTimeZone));
return $dateTime->format($format);
}
回答by Naresh Chennuri
Convert user timezone to server timezone and vice versa, with a single function:
使用单个函数将用户时区转换为服务器时区,反之亦然:
function convertTimeZone($date, $convertTo = 'userTimeZone', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
if($convertTo == 'userTimeZone'){
$dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
} else if($convertTo == 'serverTimeZone'){
$dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
$dateTime->setTimezone(new DateTimeZone($serverTimeZone));
return $dateTime->format($format);
}
}
echo convertTimeZone(date('Ydm h:i:s'),'serverTimeZone');
回答by e2p
ADDTIME($utcDate,$Site->getUTCOffset())

