Формат времени 1900

Опубликовано в QLua

Кроме привычного для lua формата времени и даты существует и другой вариант задания времени. Он применяется, например, в Excel, LibreOffice или в некоторых программах технического анализа.

 

Excel хранит даты в виде чисел от 1 до 2 958 465 (в версиях ранее Excel 97 - до 65 380). Числа эти - "номер по порядку" данного дня, отсчитанный от 1 января 1900 года (точнее от 31 декабря 1899 года). Порядковое число 1 соответствует 1 января 1900 года, число 2 — это 2 января 1900 года и так далее. Такая система хранения позволяет использовать даты в расчетах. Например, с её помощью легко подсчитать количество дней между двумя датами. 

В Excel существуют две системы дат. Microsoft Excel поддерживает систему дат 1900 и систему дат 1904. Эти системы отличаются начальной датой, от которой отсчитываются порядковые числа дат. В системе дат 1900 начальной датой является 1 января 1900 года, а в системе 1904 — 1 января 1904 года. По умолчанию Excel для Windows использует систему дат 1900, a Excel для Macintosh — систему 1904. Чтобы обеспечить совместимость с файлами электронных таблиц Macintosh, Excel для Windows может поддерживать систему дат 1904.

Максимальная доступная дата — 31 декабря 9999 года (в версиях до Excel 97 - 31 декабря 2078 года).

Время Excel хранит так же в виде чисел, точнее в виде десятичных дробей чисел соответствующих дат. То есть к порядковому номеру даты добавляется дробная часть, соответствующая части суток. Например 06 марта 2011 года имеет порядковый номер 40608, а полдень 06 марта 2011 года (12:00) будет соответствовать числу 40608.5 так как 12 часов - это 0.5 от 24.

Максимальное значение времени, которое можно ввести в ячейку (без значения даты), составляет 9999:59:59 (10 тыс. часов без одной секунды).

 


 

Очевидно, что поддержку даты и времени в формате 1900 (1904) Lua не предоставляет. Однако при реализации экспорта котировок из QUIK в SierraCharts у меня возникла необходимость работы с этим форматом.

 

На горизонте замаячила печальная перспектива написания календаря со всеми этими високосными годами, неравным количеством дней в месяцах и прочей мутью. Неудивительно, что я всячески оттягивал начало мучений с этим календарем.

Лень - двигатель прогресса и минимальные умственные усилия позволили решить задачку без кровопролития.

Мне никогда не потребуются даты ранее 1970 года. А все что позже 1 января 1970 года можно посчитать на самом Lua. Получается, задача-то сводится к преобразованию Posix формата времени в формат 1900 и обратно. Ну это же совсем другая песня!

Работаем с миллисекундами.

 

define(`offset_1900', 25569)
define(`offset_1904', 24107)

define(`seconds_per_day', eval(60*60*24))
define(`mseconds_per_day', eval(seconds_per_day*1000))
time1900 =
{ base = 1900,
-- Пересчет даты и времени из формата datetime в формат Excel 1900 или 1904
-- Параметр: структура datetime
-- Возвращает число
-- Время форматируется в соответствии с полем isdst структуры datetime (true/false)
to = function(datetime)
return (os.time(datetime) + datetime.ms * 0.001) / seconds_per_day + (tonumber(time1900.base) == 1904 and offset_1904 or offset_1900)
end,

-- Преобразование из формата Excel 1900 в формат datetime
from = function(t1900)
local mseconds = math.floor((t1900 - (tonumber(time1900.base) == 1904 and offset_1904 or offset_1900)) * mseconds_per_day + 0.5)
local datetime = os.date("*t",mseconds / 1000)
datetime.ms = mseconds % 1000
return datetime
end

}


См. также Работа с временем в Lua

 

 

Недостаточно прав для комментирования

Архив QLua