mirror of
https://github.com/PerMalmberg/libcron.git
synced 2025-04-22 08:23:04 -05:00
Added UTC handling for Windows
This commit is contained in:
parent
5395c75061
commit
c441da4287
@ -2,7 +2,12 @@ cmake_minimum_required(VERSION 3.6)
|
|||||||
project(libcron)
|
project(libcron)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
|
|
||||||
|
if( MSVC )
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/externals/date/include)
|
include_directories(${CMAKE_CURRENT_LIST_DIR}/externals/date/include)
|
||||||
|
|
||||||
@ -16,7 +21,8 @@ add_library(${PROJECT_NAME}
|
|||||||
CronSchedule.h
|
CronSchedule.h
|
||||||
DateTime.h
|
DateTime.h
|
||||||
Task.cpp
|
Task.cpp
|
||||||
CronClock.h)
|
CronClock.h
|
||||||
|
CronClock.cpp)
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_LOCATION}"
|
ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_LOCATION}"
|
||||||
|
@ -45,6 +45,8 @@ namespace libcron
|
|||||||
return clock;
|
return clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_time_until_expiry_for_tasks(std::vector<std::tuple<std::string, std::chrono::system_clock::duration>>& status) const;
|
||||||
|
|
||||||
friend std::ostream& operator<<<>(std::ostream& stream, const Cron<ClockType>& c);
|
friend std::ostream& operator<<<>(std::ostream& stream, const Cron<ClockType>& c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -78,7 +80,6 @@ namespace libcron
|
|||||||
bool res = cron.is_valid();
|
bool res = cron.is_valid();
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
|
|
||||||
Task t{std::move(name), CronSchedule{cron}, std::move(work)};
|
Task t{std::move(name), CronSchedule{cron}, std::move(work)};
|
||||||
if (t.calculate_next(clock.now()))
|
if (t.calculate_next(clock.now()))
|
||||||
{
|
{
|
||||||
@ -106,7 +107,7 @@ namespace libcron
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename ClockType>
|
template<typename ClockType>
|
||||||
size_t Cron<ClockType>::tick(system_clock::time_point now)
|
size_t Cron<ClockType>::tick(std::chrono::system_clock::time_point now)
|
||||||
{
|
{
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
|
|
||||||
@ -160,6 +161,19 @@ namespace libcron
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ClockType>
|
||||||
|
void Cron<ClockType>::get_time_until_expiry_for_tasks(std::vector<std::tuple<std::string, std::chrono::system_clock::duration>>& status) const
|
||||||
|
{
|
||||||
|
auto now = clock.now();
|
||||||
|
status.clear();
|
||||||
|
|
||||||
|
std::for_each(tasks.get_tasks().cbegin(), tasks.get_tasks().cend(),
|
||||||
|
[&status, &now](const Task& t)
|
||||||
|
{
|
||||||
|
status.emplace_back(t.get_name(), t.time_until_expiry(now));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ClockType>
|
template<typename ClockType>
|
||||||
std::ostream& operator<<(std::ostream& stream, const Cron<ClockType>& c)
|
std::ostream& operator<<(std::ostream& stream, const Cron<ClockType>& c)
|
||||||
{
|
{
|
||||||
|
39
libcron/CronClock.cpp
Normal file
39
libcron/CronClock.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "CronClock.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
|
namespace libcron
|
||||||
|
{
|
||||||
|
|
||||||
|
std::chrono::seconds LocalClock::utc_offset(std::chrono::system_clock::time_point now) const
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
(void)now;
|
||||||
|
|
||||||
|
TIME_ZONE_INFORMATION tz_info{};
|
||||||
|
seconds offset{ 0 };
|
||||||
|
|
||||||
|
auto res = GetTimeZoneInformation(&tz_info);
|
||||||
|
if (res != TIME_ZONE_ID_INVALID)
|
||||||
|
{
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
|
||||||
|
// UTC = local time + bias => local_time = utc - bias, so UTC offset is -bias
|
||||||
|
offset = minutes{ -tz_info.Bias };
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
auto t = system_clock::to_time_t(now);
|
||||||
|
tm tm{};
|
||||||
|
localtime_r(&t, &tm);
|
||||||
|
seconds offset{ tm.tm_gmtoff };
|
||||||
|
#endif
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
using namespace std::chrono;
|
|
||||||
using namespace date;
|
|
||||||
|
|
||||||
namespace libcron
|
namespace libcron
|
||||||
{
|
{
|
||||||
class ICronClock
|
class ICronClock
|
||||||
@ -25,6 +22,7 @@ namespace libcron
|
|||||||
|
|
||||||
std::chrono::seconds utc_offset(std::chrono::system_clock::time_point) const override
|
std::chrono::seconds utc_offset(std::chrono::system_clock::time_point) const override
|
||||||
{
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
return 0s;
|
return 0s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -35,20 +33,10 @@ namespace libcron
|
|||||||
public:
|
public:
|
||||||
std::chrono::system_clock::time_point now() const override
|
std::chrono::system_clock::time_point now() const override
|
||||||
{
|
{
|
||||||
auto now = system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
return now + utc_offset(now);
|
return now + utc_offset(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::seconds utc_offset(std::chrono::system_clock::time_point now) const override
|
std::chrono::seconds utc_offset(std::chrono::system_clock::time_point now) const override;
|
||||||
{
|
|
||||||
auto t = system_clock::to_time_t(now);
|
|
||||||
tm tm{};
|
|
||||||
#ifdef __WIN32
|
|
||||||
localtime_s(&tm, &t);
|
|
||||||
#else
|
|
||||||
localtime_r(&t, &tm);
|
|
||||||
#endif
|
|
||||||
return seconds{tm.tm_gmtoff};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#include "CronSchedule.h"
|
#include "CronSchedule.h"
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
using namespace date;
|
using namespace date;
|
||||||
|
@ -2,7 +2,12 @@ cmake_minimum_required(VERSION 3.6)
|
|||||||
project(cron_test)
|
project(cron_test)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Wextra")
|
|
||||||
|
if( MSVC )
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/externals/Catch2/single_include/
|
${CMAKE_CURRENT_LIST_DIR}/externals/Catch2/single_include/
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using namespace libcron;
|
using namespace libcron;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
using namespace date;
|
||||||
|
|
||||||
std::string create_schedule_expiring_in(std::chrono::system_clock::time_point now, hours h, minutes m, seconds s)
|
std::string create_schedule_expiring_in(std::chrono::system_clock::time_point now, hours h, minutes m, seconds s)
|
||||||
{
|
{
|
||||||
@ -221,7 +222,7 @@ class TestClock
|
|||||||
|
|
||||||
SCENARIO("Clock changes")
|
SCENARIO("Clock changes")
|
||||||
{
|
{
|
||||||
GIVEN("A Cron instance with a single task expiring in 4h")
|
GIVEN("A Cron instance with a single task expiring every hour")
|
||||||
{
|
{
|
||||||
Cron<TestClock> c{};
|
Cron<TestClock> c{};
|
||||||
auto& clock = c.get_clock();
|
auto& clock = c.get_clock();
|
||||||
@ -239,11 +240,11 @@ SCENARIO("Clock changes")
|
|||||||
|
|
||||||
WHEN("Clock changes <3h forward")
|
WHEN("Clock changes <3h forward")
|
||||||
{
|
{
|
||||||
THEN("Task expires accordingly")
|
THEN("Task expires accordingly")
|
||||||
{
|
{
|
||||||
REQUIRE(c.tick() == 1);
|
REQUIRE(c.tick() == 1);
|
||||||
clock.add(minutes{30}); // 00:30
|
clock.add(minutes{ 30 }); // 00:30
|
||||||
REQUIRE(c.tick() == 0);
|
REQUIRE(c.tick() == 0);
|
||||||
clock.add(minutes{30}); // 01:00
|
clock.add(minutes{30}); // 01:00
|
||||||
REQUIRE(c.tick() == 1);
|
REQUIRE(c.tick() == 1);
|
||||||
REQUIRE(c.tick() == 0);
|
REQUIRE(c.tick() == 0);
|
||||||
@ -294,6 +295,5 @@ SCENARIO("Clock changes")
|
|||||||
REQUIRE(c.tick() == 1);
|
REQUIRE(c.tick() == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user