mirror of
https://github.com/PerMalmberg/libcron.git
synced 2025-10-16 21:12:06 -05:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8c144b0ddb | ||
|
de143e8b8e | ||
|
aa3d4368d5 | ||
|
7c7d290792 |
27
README.md
27
README.md
@@ -6,10 +6,16 @@ A C++ scheduling library using cron formatting.
|
|||||||
Libcron offers an easy to use API to add callbacks with corresponding cron-formatted strings:
|
Libcron offers an easy to use API to add callbacks with corresponding cron-formatted strings:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
#include <libcron/Cron.h>
|
||||||
|
#include <libcron/CronData.h>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
libcron::Cron cron;
|
libcron::Cron cron;
|
||||||
|
|
||||||
cron.add_schedule("Hello from Cron", "* * * * * ?", [=](auto&) {
|
cron.add_schedule("Hello from Cron", "* * * * * ?", [=](auto&) {
|
||||||
std::cout << "Hello from libcron!" std::endl;
|
std::cout << "Hello from libcron!" << std::endl;
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -19,7 +25,7 @@ To trigger the execution of callbacks, one must call `libcron::Cron::tick` at le
|
|||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
cron.tick();
|
cron.tick();
|
||||||
std::this_thread::sleep_for(500mS);
|
std::this_thread::sleep_for(500ms);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -188,23 +194,28 @@ the '?'-character to ensure that it is not possible to specify a statement which
|
|||||||
|Expression | Meaning
|
|Expression | Meaning
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| * * * * * ? | Every second
|
| * * * * * ? | Every second
|
||||||
|
| 0 * * * * ? | Every minute
|
||||||
| 0 0 12 * * MON-FRI | Every Weekday at noon
|
| 0 0 12 * * MON-FRI | Every Weekday at noon
|
||||||
| 0 0 12 1/2 * ? | Every 2 days, starting on the 1st at noon
|
| 0 0 12 1/2 * ? | Every 2 days, starting on the 1st at noon
|
||||||
| 0 0 */12 ? * * | Every twelve hours
|
| 0 0 */12 ? * * | Every twelve hours
|
||||||
| @hourly | Every hour
|
| @hourly | Every hour
|
||||||
|
|
||||||
|
Note that the expression formatting has a part for seconds and the day of week.
|
||||||
|
For the day of week part, a question mark ? is utilized. This format
|
||||||
|
may not be parsed by all online crontab calculators or expression generators.
|
||||||
|
|
||||||
## Convenience scheduling
|
## Convenience scheduling
|
||||||
|
|
||||||
These special time specification tokens which replace the 5 initial time and date fields, and are prefixed with the '@' character, are supported:
|
These special time specification tokens which replace the 5 initial time and date fields, and are prefixed with the '@' character, are supported:
|
||||||
|
|
||||||
|Token|Meaning
|
|Token|Meaning
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| @yearly | Run once a year, ie. "0 0 1 1 *".
|
| @yearly | Run once a year, ie. "0 0 0 1 1 *".
|
||||||
| @annually | Run once a year, ie. "0 0 1 1 *".
|
| @annually | Run once a year, ie. "0 0 0 1 1 *"".
|
||||||
| @monthly | Run once a month, ie. "0 0 1 * *".
|
| @monthly | Run once a month, ie. "0 0 0 1 * *".
|
||||||
| @weekly | Run once a week, ie. "0 0 * * 0".
|
| @weekly | Run once a week, ie. "0 0 0 * * 0".
|
||||||
| @daily | Run once a day, ie. "0 0 * * *".
|
| @daily | Run once a day, ie. "0 0 0 * * ?".
|
||||||
| @hourly | Run once an hour, ie. "0 * * * *".
|
| @hourly | Run once an hour, ie. "0 0 * * * ?".
|
||||||
|
|
||||||
# Randomization
|
# Randomization
|
||||||
|
|
||||||
|
@@ -39,12 +39,12 @@ namespace libcron
|
|||||||
{
|
{
|
||||||
// First, check for "convenience scheduling" using @yearly, @annually,
|
// First, check for "convenience scheduling" using @yearly, @annually,
|
||||||
// @monthly, @weekly, @daily or @hourly.
|
// @monthly, @weekly, @daily or @hourly.
|
||||||
std::string tmp = std::regex_replace(cron_expression, std::regex("@yearly"), "0 0 1 1 *");
|
std::string tmp = std::regex_replace(cron_expression, std::regex("@yearly"), "0 0 0 1 1 *");
|
||||||
tmp = std::regex_replace(tmp, std::regex("@annually"), "0 0 1 1 *");
|
tmp = std::regex_replace(tmp, std::regex("@annually"), "0 0 0 1 1 *");
|
||||||
tmp = std::regex_replace(tmp, std::regex("@monthly"), "0 0 1 * *");
|
tmp = std::regex_replace(tmp, std::regex("@monthly"), "0 0 0 1 * *");
|
||||||
tmp = std::regex_replace(tmp, std::regex("@weekly"), "0 0 * * 0");
|
tmp = std::regex_replace(tmp, std::regex("@weekly"), "0 0 0 * * 0");
|
||||||
tmp = std::regex_replace(tmp, std::regex("@daily"), "0 0 * * *");
|
tmp = std::regex_replace(tmp, std::regex("@daily"), "0 0 0 * * ?");
|
||||||
const std::string expression = std::regex_replace(tmp, std::regex("@hourly"), "0 * * * *");
|
const std::string expression = std::regex_replace(tmp, std::regex("@hourly"), "0 0 * * * ?");
|
||||||
|
|
||||||
// Second, split on white-space. We expect six parts.
|
// Second, split on white-space. We expect six parts.
|
||||||
std::regex split{ R"#(^\s*(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$)#",
|
std::regex split{ R"#(^\s*(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$)#",
|
||||||
|
@@ -237,4 +237,13 @@ SCENARIO("Replacing text with numbers")
|
|||||||
std::string s = "JAN-DEC";
|
std::string s = "JAN-DEC";
|
||||||
REQUIRE(CronData::replace_string_name_with_numeric<libcron::Months>(s) == "1-12");
|
REQUIRE(CronData::replace_string_name_with_numeric<libcron::Months>(s) == "1-12");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SCENARIO("Parsing @ expressions works") {
|
||||||
|
REQUIRE(CronData::create("@yearly").is_valid());
|
||||||
|
REQUIRE(CronData::create("@annually").is_valid());
|
||||||
|
REQUIRE(CronData::create("@monthly").is_valid());
|
||||||
|
REQUIRE(CronData::create("@weekly").is_valid());
|
||||||
|
REQUIRE(CronData::create("@daily").is_valid());
|
||||||
|
REQUIRE(CronData::create("@hourly").is_valid());
|
||||||
}
|
}
|
@@ -184,6 +184,15 @@ SCENARIO("Examples from README.md")
|
|||||||
DT(2018_y / 03 / 1, hours{12}, minutes{13}, seconds{48})
|
DT(2018_y / 03 / 1, hours{12}, minutes{13}, seconds{48})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
REQUIRE(test("0 * * * * ?", DT(2018_y / 03 / 1, hours{ 12 }, minutes{ 0 }, seconds{ 10 }),
|
||||||
|
{
|
||||||
|
DT(2018_y / 03 / 1, hours{12}, minutes{1}, seconds{0}),
|
||||||
|
DT(2018_y / 03 / 1, hours{12}, minutes{2}, seconds{0}),
|
||||||
|
DT(2018_y / 03 / 1, hours{12}, minutes{3}, seconds{0}),
|
||||||
|
DT(2018_y / 03 / 1, hours{12}, minutes{4}, seconds{0})
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
REQUIRE(test("0 0 12 * * MON-FRI", DT(2018_y / 03 / 10, hours{12}, minutes{13}, seconds{45}),
|
REQUIRE(test("0 0 12 * * MON-FRI", DT(2018_y / 03 / 10, hours{12}, minutes{13}, seconds{45}),
|
||||||
{
|
{
|
||||||
DT(2018_y / 03 / 12, hours{12}),
|
DT(2018_y / 03 / 12, hours{12}),
|
||||||
@@ -212,4 +221,4 @@ SCENARIO("Examples from README.md")
|
|||||||
SCENARIO("Unable to calculate time point")
|
SCENARIO("Unable to calculate time point")
|
||||||
{
|
{
|
||||||
REQUIRE_FALSE(test( "0 0 * 31 FEB *", DT(2021_y / 1 / 1), DT(2022_y / 1 / 1)));
|
REQUIRE_FALSE(test( "0 0 * 31 FEB *", DT(2021_y / 1 / 1), DT(2022_y / 1 / 1)));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user