У меня возникла очень странная ошибка в некотором коде 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).
Ошибка в том, что даты отображаются как один выходной. Я подозреваю, что это во многом связано с тем, что сервер находится в зоне с переходом на летнее время, тогда как здесь его нет (это означает, что время на сервере отключено на один час). Это многое объясняет, особенно то, как подготовка и рендеринг данных выполняются в двух разных часовых поясах. То есть: сервер сообщает клиенту, что человек завершил работу в полночь 15 августа, а клиент интерпретирует это как 23:00 14-го и, следовательно, отображает 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 совпадает?
Код PHP, который преобразует дату MySQL в метку времени unix, следующий:
list ($year, $month, $day) = explode ('-', $mysqlDT);
$timestamp = mktime (0,0,0, $month, $day, $year);
Есть идеи, как это исправить?






Хорошо, я только что понял, почему одно свидание портится, а другое нет. В августе переход на летнее время не действовал. фейспалм
Скорее всего, это проблема экономии дневного света. Причина, по которой он делает это только для resultDate и certDate, заключается в том, что dateEnrolled находится в августе, переход на летнее время обычно начинается / заканчивается в конце сентября или начале октября.
Установите ini-параметр date.timezone на часовой пояс вашего приложения, используя apache.conf, .htaccess или ini_set ().
Это потому, что вы используете mktime, зависящий от локали. То есть он преобразует его в количество секунд с 00:00:00 1970-1-1 GMT, и это смещено на 1 час с одним часовым поясом.
Вы также должны помнить, что javascript использует тот же часовой пояс, что и браузер, а не веб-страницу.
e.resultDate = new Date(year, month - 1, day);
Это обеспечит одинаковую дату для всех зрителей во всех часовых поясах.
Или вы можете использовать gmmktime и использовать методы UTC в Date.