PHP日期问题与夏令时

时间:2008-12-22 01:20:56

标签: php mysql date dst

我在一些PHP代码中出现了一个非常奇怪的错误。该页面管理学生的课程注册。在页面上是学生课程的表格,每行都有许多日期:注册时间,完成时间,通过评估时以及获取证书时。

表数据由PHP生成(从数据库中绘制数据),Javascript实际呈现表。 PHP的输出是JS代码,如下所示:

var e = new Enrolment();
e.contactId = 5801;
e.enrolId = 14834;
e.courseId = 3;
e.dateEnrolled = new Date(1219672800000);
e.dateCompleted = new Date(-1000);  // magic value meaning they haven't completed.
e.resultDate = new Date(1223647200000);
e.certDate = new Date(1223560800000);
e.result = 95;
e.passed = true;
enrolments[14834] = e;

在数据库中,所有日期字段都存储为DATE(不是DATETIME)字段。

错误是日期显示为休息一天。我怀疑这与服务器位于有夏令时的区域有很大关系,而这里没有(意味着服务器时间是一小时关闭)。这解释了很多,特别是如何在两个不同的时区进行数据准备和渲染。那就是:服务器告诉客户该人在8月15日的午夜完成,客户正在解释为14日晚上11点,因此显示8月14日。

但是这里有一个令人困惑的部分:它只对resultDate和certDate字段执行此操作!我已经将数据复制到我的本地服务器,并且发现生产服务器实际上正在为这两个字段发送不同的时间戳(一个关闭1小时),而dateEnrolled字段是相同的。

这是使用与数据库完全相同的代码和数据的输出:

// local server (timezone GMT+1000)
e.dateEnrolled = new Date(1219672800000);   // 26 Aug 2008 00:00 +10:00
e.dateCompleted = new Date(-1000);
e.resultDate = new Date(1223647200000);     // 11 Oct 2008 00:00 +10:00
e.certDate = new Date(1223560800000);       // 10 Oct 2008 00:00 +10:00

// production server (timezone GMT+1100)
e.dateEnrolled = new Date(1219672800000);   // 26 Aug 2008 00:00 +10:00
e.dateCompleted = new Date(-1000);
e.resultDate = new Date(1223643600000);     // 10 Oct 2008 23:00 +10:00 **
e.certDate = new Date(1223557200000);       // 09 Oct 2008 23:00 +10:00 **

我可以理解,如果这是夏令时没有考虑到的问题,但请注意dateEnrolled是如何相同的?

将MySQL日期转换为unix时间戳的PHP代码如下:

list ($year, $month, $day) = explode ('-', $mysqlDT);
$timestamp = mktime (0,0,0, $month, $day, $year);

有关如何解决此问题的任何想法?

5 个答案:

答案 0 :(得分:3)

这是因为您使用特定于语言环境的mktime。也就是说,它会将它转换为1970-1-1 GMT 00:00:00之间的秒数,并且用一个时区将其偏移1小时。

您还应该记住,javascript确实使用与浏览器相同的时区,而不是网页。

e.resultDate = new Date(year, month - 1, day);

这将确保每个时区的每个观看者的日期相同。

或者您可以使用gmmktime并在Date中使用UTC方法。

答案 1 :(得分:1)

好的,我只知道为什么它会破坏一个日期而不是另一个日期。夏令时在8月没有生效。 捂脸

答案 2 :(得分:1)

  1. 始终以GMT / UTC
  2. 存储日期/日期时间
  3. 仔细查看检索这些值的查询,有关正在调整的值的任何不同之处?
  4. 如果没有,它们都是时间戳或日期或日期时间吗?

答案 3 :(得分:1)

很可能是白天节能问题。 它仅为resultDate和certDate执行的原因是dateEnrolled是在8月,夏令时通常在9月底或10月初开始/结束。

答案 4 :(得分:0)

使用apache.conf,.htaccess或ini_set()将date.timezone ini设置设置为应用的时区。