Сегодня мы поговорим о том, как преобразовать дату, представленную в виде числа типа double (используется в базе MS Access) в привычный многим формат даты языка PHP.
Для того чтобы перевести дату, представленную числом с плавающей точкой, в привычный формат нужно понимать, что обозначает это число. Вот цитата из документации Microsoft:
Тип данных «Дата/Время» хранится в Access в формате числа двойной точности с плавающей запятой и числом десятичных разрядов до 15. Целая часть числа двойной точности представляет собой дату. Дробная часть представляет время.
Дата может принимать значения от -657 434 (1 января 100 г. н.э.) до 2 958 465 (31 декабря 9999 г. н.э.). Нулевому значению даты соответствует 30 декабря 1899 г. Даты до 30 декабря 1899 г. хранятся в Access в виде отрицательных чисел.
Время может принимать значения от 0,0 (00:00:00) до 0,99999 (23:59:59). Числовое значение представляет собой долю дня. Можно перевести числовое значение в часы, минуты и секунды, умножив его на 24.
Почему майкрософт решил пойти таким путем я не знаю, возможно в этом есть какой то смысл. Однако много разработчиков сталкиваются с проблемой как же преобразовать такое число в привычный формат даты. Я приведу пример функции данного преобразования на языке PHP, однако логика реализации на других языках будет аналогична.
function fsMsDoubleDateToPhpTime($doubleDate, $asTime = true) { $result = strtotime('+'.((int)$doubleDate).' days', strtotime('1899-12-30 00:00:00')); $seconds = ($doubleDate - (int)$doubleDate) * 86400; //86400 количество секунд в сутках return $asTime ? $result + $seconds : date('Y-m-d H:i:s', $result + $seconds); }
PS: Для тех кто не знаком с логикой работы PHP, функция strtotime возвращает число секунд, прошедших с полуночи 1 января 1970 года. Соответственно переменная $result хранит число секунд, прошедших с данной даты, до высчитываемой даты.
Как видно ничего сложного нет. Логика проста и понятна:
1) Получаем число прошедших дней и прибавляем их к начальной дате в результате получаем нужный день.
2) Высчитываем сколько секунд прошло от начала нужной даты (это в любом случае будет менее 1 суток (менее 86400)) и прибавляем их к результату.
Зная это, легко написать обратную функцию преобразования даты PHP в формат даты MS Access. Однако в данном случае стоит учесть временную зону сервера.
function fsPhpTimeToMsDoubleDate($timeOrDate) { $zone = date_default_timezone_get(); date_default_timezone_set('UTC'); if(!is_numeric($timeOrDate)) $timeOrDate = strtotime($timeOrDate); $dateFrom = $timeOrDate - strtotime('1899-12-30 00:00:00'); $days = (int)($dateFrom / 86400); date_default_timezone_set($zone); return $days + ($timeOrDate % 86400 / 86400); }
Важно: Так же в связи с тем, что из расчетов были выброшены миллисекунды, при преобразовании дат, возможна погрешность в одну секунду. В большинстве случаев она не критична, однако если Вам нужны точные преобразования, необходимо учитывать и миллисекунды во время преобразования времени.