【问题标题】:Convert UTC dates to local time in PHP在 PHP 中将 UTC 日期转换为本地时间
【发布时间】:2011-04-17 01:32:24
【问题描述】:

我将 UTC 日期存储到数据库中:

$utc = gmdate("M d Y h:i:s A");

然后我想将保存的 UTC 日期转换为客户端的本地时间。

我该怎么做?

谢谢

【问题讨论】:

    标签: php datetime timezone


    【解决方案1】:

    date()localtime() 都使用服务器的本地时区,除非被覆盖;您可以覆盖date_default_timezone_set() 使用的时区。

    http://www.php.net/manual/en/function.date-default-timezone-set.php

    http://us3.php.net/manual/en/function.date.php

    http://php.net/manual/en/function.localtime.php

    【讨论】:

    • 但是如何获取当前的 UTC 时间戳?
    • 为什么需要当前的UTC时间戳来转换保存的UTC时间戳?
    • 但如果你这样做了,time() 总是返回 UTC:us2.php.net/manual/en/function.time.php
    • date()、localtime() 等不回答问题,因为问题的关键词是“UTC”,而这里没有。问题确实很简单:如何将 UTC 时间转换为本地时间。(任何时间,而不是当前时间。)请参阅我的回复。
    【解决方案2】:

    PHP 的strtotime 函数将解释时区代码,例如UTC。如果您从数据库/客户端获取没有时区代码的日期,但知道它是 UTC,那么您可以附加它。

    假设您获得带有时间戳代码的日期(如“Fri Mar 23 2012 22:23:03 GMT-0700 (PDT)”,这是 Javascript 代码 ""+(new Date()) 给出的):

    $time = strtotime($dateWithTimeZone);
    $dateInLocal = date("Y-m-d H:i:s", $time);
    

    或者如果你不这样做,这很可能来自 MySQL,那么:

    $time = strtotime($dateInUTC.' UTC');
    $dateInLocal = date("Y-m-d H:i:s", $time);
    

    【讨论】:

    • 第二个代码 sn-p 是我需要将 sqlite 的 datetime() 函数的输出从 UTC 转换为本地时间。
    • 谢谢你,你节省了我的时间。
    • 感谢您提供的“UTC”尾字符串。
    【解决方案3】:

    首先,获取 UTC 日期——您已经完成了,所以这一步实际上只是一个数据库调用:

    $timezone = "UTC";
    date_default_timezone_set($timezone);
    
    $utc = gmdate("M d Y h:i:s A");
    print "UTC: " . date('r', strtotime($utc)) . "\n";
    

    接下来,在 PHP 中设置您的本地时区:

    $timezone = "America/Guayaquil";
    date_default_timezone_set($timezone);
    

    现在以秒为单位获取偏移量:

    $offset = date('Z', strtotime($utc));
    print "offset: $offset \n";
    

    最后,将偏移量添加到原始日期时间的整数时间戳中:

    print "LOCAL: " . date('r', strtotime($utc) + $offset) . "\n";
    

    【讨论】:

    • 或者,更简洁:$local = date($format, strtotime("$utc $offset seconds"));
    • 如果您有时区,则不需要日期算术
    • 谢谢。它就像魅力一样。我使用您的代码 convert_utc_to_gmt 和 convert_gmt_to_utc 创建了 2 个函数。再次感谢:)
    【解决方案4】:

    如果您只想在不同时区显示相同的时间戳,则不需要日期算术:

    $format = "M d, Y h:ia";
    $timestamp = gmdate($format);
    
    date_default_timezone_set("UTC");
    $utc_datetime = date($format, $timestamp);
    
    date_default_timezone_set("America/Guayaquil");
    $local_datetime = date($format, $timestamp);
    

    【讨论】:

      【解决方案5】:

      如果通过客户端,你的意思是浏览器,那么你首先需要将时区名称从浏览器发送到PHP,然后按照如下所述进行转换。

      回答

      将 UTC 日期时间转换为 America/Denver

      // create a $dt object with the UTC timezone
      $dt = new DateTime('2016-12-12 12:12:12', new DateTimeZone('UTC'));
      
      // change the timezone of the object without changing its time
      $dt->setTimezone(new DateTimeZone('America/Denver'));
      
      // format the datetime
      $dt->format('Y-m-d H:i:s T');
      

      这适用于 2032 年之后的日期、夏令时和闰秒,并且不依赖于主机区域设置或时区。

      它使用 timezonedb 进行计算,这个 db 随着时区规则的变化而随着时间的推移而变化,并且必须保持最新。 (见底部注释)

      要将 UTC 日期转换为服务器(本地)时间,您可以使用不带第二个参数的 DateTime,默认为服务器时区。

      // create a $dt object with the UTC timezone
      $dt = new DateTime('2016-12-12 12:12:12', new DateTimeZone('UTC'));
      
      // get the local timezone
      $loc = (new DateTime)->getTimezone();
      
      // change the timezone of the object without changing its time
      $dt->setTimezone($loc);
      
      // format the datetime
      $dt->format('Y-m-d H:i:s T');
      

      回答 2

      我推荐使用DateTimeImmutable,因为它不会改变变量(不会在幕后改变它们),否则它就像DateTime一样工作。

      // create a $dt object with the UTC timezone
      $dt_utc = new DateTimeImmutable('2016-12-12 12:12:12', new DateTimeZone('UTC'));
      
      // Create a new instance with the new timezone
      $dt_denver = $dt_utc->setTimezone(new DateTimeZone('America/Denver'));
      
      // format the datetime
      $dt_denver->format('Y-m-d H:i:s T');
      

      不变性允许您在不更改$dt 的值的情况下多次使用链接

      $dt = new DateTimeImmutable('2016-12-12 12:12:12', new DateTimeZone('UTC'));
      
      // Format $dt in Denver timezone
      echo $dt->setTimezone(new DateTimeZone('America/Denver'))->format('Y-m-d H:i:s T');
      
      // Format $dt in Madrid timezone
      echo $dt->setTimezone(new DateTimeZone('Europe/Madrid'))->format('Y-m-d H:i:s T');
      
      // Format $dt in Local server timezone
      echo $dt->setTimezone((new DateTime())->getTimezone())->format('Y-m-d H:i:s T');
      

      注意事项

      time() 返回unix timestamp,这是一个数字,它没有时区。

      date('Y-m-d H:i:s T') 返回当前语言环境时区的日期。

      gmdate('Y-m-d H:i:s T') 以 UTC 格式返回日期

      date_default_timezone_set() 更改当前区域设置时区

      改变时区的时间

      // create a $dt object with the America/Denver timezone
      $dt = new DateTime('2016-12-12 12:12:12', new DateTimeZone('America/Denver'));
      
      // change the timezone of the object without changing it's time
      $dt->setTimezone(new DateTimeZone('UTC'));
      
      // format the datetime
      $dt->format('Y-m-d H:i:s T');
      

      在这里您可以看到所有可用的时区

      https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

      这里是所有格式选项

      http://php.net/manual/en/function.date.php

      更新 PHP 时区数据库(在 linux 中)

      sudo pecl install timezonedb
      

      由于夏令时,某些日期在某些时区重复,例如,在美国,2011 年 3 月 13 日凌晨 2:15 从未出现过,而 2011 年 11 月 6 日凌晨 1:15 出现了两次。这些日期时间无法准确确定。

      【讨论】:

      • 这实际上回答了问题,而不是提供“如何获取当地时间”。
      • 这是正确的答案,因为正确更改 $dt 对象的 TimeZone 会计算对象时的夏令时偏移量(而不是执行代码时的本地当前时间)
      • 这正是我想要的。谢谢。
      【解决方案6】:

      我将日期以 UTC 格式存储在数据库中,然后我将它们显示给当地时区的最终用户

      // retrieve
      $d = (new \DateTime($val . ' UTC'))->format('U');
      return date("Y-m-d H:i:s", $d);
      

      【讨论】:

      • 这与上面给出的答案有何不同?
      • 事实上,如果你想重写和扩展你对较新的 PHP DateTime 类的使用,你的答案可能是实现预期结果的一种新的独特方式。
      【解决方案7】:

      这是将提问者的 UTC 时间转换为本地时间的直接方法。这是存储在数据库等中的时间,即任何时间。您只需要找到 UTC 时间和您感兴趣的本地时间之间的时差,然后调整存储的 UTC 时间,并添加差异。

      $df = "G:i:s";  // Use a simple time format to find the difference
      $ts1 = strtotime(date($df));   // Timestamp of current local time
      $ts2 = strtotime(gmdate($df)); // Timestamp of current UTC time
      $ts3 = $ts1-$ts2;              // Their difference
      

      然后您可以将此差异添加到存储的 UTC 时间。 (在我这里,雅典,时差正好是 5:00:00)

      例子:

      $time = time() // Or any other timestamp
      $time += $ts3  // Add the difference
      $dateInLocal = date("Y-m-d H:i:s", $time);
      

      【讨论】:

      • 如何添加?
      • 这很明显......无论如何我举了一个如何添加它的例子。
      • 不适合 php 新手!谢谢。当然,这可能会派上用场。添加了赞成票..
      • 谢谢。享受您的 PHP 冒险之旅!这是一门很棒的语言。
      【解决方案8】:

      给定本地时区,例如“美国/丹佛”,您可以使用 DateTime 类将 UTC 时间戳转换为本地日期:

      $timestamp = *********;
      $date = new DateTime("@" . $timestamp);
      $date->setTimezone(new DateTimeZone('America/Denver'));
      echo $date->format('Y-m-d H:i:s');
      

      【讨论】:

        【解决方案9】:
        $UTC_Time   = "2018-07-06 06:06:16";
        echo "UTC Time ".$UTC_Time;
        $Indian_Time = TimeConverion($UTC_Time);
        echo "<br> Indian_Time ".$Indian_Time;
        
        function TimeConverion($UTC_Time) {
          date_default_timezone_set('Europe/London');
          $sTime = date("Y-m-d h:i:sa");
          $ts3 = strtotime(date("G:i:s"))-strtotime($sTime); 
          $utc = explode(" ",$UTC_Time);
          $time = strtotime($utc[1]);
          date_default_timezone_set("Asia/Calcutta");
          $time += $ts3;  // Add the difference
          return $utc[0]." ".date("H:i:s", $time);
        }
        

        【讨论】:

          【解决方案10】:

          这里分享脚本,将UTC时间戳转换为印度时间戳:-

              // create a $utc object with the UTC timezone
              $IST = new DateTime('2016-12-12 12:12:12', new DateTimeZone('UTC'));
          
              // change the timezone of the object without changing it's time
              $IST->setTimezone(new DateTimeZone('Asia/Kolkata'));
          
              // format the datetime
             echo $IST->format('Y-m-d H:i:s T');
          

          【讨论】:

            【解决方案11】:

            UTC 中的日期转换为 本地时间 或一行中的另一个时区。

            UTC 时间:“2021-09-13 16:30:16”

            输出时区:'America/Havana'

            (new DateTime('2021-09-13 16:30:16', new DateTimeZone('UTC')))
            ->setTimezone(new DateTimeZone('America/Havana'))
            ->format('Y-m-d H:i:s')
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-10-07
              • 1970-01-01
              • 1970-01-01
              • 2019-06-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多