Функции даты и времени (Lua) - Торговые роботы и индикаторы под QUIK

Функции даты и времени (Lua)

Давайте сразу определимся. В Lua нет понятия «Календарная дата». Есть понятие «время», которое включает в себя как цифру в календаре, так и показания стрелок будильника. Поэтому в дальнейшем будем оперировать термином «время», подразумевая, что оно включает в себя и день/месяц/год и все остальное.

Для хранения времени в Lua 5.1 используются 2 типа данных.

Первый – это таблица с полями
  • year (год, четыре цифры)
  • month (месяц, 1 – 12)
  • day (день, 1 – 31)
  • hour (час, 0 – 23)
  • min (минуты, 0 – 59)
  • sec (секунды, 0 – 61)
  • wday (день недели, воскресенью соответствует 1)
  • yday (день года)
  • isdst (флаг дневного времени суток, тип boolean).

Давайте в дальнейшем такую таблицу именовать как таблицу datetime. Эта таблица может использоваться как в качестве параметра для функций даты/времени языка lua, так и в качестве возвращаемого результата. В зависимости от контекста не все поля требуют заполнения.

Второй формат хранения даты и времени – это так называемый Posix формат времени (или Unix-время).

Представление времени в виде количества секунд удобно использовать для сравнения и хранения дат (дата и время в этом формате занимают всего 4 или 8 байтов). При необходимости обращения к элементам дат (день, месяц, год) секунды можно преобразовать в любой подходящий формат (и наоборот), но если такие преобразования выполняются часто, они снижают производительность.

Я отдельно подчеркну удобство posix формата времени. Мы можем легко прибавлять, вычитать, сравнивать и находить разницу между двумя временными моментами путем простейших арифметических операций.

Теперь о функциях работы со временем, которые нам предоставляет Lua 5.1. Собственно, основных две:

  • os.time ([table]) – преобразует таблицу datetime в posix
  • os.date ([format [, time]]) – преобразует posix в таблицу datetime.

Как видно, они комплементарные. Однако на самом деле все намного интереснее. Давайте остановимся на каждой из них подробнее. В примерах ниже я буду использовать функцию print(). Если у Вас не установлен пакет Lua 5.1, а только терминал QUIK, замените print() на message()

Преобразование таблицы DATETIME в POSIX:
datetime = { year = 2013, month = 09, day = 13, hour = 21, min = 40, sec = 15}
seconds_since_epoch = os.time(datetime) print(tostring(seconds_since_epoch))
Преобразование POSIX в таблицу DATETIME:
seconds_since_epoch  = 1379094015
datetime = os.date("!*t",seconds_since_epoch)
print( "year = "           .. tostring(datetime.year) .. " " ..
        " month = "        .. tostring(datetime.month) .. " " ..
        "day = "             .. tostring(datetime.day) .. " " ..
        "hour = "            .. tostring(datetime.hour) .. " " ..
        "min = "             .. tostring(datetime.min) .. " " ..
        "sec = "              .. tostring(datetime.sec) .. " " ..
        "weekday = "      .. tostring(datetime.wday) .. " " ..
        "day of year = "  .. tostring(datetime.yday) .. " " ..
        " iddst = "          .. tostring(datetime.isdst))

Первым параметром os.date() идет строка «!*t». Расшифрую. Если первый параметр начинается с ‘!’, то время форматируется в соответствии с универсальным глобальным временем (по Гринвичу). Далее если следуют символы «*t», то os.date() возвращает таблицу datetime.

Получение текущего времени в формате POSIX:
print(os.time())
Получение текущего времени в формате DATETIME:
datetime = os.date("!*t",os.time())
print( tostring(datetime.year) .. " " ..
         tostring(datetime.month) .. " " ..
         tostring(datetime.day) .. " " ..
         tostring(datetime.hour) .. " " ..
         tostring(datetime.min) .. " " ..
         tostring(datetime.sec) .. " " ..
         tostring(datetime.wday) .. " " ..
         tostring(datetime.yday) .. " " ..<
         tostring(datetime.isdst))
Варианты работы функции OS.DATE():

Собственно, про os.time() сказать больше нечего. А вот у второй функции еще масса возможностей.

Первый параметр функции os.date(), как мы видели выше, должен быть текстовой строкой, которая управляет поведением функции и возвращаемым значением. Вот полный список возможных строк и, соответственно, возвращаемых функцией значений:

%a abbreviated weekday name (e.g., Wed)
%A full weekday name (e.g., Wednesday)
%b abbreviated month name (e.g., Sep)
%B full month name (e.g., September)
%c date and time (e.g., 09/16/98 23:48:10)
%d day of the month (16) [01-31]
%H hour, using a 24-hour clock (23) [00-23]
%I hour, using a 12-hour clock (11) [01-12]
%M minute (48) [00-59]
%m month (09) [01-12]
%p either «am» or «pm» (pm)
%S second (10) [00-61]
%U sunday week of the year 00 (53)
%w weekday (3) [0-6 = Sunday-Saturday]
%W monday week of the year, from 00 (48)
%x date (e.g., 09/16/98)
%X time (e.g., 23:48:10)
%Y full year (1998)
%y two-digit year (98) [00-99]
%z  timezone string
%% the character %
Преобразование строки даты в DATETIME:
В терминале Quik строковое представление даты бывает в двух форматах. Любой из них легко преобразуется в формат datetime.

Для формата DD.MM.YYYY:

datetime = {}
datetime.day,datetine.month,datetime.year = string.match("13.09.2013","(%d*)\.(%d*)\.(%d*)")

Для формата YYYYMMDD:

datetime = {}
datetime.year,datetime.month,datetime.day = string.match("20130913","(%d%d%d%d)(%d%d)(%d%d)")

Замечу, что в обоих случаях string.match() выдает текстовые строки, а не числовые значения, которые сохраняются в datetime. Тем не менее os.time() прекрасно это понимает.

Преобразование строки времени в DATETIME:
datetime={}
datetime.hour,datetime.min,datetime.sec = string.match("21:17:43","(%d%d)%p(%d%d)%p(%d%d)")

Замечу, что поля year, month и day должны быть также заполнены.

Читайте также:

Добавить комментарий