如何通过PHP轻松转换UTC的日期?

时间:2009-06-04 20:42:19

标签: php timezone

我在UTC中的日期时间字段中将日期存储在MySQL数据库中。我正在使用PHP,并且我调用了date_timezone_set('UTC'),以便所有对date()的调用(没有时间戳)都以UTC格式返回日期。

然后我有了它,所以给定的网站可以选择它的时区。现在我希望日期显示在网站的时区。因此,如果我将日期存储为“2009-04-01 15:36:13”,则应在PDT时区(-7小时)内为用户显示为“2009-04-01 08:36:13”

通过PHP执行此操作的最简单(最少代码)方法是什么?到目前为止,我所想到的只是

date('Y-m-d H:i:s', strtotime($Site->getUTCOffset() . ' hours', strtotime(date($utcDate))));

有更短的路吗?

8 个答案:

答案 0 :(得分:18)

为什么不使用内置的DateTime/TimeZone功能?

<?php

$mysqlDate = '2009-04-01 15:36:13';

$dateTime = new DateTime ($mysqlDate);
$dateTime->setTimezone(new DateTimeZone('America/Los_Angeles'));

?>

DateTime类:http://us3.php.net/manual/en/class.datetime.php DateTimeZone类:http://us3.php.net/manual/en/class.datetimezone.php

PHP支持的时区:http://php.net/manual/en/timezones.php

答案 1 :(得分:8)

你正在做的是正确的做事方式。我建议坚持只使用UTC工作,只需在最后一刻进行转换即可显示。

这是我使用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/

希望有所帮助。

答案 2 :(得分:7)

以下是我们对服务器所做的工作。我们将所有内容设置为使用UTC,并通过动态转换显示在用户的时区中。这篇文章底部的代码是如何使其工作的一个例子;您应该确认它适用于您的设置(即夏令时等)的所有情况。

配置CentOS

  1. 修改/etc/sysconfig/clock并将ZONE设为UTC
  2. ln -sf /usr/share/zoneinfo/UTC /etc/localtime
  3. 配置MySQL

    1. 如有必要,将时区导入MySQL:

      mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

    2. 编辑my.cnf并在[mysqld]部分中添加以下内容:

      default-time-zone = 'UTC'

    3. 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);
          }
      
      }
      

答案 3 :(得分:1)

花了很多时间处理这个问题,不要试图自己实施时区翻译。这是一个充满困难的皇家PIA,而且很难在国际上做到这一点。

也就是说,最好的选择是将MySQL中的 datetime 转换为 timestamp ,并使用数据库转换时间:

 mysql> set time_zone='America/New_York';
MySQL中的

timestamp 更小,并支持时区转换。 datetime 没有。

在页面上显示站点信息之前,只需调用上面的命令,它就会正确显示而不需要任何PHP代码更改。

注意事项:

  1. 如果您使用 NOW()或任何本地时间函数,则应将其更新为 UTC_TIMESTAMP()
  2. 时间戳具有您可能想要关闭的有趣更新和插入属性。
  3. 关闭时间戳属性:

    ALTER TABLE mytable CHANGE COLUMN Created Created timestamp NULL DEFAULT 0;
    

    DEFAULT 0 会在您更新其他列时禁用正在更新的列。

答案 4 :(得分:1)

<?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 '';
        }
    }
?>

使用样本:

<?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
?>

答案 5 :(得分:0)

ADDTIME($utcDate,$Site->getUTCOffset())

答案 6 :(得分:0)

这对我有用,而且非常干净

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);
}

答案 7 :(得分:0)

使用单个函数将用户时区转换为服务器时区,反之亦然:

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');