I've got a very strange bug cropping up in some PHP code I've got. The page is managing student enrolments in courses. On the page is a table of the student's courses, and each row has a number of dates: when they enrolled, when they completed, when they passed the assessment and when they picked up their certificate.
The table data is generated by PHP (drawing the data from the DB), and Javascript actually renders the table. The output from PHP is JS code which looks something like this:
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;
In the database, all the date fields are stored as DATE
(not DATETIME
) fields.
The bug is that the dates are being displayed as one day off. I would suspect that this has a lot to do with the server being in an area which has daylight saving, whereas here there isn't any (meaning the server time is one hour off). This explains a lot, especially how the data preparation and rendering is being done in two different timezones. That is: the server is saying to the client that the person completed at midnight on the 15th August, and the client is interpreting that as 11pm on the 14th and therefore displaying 14th August.
But here's the confusing part: it's only doing that for the resultDate and certDate fields! I've copied the data to my local server and have found that the production server is actually sending a different timestamp (one which is off by 1 hour) just for those two fields, whereas the dateEnrolled field is the same.
Here's the output using the exact same code and data from the database:
// 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 **
I can understand if this was a problem with Daylight Saving not being accounted for, but notice how the dateEnrolled is the same?
The PHP code which converts the MySQL date to a unix timestamp is this:
list ($year, $month, $day) = explode ('-', $mysqlDT);
$timestamp = mktime (0,0,0, $month, $day, $year);
Any ideas about how to fix this?