【问题标题】:Timezone conversion in phpphp中的时区转换
【发布时间】:2011-01-31 03:09:41
【问题描述】:

谁能推荐一种简单的方法来将日期和时间转换为 php 中的不同时区?

【问题讨论】:

    标签: php datetime timezone timestamp


    【解决方案1】:

    您可以为此使用日期时间对象或其函数别名:

    Example (abridged from PHP Manual)

    date_default_timezone_set('Europe/London');
    
    $datetime = new DateTime('2008-08-03 12:35:23');
    echo $datetime->format('Y-m-d H:i:s') . "\n";
    $la_time = new DateTimeZone('America/Los_Angeles');
    $datetime->setTimezone($la_time);
    echo $datetime->format('Y-m-d H:i:s');
    

    关于 cmets 的编辑

    但我不能使用此方法,因为当用户从不同位置登录时,我需要在不同时区显示日期

    这不是问题。当用户登录时,您确定他的时区并将其设置为您的 DateTime 对象,如图所示。我在我的一个项目中使用了类似的方法,它就像一个魅力。

    在数据库中我需要获取任何单个时区的日期,然后才能正确处理它

    您可以将时间存储为一个时区中的时间戳或日期时间。当您查询 DateTime 字段时,您可以将 DateTime 对象中的时间转换为该时区,或者 - 如果您的数据库支持 - 使用所选时区进行查询。

    【讨论】:

    • 感谢 Gordon,但我不能使用此方法,因为当用户从不同位置登录时,我需要在不同时区显示日期
    • @raki:所以在用户登录后 - 使用正确的用户选择的时区设置 date_default_timezone_set()。
    • 这也是不可能的......因为......在数据库中我需要获取任何单个时区的日期,然后才能正确处理它
    • 在数据库中,您将所有内容存储在 GMT 中。要么这样,要么就变成一团糟。
    • 所有这一切都比它需要的复杂。如果我设置默认时区,那么我为获取创建/更新时间所做的 date('Y-m-d H:i:s') 位将位于用户时区。所以我必须将它们转换为UTC。到处都有很多变化,确保我没有进行两次转换。这确实是阻抗不匹配。
    【解决方案2】:

    一个更简单的方法如下所示:

    date_default_timezone_set('Europe/London'); // your user's timezone
    $my_datetime='2013-10-23 15:47:10';
    echo date('Y-m-d H:i:s',strtotime("$my_datetime UTC"));
    

    in the PHP manual 所述,strtotime() 也接受时区,您只需将其附加到您的日期时间即可。

    我建议您将所有日期时间存储为 UTC,因为这样您就不会遇到夏令时问题。

    【讨论】:

      【解决方案3】:

      这对我有用,而且也很干净!

      function convert_to_user_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
      {
          try {
              $dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
              $dateTime->setTimezone(new DateTimeZone($userTimeZone));
              return $dateTime->format($format);
          } catch (Exception $e) {
              return '';
          }
      }
      
      function convert_to_server_date($date, $format = 'n/j/Y g:i A', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC')
      {
          try {
              $dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
              $dateTime->setTimezone(new DateTimeZone($serverTimeZone));
              return $dateTime->format($format);
          } catch (Exception $e) {
              return '';
          }
      }
      
      //example usage
      $serverDate = $userDate = '2014-09-04 22:37:22';
      echo convert_to_user_date($serverDate);
      echo convert_to_server_date($userDate);
      

      【讨论】:

        【解决方案4】:

        这些答案都不适合我(我跳过了尝试体积过大的代码)。我也认为只为一次转换更改默认时区很奇怪。

        这是我的解决方案:

        function changeTimeZone($dateString, $timeZoneSource = null, $timeZoneTarget = null)
        {
          if (empty($timeZoneSource)) {
            $timeZoneSource = date_default_timezone_get();
          }
          if (empty($timeZoneTarget)) {
            $timeZoneTarget = date_default_timezone_get();
          }
        
          $dt = new DateTime($dateString, new DateTimeZone($timeZoneSource));
          $dt->setTimezone(new DateTimeZone($timeZoneTarget));
        
          return $dt->format("Y-m-d H:i:s");
        }
        

        因此,要转换为服务器默认设置,您只需传递一个时区:

        changeTimeZone("2016-10-24 16:28", "Asia/Tokyo");
        

        要将服务器默认值转换为用户,您可以将第二个参数留空或留空:

        changeTimeZone("2016-10-24 16:28", "", "Asia/Tokyo");
        

        要在与默认值无关的 2 个时区之间切换,您需要提供 2 个时区:

        changeTimeZone("2016-10-24 16:28", "America/New_York", "Asia/Tokyo");
        

        【讨论】:

        • 不错的答案。我更喜欢 try catch 而不是 is(empty) 以避免时区字符串中的任何拼写错误。尝试{新的 DateTimeZone($timeZoneSource); } catch(Exception $e){ $timeZoneSource = date_default_timezone_get(); }
        【解决方案5】:

        UTC 到本地:

        <?php
        $datetime = date("Y-m-d H:i:s");
        $utc = new DateTime($datetime, new DateTimeZone('UTC'));
        $utc->setTimezone(new DateTimeZone('America/Sao_Paulo'));
        echo $utc->format('Y-m-d H:i:s');
        
        ?>
        

        【讨论】:

          【解决方案6】:

          DateTime::setTimezone -- date_timezone_set — Sets the time zone for the DateTime object

          面向对象的风格

          <?php
          $date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
          echo $date->format('Y-m-d H:i:sP') . "\n";
          
          $date->setTimezone(new DateTimeZone('Pacific/Chatham'));
          echo $date->format('Y-m-d H:i:sP') . "\n";
          ?>
          

          程序风格

          <?php
          $date = date_create('2000-01-01', timezone_open('Pacific/Nauru'));
          echo date_format($date, 'Y-m-d H:i:sP') . "\n";
          
          date_timezone_set($date, timezone_open('Pacific/Chatham'));
          echo date_format($date, 'Y-m-d H:i:sP') . "\n";
          ?>
          

          上面的例子会输出:

          2000-01-01 00:00:00+12:00
          2000-01-01 01:45:00+13:45
          

          【讨论】:

            【解决方案7】:
            // Convert date from one zone to another..
            /* 
            $zone_from='Asia/Kolkata';
            
            $zone_to='America/Phoenix';
            
            date_default_timezone_set($zone_from);
            
            $convert_date="2016-02-26 10:35:00";
            
            echo $finalDate=zone_conversion_date($convert_date, $zone_from, $zone_to);
            
            */
            function zone_conversion_date($time, $cur_zone, $req_zone)
            {   
                date_default_timezone_set("GMT");
                $gmt = date("Y-m-d H:i:s");
                
                date_default_timezone_set($cur_zone);
                $local = date("Y-m-d H:i:s");
              
                date_default_timezone_set($req_zone);
                $required = date("Y-m-d H:i:s");
                
                /* return $required; */
                $diff1 = (strtotime($gmt) - strtotime($local));
                $diff2 = (strtotime($required) - strtotime($gmt));
            
                $date = new DateTime($time);
                $date->modify("+$diff1 seconds");
                $date->modify("+$diff2 seconds");
            
                return $timestamp = $date->format("Y-m-d H:i:s");
            }
            

            【讨论】:

              【解决方案8】:
              <?php
              $time='6:02';
              $dt = new DateTime($time, new DateTimeZone('America/New_York'));
              //echo $dt->format('Y-m-d H:i:s') . PHP_EOL;
              $dt->setTimezone(new DateTimeZone('Asia/Kolkata'));
              echo $dt->format('H:i') . PHP_EOL; 
              ?>
              

              【讨论】:

              • 这正是我想要的...谢谢兄弟
              【解决方案9】:

              我总是很难记住setTimezone() 方法的工作原理。是否根据时区调整日期时间?或者它是否需要一个给定的日期时间,放弃它的时区,并使用你传递的那个?总而言之,我宁愿有一种更直观的方式来处理时区。

              我喜欢这个:

              (new AdjustedAccordingToTimeZone(
                  new DateTimeFromISO8601String('2018-04-25 15:08:01+03:00'),
                  new Novosibirsk()
              ))
                  ->value();
              

              它以新西伯利亚时区的 ISO8601 格式输出日期时间。

              此方法使用蛋白酥皮库,查看quick start 了解更多示例。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-12-20
                • 1970-01-01
                • 1970-01-01
                • 2011-12-15
                • 1970-01-01
                • 2011-07-27
                相关资源
                最近更新 更多