代码之家  ›  专栏  ›  技术社区  ›  Eran Galperin

用PHP处理时区

  •  19
  • Eran Galperin  · 技术社区  · 16 年前

    一些关于PHP时区的问题已经在我的脑海中萦绕了一段时间,我想知道是否有比我目前正在做的更好的方法来处理它。

    当处理一个必须支持多个时区(对于用户)的站点时,为了规范化存储时间戳的时区设置,我总是使用 CURRENT_TIMESTAMP 属性或 NOW()

    这样我就不必考虑输入时间戳时为PHP设置了什么时区(因为PHP时间函数是时区感知的)。对于每个用户,根据其偏好,我在引导文件中的某个位置使用以下命令设置时区:

    date_default_timezone_set($timezone);
    

    当我想用php格式化日期时 date() 函数,由于MySQL当前将时间戳存储为 Y-m-d H:i:s . 不考虑时区,您只需运行:

    $date = date($format,strtotime($dbTimestamp));
    

    问题是 日期() strtotime() 都是时区感知函数,这意味着如果PHP时区的设置与服务器时区不同,则时区偏移量将应用两次(而不是我们希望的一次)。

    为了解决这个问题,我通常使用 UNIX_TIMESTAMP() 不知道时区的函数,允许我应用 直接在它上面-因此只应用一次时区偏移。

    * 获取所有列(有时会大大简化查询)。而且,有时它根本不是一个使用 (尤其是在与没有太多查询组合抽象的开源包一起使用时)。

    另一个问题是当存储时间戳时 当前时间戳 不是一个选项-存储PHP生成的时间戳将使用时区偏移量来存储它,我希望避免这种情况。

    我可能遗漏了一些非常基本的东西,但是到目前为止,我还没有想出一个通用的解决方案来处理这些问题,所以我不得不逐个处理它们。你的想法很受欢迎

    4 回复  |  直到 13 年前
        1
  •  12
  •   Misha Moroshko Amr Mostafa    12 年前

    几个月前我们花了一些时间思考这个问题。我们最终采用的技术非常简单:

    1. 以GMT/UTC格式存储日期(例如0时区偏移量)。
    2. 从数据库检索后应用当前用户时区偏移量(例如,在显示给用户之前或在您需要的任何时候)。

        2
  •  7
  •   John Conde    12 年前

    由于PHP5.2,您可以使用DateTime,这使得使用时区变得容易:

    $datetime = new DateTime($dbTimestamp, $timezone);
    echo $datetime->format('Y-m-d H:i:s');
    $datetime->setTimezone(new DateTimeZone('Pacific/Nauru'));
    echo $datetime->format('Y-m-d H:i:s');
    
        3
  •  1
  •   user42092 user42092    16 年前

    您可以尝试使用 SET time_zone

    不幸的是,对于strotime/UNIX时间戳,我没有任何答案,事实上,Postgres也有同样的问题。

        4
  •  0
  •   Lucian D.    11 年前

    我没有在网上找到任何优雅的解决方案,所以我创建了一个 Timezone HTML select generator 剧本,这是 output

    <select name="timezone" id="timezone">
        <optgroup label="UTC -11:00">
            <option value="Pacific/Midway">UTC -11:00 Midway</option>
            <option value="Pacific/Niue">UTC -11:00 Niue</option>
            <option value="Pacific/Pago_Pago">UTC -11:00 Pago_Pago</option>
        </optgroup>
        <optgroup label="UTC -10:00">
            <option value="America/Adak">UTC -10:00 Adak</option>
            <option value="Pacific/Honolulu">UTC -10:00 Honolulu</option>
            <option value="Pacific/Johnston">UTC -10:00 Johnston</option>
            <option value="Pacific/Rarotonga">UTC -10:00 Rarotonga</option>
            <option value="Pacific/Tahiti">UTC -10:00 Tahiti</option>
        </optgroup>
        . . . . . . . . . . . . . .
        <optgroup label="UTC +13:00">
            <option value="Pacific/Apia">UTC +13:00 Apia</option>
            <option value="Pacific/Enderbury">UTC +13:00 Enderbury</option>
            <option value="Pacific/Fakaofo">UTC +13:00 Fakaofo</option>
            <option value="Pacific/Tongatapu">UTC +13:00 Tongatapu</option>
        </optgroup>
        <optgroup label="UTC +14:00">
            <option value="Pacific/Kiritimati">UTC +14:00 Kiritimati</option>
        </optgroup>
    </select>
    

    享受吧!