Added UTC handling for Windows

This commit is contained in:
Per Malmberg 2018-03-22 22:38:55 +01:00
parent 5395c75061
commit c441da4287
7 changed files with 80 additions and 27 deletions

View File

@ -2,7 +2,12 @@ cmake_minimum_required(VERSION 3.6)
project(libcron)
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)
@ -16,7 +21,8 @@ add_library(${PROJECT_NAME}
CronSchedule.h
DateTime.h
Task.cpp
CronClock.h)
CronClock.h
CronClock.cpp)
set_target_properties(${PROJECT_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_LOCATION}"

View File

@ -45,6 +45,8 @@ namespace libcron
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);
private:
@ -78,7 +80,6 @@ namespace libcron
bool res = cron.is_valid();
if (res)
{
Task t{std::move(name), CronSchedule{cron}, std::move(work)};
if (t.calculate_next(clock.now()))
{
@ -106,7 +107,7 @@ namespace libcron
}
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;
@ -160,6 +161,19 @@ namespace libcron
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>
std::ostream& operator<<(std::ostream& stream, const Cron<ClockType>& c)
{

39
libcron/CronClock.cpp Normal file
View 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;
}
}

View File

@ -2,9 +2,6 @@
#include <chrono>
using namespace std::chrono;
using namespace date;
namespace libcron
{
class ICronClock
@ -25,6 +22,7 @@ namespace libcron
std::chrono::seconds utc_offset(std::chrono::system_clock::time_point) const override
{
using namespace std::chrono;
return 0s;
}
};
@ -35,20 +33,10 @@ namespace libcron
public:
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);
}
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};
}
std::chrono::seconds utc_offset(std::chrono::system_clock::time_point now) const override;
};
}

View File

@ -1,4 +1,5 @@
#include "CronSchedule.h"
#include <tuple>
using namespace std::chrono;
using namespace date;

View File

@ -2,7 +2,12 @@ cmake_minimum_required(VERSION 3.6)
project(cron_test)
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(
${CMAKE_CURRENT_LIST_DIR}/externals/Catch2/single_include/

View File

@ -5,6 +5,7 @@
using namespace libcron;
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)
{
@ -221,7 +222,7 @@ class TestClock
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{};
auto& clock = c.get_clock();
@ -242,7 +243,7 @@ SCENARIO("Clock changes")
THEN("Task expires accordingly")
{
REQUIRE(c.tick() == 1);
clock.add(minutes{30}); // 00:30
clock.add(minutes{ 30 }); // 00:30
REQUIRE(c.tick() == 0);
clock.add(minutes{30}); // 01:00
REQUIRE(c.tick() == 1);
@ -294,6 +295,5 @@ SCENARIO("Clock changes")
REQUIRE(c.tick() == 1);
}
}
}
}