0

我知道这可能是 ServerFault 的问题,但我无法登录。

我在云中有一个运行 Nginx + PHP5-fpm 的 Ubuntu 实例。

我已将 php.ini 中的时区设置为Asia/Singapore并验证它设置为phpinfo().

我也设置了操作系统时区dpkg-reconfigure tzdata

一段时间以来,我一直在为我的申请中设置错误的日期而烦恼。我最初认为这可能是我在 PHP 设置中所做的事情,所以在我的引导脚本中,我包括:

date_default_timezone_set('Asia/Singapore');

尝试按照这篇文章中的建议通过 PECL 安装 timezonedb: Setting default timezone does not work 尽管 timezone is valid

在网络表单上设置的用户设置日期在处理时仍会转换为“昨天”。我在 PHP 中都尝试过date()&gmdate()并得到相同的结果。

编辑

更多信息以防万一。

  1. 用户选择一个日期jQuery DatePicker

  2. 在表单提交时,我将时间戳发送回服务器供 PHP 处理和存储。在存储之前,我在 PHP 中将时间戳除以 1000。

    <?php $timestamp = (int) $_POST['birthday'] / 1000
    // this is received from a form.
    
  3. 在回显日期和时间戳后,

        <?php echo date('dS F Y', (int) $timestamp);
         // when rendering to HTML...
         // computes to 13th April 1981
    
        //JS
        new Date(data.timestamp * 1e3).toString()
        // the exact same timestamp from earlier but received from server.
        // computes to Tue Apr 14 1981 23:30:00 GMT+0730 (SGT)
    

有任何想法吗?

4

2 回答 2

0

Your clock is assumed to be in UTC/GMT, but the "humanising"/ conversion to a string adds the time zone offset. The HTTP header being in GMT will be on the original value. This is generally how Unix clocks work, it makes global traffic routing possible.

<?php

# my locale is configured for London
var_dump(time(), date('Y-m-d H:i:s'));

date_default_timezone_set('Asia/Singapore');
var_dump(time(), date('Y-m-d H:i:s')); # MySQL, locale
var_dump(time(), date('r')); # RFC 2822 
var_dump(time(), date('c')); # ISO 8601 

Your server is reporting the correct time in UTC. To fix, could you emit that header inside the PHP? This will override the first value...

header("Date: ".date('r', time()+8*60*60));

Edit

As you changed the question, more text response...

I think its necessary to confirm all the date-as-int operations are done with UTC/GMT time. If your user in in Singapore the time will be sent to the server in +8h offset. Are you transmitting as text or an int? All of the jQuery dates I have used return a string. If you unpack via strtotime(), it corrects the time offset.

The /1000 should have no computation significance, 8h = (60*60*8)s = 28800s which is >1000.

What does your client say for the timezone ~ gettimezoneoffset

It looks like one of the convert-to-int operations didn't remove the timezone offset.

于 2013-08-15T22:02:44.497 回答
0

在 Ubuntu启动板中列出并修补了一个错误。更新 PHP 后时间戳有效。该错误的摘录:

[影响]

Precise 和 Quantal 之间时区处理的回归意味着依赖于系统时区的 PHP 脚本现在改用 UTC。这会破坏任意 PHP 脚本 - 例如。仙人掌按预期停止工作。

不受影响:5.3.10-1ubuntu3.4(精确) 受影响:5.4.6-1ubuntu1(量子)不受影响:5.4.4-7(sid)

解决方法:编辑 /etc/php5/*/php.ini,取消注释“date.timezone”行并将其设置为您需要的。

[测试用例]

  1. 使用“dpkg reconfigure tzdata”设置 UTC 以外的时区。
  2. $ php -r '回显 date_default_timezone_get()."\n";'

预期结果:系统时区(例如“欧洲/伦敦”)

实际结果: PHP 警告:date_default_timezone_get():依赖系统的时区设置是不安全的。您需要使用 date.timezone 设置或 date_default_timezone_set() 函数。如果您使用了这些方法中的任何一种,但仍然收到此警告,您很可能拼错了时区标识符。我们现在选择时区“UTC”,但请设置 date.timezone 以选择您的时区。在 UTC 第 1 行的命令行代码中

(在这种情况下,UTC 是系统时区)。

于 2013-09-10T04:31:44.820 回答