diff --git a/src/main.cpp b/src/main.cpp index af6bb8f..da947ea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,11 +5,14 @@ int main() { oro::Api oro_api("https://api.originsro.org", "RESTC_CPP", "Testing"); auto ping = oro_api.ping(); + std::cout << "date: " << ping.first.date << '\n'; std::cout << "rate limit: " << ping.first.rate_limit << '\n'; std::cout << "remaining: " << ping.first.rate_limit_remaining << '\n'; std::cout << "reset: " << ping.first.rate_limit_reset << '\n'; std::cout << "retry after: " << ping.first.retry_after << '\n'; std::cout << "server: " << ping.first.server << '\n'; + std::cout << "-----\n"; + std::cout << "timestamp: " << ping.second.generation_timestamp << '\n'; std::cout << "answer: " << ping.second.message << '\n'; std::cout << "version: " << ping.second.version << '\n'; return 0; diff --git a/src/meson.build b/src/meson.build index 5e51c11..87bbc8a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -9,6 +9,7 @@ executable(meson.project_name(), 'main.cpp', 'oro/datatypes.cpp', 'oro/api.cpp', + 'oro/dateconv.cpp', install: true, dependencies: [restc_cpp_dep], include_directories: date_incdir, diff --git a/src/oro/api.cpp b/src/oro/api.cpp index dce130d..6420d09 100644 --- a/src/oro/api.cpp +++ b/src/oro/api.cpp @@ -1,5 +1,6 @@ #include "api.hpp" #include "datatypes.hpp" +#include "dateconv.hpp" #include #include #include @@ -32,6 +33,9 @@ namespace { .Execute(); Header h; + if (auto val = reply->GetHeader("Date")) { + h.date = from_header_timestamp(*val); + } if (auto val = reply->GetHeader("X-RateLimit-Limit")) { h.rate_limit = std::stoi(*val); } diff --git a/src/oro/datatypes.cpp b/src/oro/datatypes.cpp index 1805630..d6da633 100644 --- a/src/oro/datatypes.cpp +++ b/src/oro/datatypes.cpp @@ -1,15 +1,18 @@ #include "datatypes.hpp" +#include "dateconv.hpp" #define HAS_UNCAUGHT_EXCEPTIONS 1 #include "date/date.h" -#include namespace oro { Timestamp& Timestamp::operator= (const std::string& str) { - std::istringstream iss(str); - - //date has this format: 2020-06-19T22:33:36.855672+00:00 - date::from_stream(iss, "%FT%T%Ez", ts); + ts = from_json_timestamp(str); return *this; } + + std::ostream& operator<<(std::ostream& os, const Timestamp& ts) { + using date::operator<<; + os << ts.ts; + return os; + } } //namespace oro diff --git a/src/oro/datatypes.hpp b/src/oro/datatypes.hpp index e976c4a..67d17ec 100644 --- a/src/oro/datatypes.hpp +++ b/src/oro/datatypes.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace oro { typedef std::chrono::time_point timestamp_t; @@ -12,4 +13,6 @@ namespace oro { timestamp_t ts; }; + + std::ostream& operator<< (std::ostream& os, const Timestamp& ts); } //namespace oro diff --git a/src/oro/dateconv.cpp b/src/oro/dateconv.cpp new file mode 100644 index 0000000..e384925 --- /dev/null +++ b/src/oro/dateconv.cpp @@ -0,0 +1,41 @@ +#include "dateconv.hpp" + +#define HAS_UNCAUGHT_EXCEPTIONS 1 +#include "date/date.h" + +#include +#include +#include + +namespace oro { +namespace { + struct LocaleDeleter { + void operator() (char* old_locale) { + std::setlocale(LC_TIME, old_locale); + } + }; + + Timestamp to_timestamp (const char* fmt, const std::string& str) { + std::istringstream iss(str); + Timestamp ts; + date::from_stream(iss, fmt, ts.ts); + return ts; + } + + typedef std::unique_ptr UniqueLocale; +} //unnamed namespace + +//For formatting modifiers see: +//https://howardhinnant.github.io/date/date.html#from_stream_formatting + +Timestamp from_json_timestamp (const std::string& str) { + //date has this format: 2020-06-19T22:33:36.855672+00:00 + return to_timestamp("%FT%T%Ez", str); +} + +Timestamp from_header_timestamp (const std::string& str) { + UniqueLocale loc(std::setlocale(LC_TIME, "POSIX")); + //date has this format: Fri, 19 Jun 2020 22:33:43 GMT + return to_timestamp("%a, %d %b %Y %T %Z", str); +} +} //namespace oro diff --git a/src/oro/dateconv.hpp b/src/oro/dateconv.hpp new file mode 100644 index 0000000..556740a --- /dev/null +++ b/src/oro/dateconv.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "datatypes.hpp" +#include + +namespace oro { +Timestamp from_json_timestamp (const std::string& str); +Timestamp from_header_timestamp (const std::string& str); +} //namespace oro