我在一些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);
有关如何解决此问题的任何想法?
答案 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)
答案 3 :(得分:1)
很可能是白天节能问题。 它仅为resultDate和certDate执行的原因是dateEnrolled是在8月,夏令时通常在9月底或10月初开始/结束。
答案 4 :(得分:0)
使用apache.conf,.htaccess或ini_set()将date.timezone ini设置设置为应用的时区。