diff --git a/src/parse_options.cpp b/src/parse_options.cpp index 6e7f048..b9ac81d 100644 --- a/src/parse_options.cpp +++ b/src/parse_options.cpp @@ -16,9 +16,6 @@ #include #include -#include -#include -#include #include #include "version.hpp" #include "parse_options.hpp" @@ -34,16 +31,6 @@ options::options(const uint8_t &status) : status_code(status) {} -const system_clock::time_point string_to_timepoint(const string &strtime) -{ - std::stringstream sstime(strtime); - struct std::tm tm = {}; - tm.tm_isdst = -1; // Detect daylight saving time. - sstime >> std::get_time(&tm, "%Y-%m-%dT%T"); - std::time_t time = timelocal(&tm); // Assume time is local. - return system_clock::from_time_t(time); -} - const options parse_options(const int argc, const char *argv[]) { string tags; diff --git a/src/parse_options.hpp b/src/parse_options.hpp index b00e2f1..9905c99 100644 --- a/src/parse_options.hpp +++ b/src/parse_options.hpp @@ -22,6 +22,7 @@ #include #include #include +#include "time.hpp" using std::string; using std::vector; @@ -49,9 +50,6 @@ typedef struct options explicit options(const uint8_t &status); } options; -// Convert ISO 8601 time-string to time_point. -const system_clock::time_point string_to_timepoint(const string &strtime); - // Parse command-line options. const options parse_options(const int argc, const char *argv[]); diff --git a/src/time.cpp b/src/time.cpp new file mode 100644 index 0000000..60c5d70 --- /dev/null +++ b/src/time.cpp @@ -0,0 +1,44 @@ +/* This file is part of remwharead. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include "time.hpp" + +const system_clock::time_point string_to_timepoint(const string &strtime) +{ + std::stringstream sstime(strtime); + struct std::tm tm = {}; + tm.tm_isdst = -1; // Detect daylight saving time. + sstime >> std::get_time(&tm, "%Y-%m-%dT%T"); + std::time_t time = timelocal(&tm); // Assume time is local. + return system_clock::from_time_t(time); +} + +const string timepoint_to_string(const system_clock::time_point &tp) +{ + constexpr std::uint16_t bufsize = 32; + std::time_t time = system_clock::to_time_t(tp); + std::tm *tm; + tm = std::localtime(&time); + + char buffer[bufsize]; + std::strftime(buffer, bufsize, "%FT%T", tm); + + return static_cast(buffer); +} diff --git a/src/time.hpp b/src/time.hpp new file mode 100644 index 0000000..d831f11 --- /dev/null +++ b/src/time.hpp @@ -0,0 +1,32 @@ +/* This file is part of remwharead. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef REMWHAREAD_TIME_HPP +#define REMWHAREAD_TIME_HPP + +#include +#include + +using std::string; +using std::chrono::system_clock; + +// Convert ISO 8601 time-string to time_point. +const system_clock::time_point string_to_timepoint(const string &strtime); + +// Convert time_point to USO 8601 time-string. +const string timepoint_to_string(const system_clock::time_point &tp); + +#endif // REMWHAREAD_TIME_HPP diff --git a/tests/test_parse_options.cpp b/tests/test_parse_options.cpp index b2dc129..7ebfd86 100644 --- a/tests/test_parse_options.cpp +++ b/tests/test_parse_options.cpp @@ -16,45 +16,13 @@ #include #include -#include #include #include #include "parse_options.hpp" using std::string; -using std::chrono::system_clock; -using std::chrono::seconds; using std::vector; -SCENARIO ("The time conversion works correctly") -{ - bool exception = false; - const string datetime = "1970-01-04T00:00:00"; - system_clock::time_point tp; - seconds seconds_since_epoch; - - GIVEN ("The date and time " + datetime) - { - try - { - tp = string_to_timepoint(datetime); - seconds_since_epoch = std::chrono::duration_cast - (tp.time_since_epoch()); - } - catch (const std::exception &e) - { - exception = true; - } - - THEN ("No exception is thrown") - AND_THEN ("Seconds since epoch is not 0") - { - REQUIRE_FALSE(exception); - REQUIRE(seconds_since_epoch != seconds(0)); - } - } -} - SCENARIO ("The option parser works correctly") { bool exception = false; diff --git a/tests/test_time.cpp b/tests/test_time.cpp new file mode 100644 index 0000000..d871658 --- /dev/null +++ b/tests/test_time.cpp @@ -0,0 +1,74 @@ +/* This file is part of remwharead. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include "time.hpp" + +using std::string; +using std::chrono::system_clock; +using std::chrono::seconds; + +SCENARIO ("The time conversion works correctly") +{ + bool exception = false; + const string datetime = "1970-01-04T00:00:00"; + system_clock::time_point tp; + seconds seconds_since_epoch; + + GIVEN ("The date and time " + datetime + " as string") + { + try + { + tp = string_to_timepoint(datetime); + seconds_since_epoch = std::chrono::duration_cast + (tp.time_since_epoch()); + } + catch (const std::exception &e) + { + exception = true; + } + + THEN ("No exception is thrown") + AND_THEN ("Seconds since epoch is not 0") + { + REQUIRE_FALSE(exception); + REQUIRE(seconds_since_epoch != seconds(0)); + } + + WHEN ("Converted back to string") + { + string datetime2; + try + { + datetime2 = timepoint_to_string(tp); + } + catch (const std::exception &e) + { + exception = true; + } + + THEN ("No exception is thrown") + AND_THEN ("Date and time is the same as the initial value") + { + REQUIRE_FALSE(exception); + REQUIRE(datetime2 == datetime); + } + } + } +}