diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 1f97281f68ca67d9868d69f78fc744b5cbe0a765..1e0e2b78089ee9986c27cdbed8308de8d7a7ffaa 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -49,6 +49,7 @@ endif() set(VEREIGNLIB_SRC vereign/core/rand.cc vereign/core/string.cc + vereign/core/time.cc vereign/fs/util.cc vereign/fs/operations.cc vereign/fs/path.cc diff --git a/cpp/src/vereign/core/time.cc b/cpp/src/vereign/core/time.cc new file mode 100644 index 0000000000000000000000000000000000000000..33030082a682d2bc3091602a24d5e39c22da4b96 --- /dev/null +++ b/cpp/src/vereign/core/time.cc @@ -0,0 +1,73 @@ +#include <vereign/core/time.hh> + +namespace vereign::time { + +auto Epoch() -> boost::posix_time::ptime { + static const auto epoch = boost::posix_time::ptime{boost::gregorian::date{1970, 1, 1}}; + + return epoch; +} + +auto PosixTimeToTime(boost::posix_time::ptime t) -> time_t { + return time_t((t - Epoch()).total_seconds()); +} + +auto MakePosixTime( + int year, + int month, + int day, + int hours, + int minutes, + int seconds +) -> boost::posix_time::ptime { + using namespace boost::posix_time; + using namespace boost::gregorian; + + return ptime( + date{ + static_cast<date::year_type>(year), + static_cast<date::month_type>(month), + static_cast<date::day_type>(day) + }, + time_duration(hours, minutes, seconds) + ); +} + +auto MakeTimeUTC( + int year, + int month, + int day, + int hours, + int seconds, + int milliseconds +) -> time_t { + using namespace boost::posix_time; + using namespace boost::gregorian; + + return PosixTimeToTime( + ptime( + date{ + static_cast<date::year_type>(year), + static_cast<date::month_type>(month), + static_cast<date::day_type>(day) + }, + time_duration(hours, seconds, milliseconds) + ) + ); +} + +auto MakeTimeUTCFromString(const std::string& str) -> time_t { + using namespace boost::posix_time; + using namespace boost::gregorian; + + return PosixTimeToTime(boost::posix_time::time_from_string(str)); +} + +auto MakeTimeUTCFromISO(const std::string& str) -> time_t { + using namespace boost::posix_time; + using namespace boost::gregorian; + + return PosixTimeToTime(from_iso_string(str)); +} + +} // vereign::time diff --git a/cpp/src/vereign/core/time.hh b/cpp/src/vereign/core/time.hh index 120ddd8e0bc23b52c8d7cb3c994f8d2f78eac85b..5b7d775606d25a7c2ac264d543bbbdeac833088c 100644 --- a/cpp/src/vereign/core/time.hh +++ b/cpp/src/vereign/core/time.hh @@ -5,74 +5,68 @@ namespace vereign::time { -auto Epoch() -> boost::posix_time::ptime { - static const auto epoch = boost::posix_time::ptime{boost::gregorian::date{1970, 1, 1}}; +/** + * Returns the gregorian epoch boost posix time - 1970:01:01. + */ +auto Epoch() -> boost::posix_time::ptime; - return epoch; -} - -auto PosixTimeToTime(boost::posix_time::ptime t) -> time_t { - return time_t((t - Epoch()).total_seconds()); -} +/** + * Converts boost posix time to time_t timestamp. + * + * @param t The source boost posix time. + * @returns timestamp. + */ +auto PosixTimeToTime(boost::posix_time::ptime t) -> time_t; +/** + * Creates boost posix timetamp. + * + * @param year Year component. + * @param month Month component 1-12. + * @param day Day component 1-31. + * @param hours The hours component 0-23. + * @param minutes The minutes component 0-59. + * @param seconds The minutes component 0-59. + * @returns posix time. + */ auto MakePosixTime( int year, int month, int day, int hours, - int seconds, - int milliseconds -) -> boost::posix_time::ptime { - using namespace boost::posix_time; - using namespace boost::gregorian; - - return ptime( - date{ - static_cast<date::year_type>(year), - static_cast<date::month_type>(month), - static_cast<date::day_type>(day) - }, - time_duration(hours, seconds, milliseconds) - ); -} - -auto MakeTimeUTC( - int year, - int month, - int day, - int hours, - int seconds, - int milliseconds -) -> time_t { - using namespace boost::posix_time; - using namespace boost::gregorian; - - return PosixTimeToTime( - ptime( - date{ - static_cast<date::year_type>(year), - static_cast<date::month_type>(month), - static_cast<date::day_type>(day) - }, - time_duration(hours, seconds, milliseconds) - ) - ); -} - -auto MakeTimeUTCFromString(const std::string& str) -> time_t { - using namespace boost::posix_time; - using namespace boost::gregorian; + int minutes, + int seconds +) -> boost::posix_time::ptime; - return PosixTimeToTime(boost::posix_time::time_from_string(str)); -} +/** + * Creates UTC timestamp. + * + * @param year Year component. + * @param month Month component 1-12. + * @param day Day component 1-31. + * @param hours The hours component 0-23. + * @param minutes The minutes component 0-59. + * @param seconds The minutes component 0-59. + * @returns timestamp. + */ +auto MakeTimeUTC(int year, int month, int day, int hours, int seconds, int milliseconds) -> time_t; -auto MakeTimeUTCFromISO(const std::string& str) -> time_t { - using namespace boost::posix_time; - using namespace boost::gregorian; +/** + * Creates UTC timestamp from a string. + * + * @param str Time string representation, example: "2002-01-20 23:59:59.000". + * @returns timestamp. + */ +auto MakeTimeUTCFromString(const std::string& str) -> time_t; - return PosixTimeToTime(from_iso_string(str)); -} +/** + * Creates UTC timestamp from ISO formatted string. + * + * @param str Time string representation, example: "20020120T235959". + * @returns timestamp. + */ +auto MakeTimeUTCFromISO(const std::string& str) -> time_t; -} // vereign::string +} // vereign::time #endif // __VEREIGN_CORE_TIME_HH diff --git a/cpp/tests/vereign/CMakeLists.txt b/cpp/tests/vereign/CMakeLists.txt index 2633cbfc0b134d2361ac17e9c028ed75846edc50..b7c43c069858265bed7a23715e8832f9b4505105 100644 --- a/cpp/tests/vereign/CMakeLists.txt +++ b/cpp/tests/vereign/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND TESTS_SRC test/device.cc test/service_context.cc + core/time_test.cc sync/channel_test.cc encoding/base64_test.cc diff --git a/cpp/tests/vereign/core/time_test.cc b/cpp/tests/vereign/core/time_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..09637b9fb892cc8a86a27281587d003326c15642 --- /dev/null +++ b/cpp/tests/vereign/core/time_test.cc @@ -0,0 +1,42 @@ +#include <vereign/core/time.hh> + +#include <catch2/catch.hpp> + +using namespace vereign; + +TEST_CASE("time::MakePosixTime", "[vereign/time][vereign/core]") { + auto ptime = time::MakePosixTime(2020, 1, 1, 0, 1, 1); + + CHECK(ptime.date().year() == 2020); + CHECK(ptime.date().month() == boost::gregorian::Jan); + CHECK(ptime.date().day() == 1); + CHECK(ptime.time_of_day().hours() == 0); + CHECK(ptime.time_of_day().minutes() == 1); + CHECK(ptime.time_of_day().seconds() == 1); + + CHECK(time::PosixTimeToTime(ptime) == 1577836861); + CHECK(time::MakeTimeUTCFromISO("20200101T000101") == time::PosixTimeToTime(ptime)); + + ptime = time::MakePosixTime(2020, 1, 1, 24, 60, 60); + CHECK(boost::posix_time::to_iso_string(ptime) == "20200102T010100"); +} + +TEST_CASE("time::MakeTimeUTC", "[vereign/time][vereign/core]") { + auto timestamp = time::MakeTimeUTC(2020, 1, 1, 0, 1, 1); + + CHECK(timestamp == 1577836861); + CHECK(time::MakeTimeUTCFromISO("20200101T000101") == timestamp); +} + +TEST_CASE("time::MakeTimeUTCFromString", "[vereign/time][vereign/core]") { + auto timestamp = time::MakeTimeUTCFromString("2020-1-1 0:1:1"); + + CHECK(timestamp == 1577836861); + CHECK(time::MakeTimeUTCFromISO("20200101T000101") == timestamp); +} + +TEST_CASE("time::MakeTimeUTCFromISO", "[vereign/time][vereign/core]") { + auto timestamp = time::MakeTimeUTCFromISO("20200101T000101"); + + CHECK(timestamp == 1577836861); +}