【问题标题】:PHP date() with timezone?PHP date() 与时区?
【发布时间】:2013-12-15 19:53:52
【问题描述】:

所以我检查了supported time zones in PHP 的列表,我想知道如何将它们包含在date() 函数中? 谢谢!

我不想要默认时区,每个用户都将他们的时区存储在数据库中,我使用用户的时区并使用它。如何?不过,我知道如何从数据库中获取它,而不是如何使用它。

【问题讨论】:

  • 您以哪种格式存储时区?

标签: php date timezone


【解决方案1】:

对于这样的任务,你真的应该使用 PHP 的 DateTime 类。请忽略所有建议您使用 date() 或 date_set_time_zone 的答案,这简直是糟糕和过时的。

我将使用伪代码进行演示,因此请尝试调整代码以满足您的需求。

假设变量 $tz 包含有效时区的字符串名称,变量 $timestamp 包含您希望根据时区格式化的时间戳,代码如下所示:

$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 类很强大,并且要掌握它的所有功能——您应该花一些时间在 php.net 上阅读它。要完全回答您的问题 - 是的,您可以动态调整时区参数(在从 db 读取时的每次迭代中,您可以创建一个新的 DateTimeZone() 对象)。

【讨论】:

  • @Glavić - 你是对的,我会留下答案来说明如何 not 做到这一点。但是,DateTime 胜过操纵服务器的时区,这是我想要(但未能)指出的。
  • 您的代码不起作用,因为 DateTime 构造函数的第一个参数必须是字符串 [php.net/manual/en/datetime.construct.php]
  • @Alex - 是的,这是不正确的 - 这是我评论并留下答案的内容。当我不懒惰时,我将编辑答案以包含正确的构造函数:)(在同时,您也可以编辑答案吗?)
  • 既然你已经用'now'启动了DateTime,为什么还要将时间戳设置为现在的时间戳?
  • @GeorgeDimitriadis 因为它是如何使用代码的示例。它的目的是突出你可以做什么。你说它在 this 实例中基本上没有意义是正确的,但我把它放在那里是为了让人们可以看到如何在创建的 DateTime 对象上更改时间戳。
【解决方案2】:

如果我理解正确,您需要先设置时区,例如:

date_default_timezone_set('UTC');

你可以使用日期功能:

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

【讨论】:

  • 我不想要默认时区,它将为每个用户存储在数据库中。
  • @user2917204 如果您使用的是 MySQL,请将其存储为 TIMESTAMP 数据类型。这些以 UTC 格式存储在后端,因此可以转换为您选择的任何时区。
  • 我正在使用 MySQL 并将它存储为 TIMESTAMP,我需要转换它的代码是什么?
  • @user2917204 创建一个函数来设置时区,输出格式化的日期,然后放回时区。很多例子stackoverflow.com/questions/11900126/…stackoverflow.com/questions/7824038/…。 DateTime 类还接受时区参数php.net/manual/en/class.datetime.php
【解决方案3】:

请改用DateTime class,因为它支持时区。 date() 的 DateTime 等效项是 DateTime::format

一个非常有用的 DateTime 包装器是 Carbon - 一定要看看。

您需要以 UTC 格式存储在数据库中并在应用程序级别进行转换。

【讨论】:

  • 是的,可以。您可以在应用程序逻辑中使用这些类的 setTimezone() 函数来处理它。
【解决方案4】:

answer above 让我跳过了一些障碍/陷阱,所以只需发布对我有用的更简洁的代码:

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

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

【讨论】:

    【解决方案5】:

    应该是这样的:

    date_default_timezone_set('America/New_York');
    

    【讨论】:

    • 我不想要默认时区,每个用户都有他们的时区存储在数据库中,我取用户的那个时区并使用它。如何?不过,我知道如何从数据库中获取它,而不是如何使用它。
    • 它不会为所有用户创建默认时区,只为当前脚本创建一个默认时区,该脚本可能会响应 1 个当前用户的操作。
    • 这本质上是在改变全局变量,这几乎不是正确的做法。使用 DateTime 和 DateTimeZone 使计算保持在本地,并且没有可怕的副作用。
    【解决方案6】:

    U 可以添加时区差异到 unix 时间戳。 莫斯科 (UTC+3) 示例

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

    【讨论】:

    • 不错。不幸的是,date() 最多只能接受 2 个参数,所以我不能将它与 strtotime() 结合使用(例如,date('Y-m-d', time() + -6 * 60 * 60, strtotime('-1 days')))。
    【解决方案7】:

    这在 2019 年完美运行:

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

    【讨论】:

      【解决方案8】:

      试试这个。您可以传递 unix 时间戳或日期时间字符串

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

      【讨论】:

        【解决方案9】:

        我创建了这个非常简单的函数,它就像一个魅力:

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

        【讨论】:

          【解决方案10】:

          上面没有提到。您还可以通过在构造函数中提供带有前导 @ 符号的时间戳作为字符串来创建 DateTime 对象。

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

          请参阅有关复合格式的文档: https://www.php.net/manual/en/datetime.formats.compound.php

          【讨论】:

            【解决方案11】:

            如果您使用 Team EJ 的答案,在 DateTime 的格式字符串中使用 T 将显示一个三个字母的缩写,但您可以像这样获得时区的长名称:

            $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 */
            

            【讨论】:

              【解决方案12】:
              $now = new DateTime();
              $now->format('d-m-Y H:i:s T')
              

              将输出:

              29-12-2021 12:38:15 UTC
              

              【讨论】:

                【解决方案13】:

                我已经尝试了基于 DateTime 类的答案。在他们工作的时候,我发现了一个更简单的解决方案,它可以让 DateTime 对象在创建时知道时区。

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

                这将返回印度尼西亚雅加达的当前当地时间。

                【讨论】:

                  【解决方案14】:

                  您可以在 date_default_timezone_set 函数中替换数据库值, date_default_timezone_set(SOME_PHP_VARIABLE); 但只需要处理与时区相关的确切值。

                  【讨论】:

                    猜你喜欢
                    • 2011-06-21
                    • 2012-03-01
                    • 2017-05-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多