CRON date&time range
Motivation for LwDTC library comes with my home automation project, where I need a simple way to define range of date or time, from and to, in very flexible and field-agnostic way.
It should be possible to just define from and to seconds within a minute, or from 2
different minutes and different seconds.
CRON concept doesn’t provide such functionality. To overcome such problem, a simple solution with multiple cron objects can be implemented.
Consider a task, that needs to execute each beginning of a minute, between Monday starting at 07:00:00
and Friday ending at 19:30:00
.
For CRON-like compatible syntax, defined range needs a split to:
Monday: CRON is active every beginning of a minute from
07
to23
hours. This can be described as:0 * 7/1 * * 1 *
Tue,Wed,Thu: CRON is active at beginning of each minute for all
3
days:0 * * * * 2-4 *
Friday:
CRON is active between
0
and19
hours, at beginning of each minute:0 * 7-19 * * 5 *
CRON is also active at beginning of each minute, when minutes are between
0
and30
and when hour is19
:0 0-30 19 * * 5 *
This gives us in total 4
different cron objects, for which:
We need to parse all of them
To check if particular time is within range, an OR operation between all ranges is performed
1#include "windows.h"
2#include <time.h>
3#include <stdio.h>
4#include "lwdtc/lwdtc.h"
5
6/*
7 * This is example for docs user manual
8 *
9 * Defines time range:
10 * - Starts at Monday at 07:00 morning
11 * - Ends on Friday at 19:30 evening
12 */
13static const char* cron_strings[] = {
14 "0 * 7/1 * * 1 *",
15 "0 * * * * 2-4 *",
16 "0 * 7-19 * * 5 *",
17 "0 0-30 19 * * 5 *"
18};
19
20/* Define context array for all CRON strings */
21static lwdtc_cron_ctx_t cron_ctx[LWDTC_ARRAYSIZE(cron_strings)] = {0};
22
23int
24cron_dt_range(void) {
25 /* Define context for CRON, used to parse data to */
26 struct tm* timeinfo;
27 time_t rawtime, rawtime_old = 0;
28
29 /* Parse all CRON strings */
30 for (size_t i = 0; i < LWDTC_ARRAYSIZE(cron_strings); ++i) {
31 if (lwdtc_cron_parse(&cron_ctx[i], cron_strings[i]) != lwdtcOK) {
32 printf("Could not parse CRON: %s\r\n", cron_strings[i]);
33 while (1) {}
34 }
35 }
36
37 while (1) {
38 /* Get current time and react on changes only */
39 time(&rawtime);
40
41 /* Check if new time has changed versus last read */
42 if (rawtime != rawtime_old) {
43 rawtime_old = rawtime;
44 timeinfo = localtime(&rawtime);
45
46 /* Print time to user */
47 printf("Time: %02d.%02d.%04d %02d:%02d:%02d\r\n",
48 (int)timeinfo->tm_mday, (int)timeinfo->tm_mon, (int)timeinfo->tm_year + 1900,
49 (int)timeinfo->tm_hour, (int)timeinfo->tm_min, (int)timeinfo->tm_sec
50 );
51
52 /* Check if current time fits inside CRON-defined time range */
53 if (lwdtc_cron_is_valid_for_time_multi_or(timeinfo, cron_ctx, LWDTC_ARRAYSIZE(cron_ctx)) == lwdtcOK) {
54 printf("Time is within CRON range\r\n");
55 } else {
56 printf("Time is NOT within CRON range\r\n");
57 }
58 }
59
60 /* This is sleep from windows.h lib */
61 Sleep(100);
62 }
63 return 0;
64}