Работа с датами и временем
Помимо традиционного формата указания даты (YMD, YMDHMS, в строках или в числовом представлении), nnCron работает и с двумя другими представлениями дат: DATE и FILETIME.
DATE - это число, которое в двоичном представлении выглядит так: гггггггггггммммддддд, т. е. пять младших разрядов занимает день, четыре следующих - месяц, а все остальное год. Из этого следует, что DATE содержит только информацию о годе, месяце и числе. Информация о часах, минутах и секундах не хранится. Формат DATE используют, например, слова FILE-CREATION-DATE:, FILE-ACCESS-DATE:, FILE-WRITE-DATE:, а также слова, употребляемые внутри цикла FOR-FILES: (CREATION-DATE, ACCESS-DATE, WRITE-DATE).
FILETIME позволяет оперировать не только со значениями года, месяца и числа, но и с часами, минутами, секундами и даже миллисекундами. FILETIME - число двойной длины, которое содержит количество 100-наносекндных интервалов, прошедших с 1-го января 1601 года до времени указанной даты. Формат FILETIME используют, например, слова из плагина time.spf (FILE-TIME:, FILE-ATIME:, FILE-WTIME:). При работе с датами и временем мы рекомендуем использовать именно формат FILETIME.
При необходимости вы можете конвертировать даты между форматами YMD, DATE и FILETIME.
ASSUMED-NEXT-TIME (
-- d t= | -- f= )
ASSUMED-PREV-TIME ( -- d t= | -- f= )
При использовании внутри задачи, эти слова позволяют получить доступ к информации о предполагаемом времени следующего и предыдущего запусков текущей задачи.
Слово ASSUMED-NEXT-TIME возвращает флаг TRUE и предполагаемое время следующего планируемого запуска задачи либо просто флаг FALSE, если программе не удается вычислить время. Слово ASSUMED-PREV-TIME возвращает флаг TRUE и предполагаемое время предыдущего запуска задачи (даже если оно было просрочено) или флаг FALSE, если программе не удается вычислить время.
Оба слова возвращает время в формате FILETIME.
Примеры:
#( test_assumed_time \ каждые две минуты выводим на консоль \ предполагаемое время следующего запуска задачи Time: */2 Action: ASSUMED-NEXT-TIME IF FT>DD.MM.YYYY/hh:mm:ss TYPE CR THEN )# #( test_assumed_time1 \ создаем специальные слова и каждые три минуты \ выводим на консоль предполагаемое время предыдущего \ и следующего запуска задачи : FT. FT>DD.MM.YYYY/hh:mm:ss TYPE ; : ?FT. IF FT. ELSE ." none" THEN ; Time: */3 Action: ASSUMED-NEXT-TIME ?FT. CR ASSUMED-PREV-TIME ?FT. CR )#
Кладет на стек значение текущей даты (в формате DATE). Используется для сравнения произвольных дат, например даты создания/последнего доступа/последней записи в файл с текущей датой (подробнее).
Преобразует дату в формате DATE в строку "DD-MM-YYYY".
Примеры:
\ выводим текущую дату на консоль CUR-DATE DATE>S TYPE #( test_message
NoActive Action: \ выводим текущую дату в сообщении MSG: "Current date: %CUR-DATE DATE>S%" )#
Возвращает разницу в днях между двумя датами в формате DATE.
Пример:
\ кладем на стек значение текущей даты CUR-DATE \ преобразуем дату "31 декабря 2002" в формат DATE 2002 12 31 YMD>DATE \ вычисляем разницу (в днях) между этими двумя датами DATE- . CR
DATE-INTERVAL: dd1.mm1.yyyy1-dd2.mm2.yyyy2[/days]
Возвращает флаг TRUE (-1), если текущая дата попадает в указанный
интервал.
Дополнительный (необязательный) параметр, указывающийся через косую черту, определяет
"шаг срабатывания" условия: (количество дней, прошедших с начала интервала
кратно периоду days).
См. также: INTERVAL: hh1:mm1-hh2:mm2[/hh3:mm3]
DAY+ ( y m d days -- y1 m1 d1 )
Это слово позволяет "добавить" или "отнять" произвольное количество дней у даты, указанной в формате YMD и получить результат в этом же формате, с учетом количества дней в месяце и количества месяцев в году.
Пример:
\ добавляем один день к дате "31 декабря 2002", \ выводим на консоль результат ("1 января 2003"). 2002 12 31 1 DAY+ . . . CR
Используйте отрицательное значение, чтобы "вычесть" определенное количество дней.
Пример:
\ вычитаем один день из даты "31 декабря 2002", \ выводим на консоль результат ("30 декабря 2002"). 2002 12 31 -1 DAY+ . . . CR
Кладет на стек количество дней, прошедших от начала летоисчисления по григорианскому календарю до указанной даты. В качестве аргумента принимает дату в формате YMD.
Пример:
\ выводим на консоль количество дней, \ прошедших до 1 января 2003 2003 1 1 DAYS . CR
Кладет на стек количество дней, прошедших от начала летоисчисления по григорианскому календарю до текущей даты.
Возвращает разницу между двумя датами в формате FILETIME. Чтобы перевести полученное значение, например, в секунды, воспользуйтесь словом FT>SEC.
Пример:
\ дважды "засекаем" время и кладем на стек \ разницу между двумя датами в секундах FT-CUR 10000 PAUSE FT-CUR FT- FT>SEC D>S . CR
Конвертирует текущие дату и время в формат FILETIME.
Пример:
#( test_file_time \ если файл '1.sem' создан больше двух минут назад, \ производим какие-то полезные действия Action: FT-CUR FILE-TIME: "C:\1.sem" FTIME- 120 > IF \ ... производим работу THEN )#
Конвертирует указанную дату и время в формате FILETIME в количество дней, часов и минут соответственно.
FT>DD.MM.YYYY/hh:mm:ss ( d - a u)
Конвертирует указанную дату и время в формате FILETIME в строку "DD.MM.YYYY/hh:mm:ss".
Пример:
\ выводим на консоль текущую дату и время (31.03.3003/14:40:47) FT-CUR FT>DD.MM.YYYY/hh:mm:ss TYPE CR
Конвертирует указанную дату и время в формате FILETIME в миллисекунды и секунды соответственно. Возвращает число двойной длины.
Принудительно "обновляет" значение текущего времени. nnCron делает это автоматически один раз в минуту и, соответственно, значения секунд в течение минуты больше не обновляются. Используйте GET-CUR-TIME, чтобы обновить значение секунд принудительно.
Примеры:
\ на пpотяжении минуты (pаз в секунду) \ пишем точное текущее вpемя в лог-файл: #( test_cur_time NoActive Action: 60 0 DO GET-CUR-TIME LOG: "log\idle.log" "%hh%:%mm%:%ss% - current time" PAUSE: 1000 LOOP )# \ выводим на консоль точное значение текущей секунды GET-CUR-TIME Sec@
Кладет на стек количество миллисекунд, прошедших с момента старта операционной системы. GetTickCount - это системная функция, которая возвращает число одинарной длины со знаком. Это означает, что через 49,7 дней непрерывной работы компьютера значение GetTickCount переполнится и снова начнет отсчитываться с нуля.
Пример:
\ задача запустится, если с момента старта \ операционной системы прошло меньше 90 секунд Rule: GetTickCount 90000 <
См. также: UPTIME
INTERVAL: hh1:mm1-hh2:mm2[/hh3:mm3]
Возвращает флаг TRUE (-1), если текущее время попадает в указанный
интервал.
Дополнительный (необязательный) параметр, указывающийся через косую черту определяет
"шаг срабатывания" условия: (время, прошедшее от начала интервала,
кратно периоду hh3:mm3).
\ возвратит 'TRUE' в 10:00, 10:45 и 11:30 \ (т. е. через каждые 45 минут) Rule: INTERVAL: 10:00-12:00/00:45 \ возвратит 'TRUE' в 10:00, 11:01, 12:02 и 13:03 \ (т. е. раз в 61-ну минуту) Rule: INTERVAL: 10:00-14:00/01:01
Примеры:
#( test_interval WatchConnect Rule: INTERVAL: 10:00-18:00 Action: \ ... выполняем работу )#
#( test_interval1 \ срабатываем раз в 30 минут с 10:00 до 18:00 включительно Rule: INTERVAL: 10:00-18:00/00:30 Action: MSG: "Прошло полчаса!" )#
См. также: DATE-INTERVAL: dd1.mm1.yyyy1-dd2.mm2.yyyy2[/days]
FT>DATE
FT>YMDHMS
DATE>YMD
YMD>DATE
YMDHMS>FT
Эти слова конвертируют даты между форматами YMD (YMDHMS), DATE и FILETIME.
Примеры:
\ FILETIME в DATE FT-CUR FT>DATE \ FILETIME в YMDHMS FT-CUR FT>YMDHMS \ DATE в YMD CUR-DATE DATE>YMD \ YMD в DATE 2002 12 31 YMD>DATE \ YMDHMS в FILETIME 2002 12 31 0 0 0 YMDHMS>FT
Sec@
Min@
Hour@
Day@
Mon@
WDay@
Year@
Эти слова кладут на стек текущее значение секунды, минуты, часа, дня, месяца, дня недели и года. Обратите внимание, что для получения корректного текущего значения секунд вам придется воспользоваться словом GET-CUR-TIME.
Пример:
\ кладем на стек текущую дату в формате YMD Year@ Mon@ Day@ \ кладем на стек текущую дату в формате YMDHMS Year@ Mon@ Day@ Hour@ Min@ GET-CUR-TIME Sec@
MonLength ( year month -- days-of-month )
Возвращает количество дней в указанном месяце. В качестве аргументов принимает год и порядковый номер нужного месяца.
Пример:
\ выводим на консоль количество дней в феврале 2003 2003 2 MonLength . CR
Эти предопределенные массивы содержат сокращенные названия дней недели и месяцев. WDAYS содержит символы "MonTueWedThuFriSatSun", a MONNAMES содержит символы "JanFebMarAprMayJunJulAugSepOctNovDec". С помощью этих массивов вы можете получить название дня недели/месяца по его порядковому номеру.
Примеры:
\ выводим на консоль название 1-го месяца 1 1- 3 * MONNAMES COUNT DROP + 3 TYPE CR \ выводим на консоль название 12-го месяца 12 1- 3 * MONNAMES COUNT DROP + 3 TYPE CR \ выводим на консоль название 3-го дня недели 3 1- 3 * WDAYS COUNT DROP + 3 TYPE CR \ выводим на консоль название 5-го дня недели 5 1- 3 * WDAYS COUNT DROP + 3 TYPE CR
Кладет на стек количество дней, прошедших от начала летоисчисления по григорианскому календарю до указанной даты. В качестве аргумента принимает строку с датой в формате DD.MM.YYYY.
Пример:
\ выводим на консоль количество дней, \ прошедших до 31.12.2002 S" 31.12.2002" SD.M.Y>Day . CR
SDD.MM.YYYY ( addr u -- y m d )
Конвертирует строку в формате DD.MM.YYYY в дату (формат YMD).
Пример:
\ конвертируем строку "31.12.2002" в три числа (YMD) \ и выводим эти числа на консоль S" 31.12.2002" SDD.MM.YYYY . . . CR
Принимает в качестве аргумента строку со временем в формате HH:MM и конвертирует это время в число, содержащее количество минут.
Примеры:
\ переводим строки "1:20" и "01:20" \ в количество минут (80) S" 1:20" SH:M>Min . CR S" 01:20" SH:M>Min . CR
Проверяет, совпадает ли текущее время с началом первой минуты после старта nnCron. Возвращает TRUE (-1), если это соответствует действительности и FALSE (0) в противном случае. Слово START-TIME? удобно использовать, например, для предотвращения запуска задачи при старте nnCron.
Пример:
#( test_nostartup
\ запускаться каждую минуту, но не в начале
\ первой минуты после старта nnCron
Rule: START-TIME? 0=
Action:
\ ...
)#
TASK-CREATION-TIME (
-- d t= | -- f=)
TASK-EXECUTION-TIME ( -- d t= | -- f=)
При использовании внутри задачи, эти слова позволяют получить доступ к информации о времени создания текущей задачи (вернее времени последнего изменения хотя бы одной из конструкций Time: этой задачи) и времени последнего выполнения текущей задачи..
Слово TASK-CREATION-TIME возвращает флаг TRUE и время создания задачи либо просто флаг FALSE, если программе не удается вычислить время. Слово TASK-EXECUTION-TIME возвращает флаг TRUE и время последнего выполнения текущей задачи или флаг FALSE, если программе не удается вычислить время.
Оба слова возвращает время в формате FILETIME.
Примеры:
#( test_task_time \ каждые две минуты выводим на консоль \ время создания текущей задачи Time: */2 Action: TASK-CREATION-TIME IF FT>DD.MM.YYYY/hh:mm:ss TYPE CR THEN )# #( test_task_time1 \ создаем специальные слова и каждые три минуты \ выводим на консоль время создания и выполнения \ текущей задачи : FT. FT>DD.MM.YYYY/hh:mm:ss TYPE ; : ?FT. IF FT. ELSE ." none" THEN ; Time: */3 Action: TASK-CREATION-TIME ?FT. CR TASK-EXECUTION-TIME ?FT. CR )#
TimeMin@ ( -- CurrentTime_in_minutes
)
TimeSec@ ( -- CurrentTime_in_seconds )
Кладет на стек текущее время в минутах/секундах (количество минут/секунд, прошедших с ближайшей полуночи).
Примеры:
\ выводим на консоль текущее время в минутах/секундах TimeMin@ . CR TimeSec@ . CR
Кладет на стек порядковый номер дня недели (1 ... 7), на который попадает указанная дата в формате YMD.
Пример:
\ выводим на консоль день недели, \ на который попадает 31 декабря 2002 2002 12 31 WEEK-DAY . CR
См. также: