From 83788f38856fb0a937d07b529cce2cd9eb62cd02 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 31 Jul 2019 15:23:50 +0200 Subject: [PATCH] Added SimpleWeb::Date::to_string to create HTTP date strings --- .clang-format | 1 + tests/parse_test.cpp | 2 ++ utility.hpp | 66 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/.clang-format b/.clang-format index 50f9423..740ccf7 100644 --- a/.clang-format +++ b/.clang-format @@ -7,3 +7,4 @@ SpaceBeforeParens: Never BreakBeforeBraces: Custom BraceWrapping: {BeforeElse: true, BeforeCatch: true} NamespaceIndentation: All +AllowShortCaseLabelsOnASingleLine: true diff --git a/tests/parse_test.cpp b/tests/parse_test.cpp index e739a59..8d7abcd 100644 --- a/tests/parse_test.cpp +++ b/tests/parse_test.cpp @@ -323,4 +323,6 @@ int main() { } } } + + ASSERT(SimpleWeb::Date::to_string(std::chrono::system_clock::now()).size() == 29); } diff --git a/utility.hpp b/utility.hpp index 5b3318d..846716b 100644 --- a/utility.hpp +++ b/utility.hpp @@ -3,7 +3,9 @@ #include "status_code.hpp" #include +#include #include +#include #include #include #include @@ -313,6 +315,70 @@ namespace SimpleWeb { return true; } }; + + /// Date class working with formats specified in RFC 7231 Date/Time Formats + class Date { + public: + /// Returns the given std::chrono::system_clock::time_point as a string with the following format: Wed, 31 Jul 2019 11:34:23 GMT. + /// Warning: this function uses std::gmtime and is thus not thread safe. + static std::string to_string(const std::chrono::system_clock::time_point time_point) noexcept { + std::string result; + result.reserve(29); + + auto time = std::chrono::system_clock::to_time_t(time_point); + auto gmtime = std::gmtime(&time); + + switch(gmtime->tm_wday) { + case 0: result += "Sun, "; break; + case 1: result += "Mon, "; break; + case 2: result += "Tue, "; break; + case 3: result += "Wed, "; break; + case 4: result += "Thu, "; break; + case 5: result += "Fri, "; break; + case 6: result += "Sat, "; break; + } + + result += gmtime->tm_mday < 10 ? '0' : static_cast(gmtime->tm_mday / 10 + 48); + result += static_cast(gmtime->tm_mday % 10 + 48); + + switch(gmtime->tm_mon) { + case 0: result += " Jan "; break; + case 1: result += " Feb "; break; + case 2: result += " Mar "; break; + case 3: result += " Apr "; break; + case 4: result += " May "; break; + case 5: result += " Jun "; break; + case 6: result += " Jul "; break; + case 7: result += " Aug "; break; + case 8: result += " Sep "; break; + case 9: result += " Oct "; break; + case 10: result += " Nov "; break; + case 11: result += " Des "; break; + } + + auto year = gmtime->tm_year + 1900; + result += static_cast(year / 1000 + 48); + result += static_cast((year / 100) % 10 + 48); + result += static_cast((year / 10) % 10 + 48); + result += static_cast(year % 10 + 48); + result += ' '; + + result += gmtime->tm_hour < 10 ? '0' : static_cast(gmtime->tm_hour / 10 + 48); + result += static_cast(gmtime->tm_hour % 10 + 48); + result += ':'; + + result += gmtime->tm_min < 10 ? '0' : static_cast(gmtime->tm_min / 10 + 48); + result += static_cast(gmtime->tm_min % 10 + 48); + result += ':'; + + result += gmtime->tm_sec < 10 ? '0' : static_cast(gmtime->tm_sec / 10 + 48); + result += static_cast(gmtime->tm_sec % 10 + 48); + + result += " GMT"; + + return result; + } + }; } // namespace SimpleWeb #ifdef __SSE2__