我的一些 PHP 代码中出现了一个非常奇怪的错误。该页面正在管理类(class)中的学生注册。页面上是一张学生类(class)表,每一行都有一些日期:他们注册的时间、完成的时间、通过评估的时间以及拿到证书的时间。
表格数据由PHP生成(从DB中提取数据),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);
关于如何解决这个问题有什么想法吗?
最佳答案
那是因为您使用了特定于语言环境的 mktime。也就是说,它会将其转换为从 00:00:00 1970-1-1 GMT 开始的秒数,并且在一个时区内偏移 1 小时。
您还应该记住,javascript 确实使用与浏览器相同的时区,而不是网页。
e.resultDate = new Date(year, month - 1, day);
这将确保每个时区的每个观看者的日期都相同。
或者您可以使用 gmmktime 并在 Date 中使用 UTC 方法。
关于夏令时的 PHP 日期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/385306/