mirror of
https://github.com/PerMalmberg/libcron.git
synced 2025-04-22 00:13:01 -05:00
Part of calculation
This commit is contained in:
parent
a6dd20d150
commit
22da55666a
@ -8,4 +8,11 @@ include_directories(externals/date)
|
||||
|
||||
add_library(${PROJECT_NAME}
|
||||
Cron.h
|
||||
Cron.cpp Task.h CronData.h TimeTypes.h CronData.cpp)
|
||||
Cron.cpp
|
||||
Task.h
|
||||
CronData.h
|
||||
TimeTypes.h
|
||||
CronData.cpp
|
||||
CronSchedule.cpp
|
||||
CronSchedule.h
|
||||
externals/date/date.h DateTime.h)
|
||||
|
@ -7,7 +7,7 @@ bool libcron::Cron::add_schedule(const std::string &schedule, std::function<void
|
||||
bool res = cron.is_valid();
|
||||
if (res)
|
||||
{
|
||||
items.emplace(Task(cron, std::move(work)));
|
||||
items.emplace(Task(CronSchedule(cron), std::move(work)));
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include "TimeTypes.h"
|
||||
#include <regex>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "TimeTypes.h"
|
||||
|
||||
namespace libcron
|
||||
{
|
||||
@ -96,6 +95,12 @@ namespace libcron
|
||||
return day_of_week;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static uint8_t value_of(T t)
|
||||
{
|
||||
return static_cast<uint8_t>(t);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void parse(const std::string& cron_expression);
|
||||
@ -123,12 +128,6 @@ namespace libcron
|
||||
template<typename T>
|
||||
bool get_step(const std::string& s, uint8_t& start, uint8_t& step);
|
||||
|
||||
template<typename T>
|
||||
uint8_t value_of(T t)
|
||||
{
|
||||
return static_cast<uint8_t>(t);
|
||||
}
|
||||
|
||||
std::vector<std::string> split(const std::string& s, char token);
|
||||
|
||||
bool is_number(const std::string& s);
|
||||
|
61
libcron/CronSchedule.cpp
Normal file
61
libcron/CronSchedule.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "CronSchedule.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
using namespace date;
|
||||
|
||||
namespace libcron
|
||||
{
|
||||
|
||||
std::chrono::system_clock::time_point
|
||||
CronSchedule::calculate_from(const std::chrono::system_clock::time_point& from)
|
||||
{
|
||||
auto curr = from;
|
||||
|
||||
year_month_day ymd = date::floor<days>(curr);
|
||||
|
||||
// Add months until one of the allowed days are found, or stay at the current one.
|
||||
while (data.get_months().find(static_cast<Months>(unsigned(ymd.month()))) == data.get_months().end())
|
||||
{
|
||||
curr += months{1};
|
||||
ymd = date::floor<days>(curr);
|
||||
};
|
||||
|
||||
|
||||
// If all days are allowed, then the 'day of week' takes precedence, which also means that
|
||||
// day of week only is ignored when specific days of months are specified.
|
||||
if (data.get_day_of_month().size() != CronData::value_of(DayOfMonth::Last))
|
||||
{
|
||||
// Add days until one of the allowed days are found, or stay at the current one.
|
||||
while (data.get_day_of_month().find(static_cast<DayOfMonth>(unsigned(ymd.day()))) ==
|
||||
data.get_day_of_month().end())
|
||||
{
|
||||
curr += days{1};
|
||||
ymd = date::floor<days>(curr);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
//Add days until the current weekday is one of the allowed weekdays
|
||||
year_month_weekday ymw = date::floor<days>(curr);
|
||||
|
||||
while (data.get_day_of_week().find(static_cast<DayOfWeek>(unsigned(ymw.weekday()))) ==
|
||||
data.get_day_of_week().end())
|
||||
{
|
||||
curr += days{1};
|
||||
ymw = date::floor<days>(curr);
|
||||
};
|
||||
}
|
||||
|
||||
// 'curr' now represents the next year, month and day matching the expression, with a time of 0:0:0.
|
||||
|
||||
// Re-add the hours, minutes and seconds to 'curr'
|
||||
auto date_time = to_calendar_time(from);
|
||||
curr += hours{date_time.hour};
|
||||
curr += minutes{date_time.min};
|
||||
curr += seconds{date_time.sec};
|
||||
|
||||
auto t = to_calendar_time(from);
|
||||
|
||||
return curr;
|
||||
}
|
||||
}
|
44
libcron/CronSchedule.h
Normal file
44
libcron/CronSchedule.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "CronData.h"
|
||||
#include <chrono>
|
||||
#include "externals/date/date.h"
|
||||
#include "DateTime.h"
|
||||
|
||||
namespace libcron
|
||||
{
|
||||
class CronSchedule
|
||||
{
|
||||
public:
|
||||
explicit CronSchedule(CronData data)
|
||||
: data(std::move(data))
|
||||
{
|
||||
}
|
||||
|
||||
std::chrono::system_clock::time_point calculate_from(const std::chrono::system_clock::time_point& from);
|
||||
|
||||
// https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#obtaining-ymd-hms-components-from-a-time_point
|
||||
static DateTime to_calendar_time(std::chrono::system_clock::time_point time)
|
||||
{
|
||||
auto daypoint = date::floor<date::days>(time);
|
||||
auto ymd = date::year_month_day(daypoint); // calendar date
|
||||
auto tod = date::make_time(time - daypoint); // Yields time_of_day type
|
||||
|
||||
// Obtain individual components as integers
|
||||
DateTime dt{
|
||||
int(ymd.year()),
|
||||
unsigned(ymd.month()),
|
||||
unsigned(ymd.day()),
|
||||
static_cast<uint8_t>(tod.hours().count()),
|
||||
static_cast<uint8_t>(tod.minutes().count()),
|
||||
static_cast<uint8_t>(tod.seconds().count())};
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CronData data;
|
||||
};
|
||||
|
||||
}
|
16
libcron/DateTime.h
Normal file
16
libcron/DateTime.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace libcron
|
||||
{
|
||||
struct DateTime
|
||||
{
|
||||
int year = 0;
|
||||
unsigned month = 0;
|
||||
unsigned day = 0;
|
||||
uint8_t hour = 0;
|
||||
uint8_t min = 0;
|
||||
uint8_t sec = 0;
|
||||
};
|
||||
}
|
@ -2,25 +2,30 @@
|
||||
|
||||
#include <functional>
|
||||
#include "CronData.h"
|
||||
#include "CronSchedule.h"
|
||||
|
||||
namespace libcron
|
||||
{
|
||||
class Task
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
Task(CronData time, std::function<void()> task)
|
||||
: time(std::move(time)), task(std::move(task))
|
||||
{
|
||||
}
|
||||
Task(CronSchedule schedule, std::function<void()> task)
|
||||
: schedule(std::move(schedule))//, task(std::move(task))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const Task& other) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Task(const Task&) = default;
|
||||
|
||||
private:
|
||||
CronData time{};
|
||||
std::function<void()> task;
|
||||
Task& operator=(const Task&) = default;
|
||||
|
||||
bool operator<(const Task& other) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
CronSchedule schedule;
|
||||
//std::function<void()> task;
|
||||
};
|
||||
}
|
@ -7,6 +7,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -fsanitize=address -las
|
||||
include_directories(
|
||||
externals/Catch2/single_include/
|
||||
..
|
||||
../libcron/externals/date
|
||||
)
|
||||
|
||||
add_executable(
|
||||
|
@ -1,11 +1,13 @@
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <date.h>
|
||||
#include <libcron/Cron.h>
|
||||
#include <libcron/CronData.h>
|
||||
|
||||
using namespace libcron;
|
||||
using namespace date;
|
||||
using namespace std::chrono;
|
||||
|
||||
template<typename T>
|
||||
bool has_value_range(const std::set<T>& set, uint8_t low, uint8_t high)
|
||||
@ -231,18 +233,30 @@ SCENARIO("Calculating next runtime")
|
||||
{
|
||||
auto c = CronData::create("0 0 * * * *");
|
||||
REQUIRE(c.is_valid());
|
||||
CronSchedule sched(c);
|
||||
|
||||
WHEN("Start time is midnight")
|
||||
{
|
||||
// std::chrono::system_clock::time_point run_time = c.calculate_from(midnight);
|
||||
// THEN("Next runtime is 01:00")
|
||||
// {
|
||||
// auto t = std::chrono::system_clock::to_time_t(run_time);
|
||||
sys_days midnight = 2010_y/1/1;
|
||||
std::chrono::system_clock::time_point run_time = sched.calculate_from(midnight);
|
||||
|
||||
THEN("Next runtime is 01:00 of the same date")
|
||||
{
|
||||
auto t = CronSchedule::to_calendar_time(run_time);
|
||||
REQUIRE(t.year == 2010);
|
||||
REQUIRE(t.month == 1);
|
||||
REQUIRE(t.day == 1);
|
||||
REQUIRE(t.hour == 1);
|
||||
REQUIRE(t.min == 0);
|
||||
REQUIRE(t.sec == 0);
|
||||
|
||||
|
||||
// auto t = std::chrono::system_clock::to_time_t(run_time);
|
||||
// REQUIRE(t.get_seconds() == 0);
|
||||
// REQUIRE(t.minute == 0);
|
||||
// REQUIRE(t.hour == 1);
|
||||
// REQUIRE(t.)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user