#include #include namespace ranczo::date { std::optional< std::chrono::system_clock::time_point > parse_timestamp_utc(std::string_view sv) noexcept { try { // Strip trailing 'Z' if present; Boost expects no timezone marker std::string s(sv); if(!s.empty() && (s.back() == 'Z' || s.back() == 'z')) s.pop_back(); // Parse as extended ISO string using namespace boost::posix_time; ptime t = from_iso_extended_string(s); // may throw on invalid static const ptime epoch{boost::gregorian::date{1970, 1, 1}}; time_duration d = t - epoch; // Keep sub-second precision if present (microseconds is enough for the given example) auto us = d.total_microseconds(); return std::chrono::system_clock::time_point{std::chrono::microseconds{us}}; } catch(...) { return std::nullopt; } } std::pmr::string to_iso_timestamp(std::chrono::system_clock::time_point tp, std::pmr::memory_resource *mr) { BOOST_ASSERT(mr); char buf[32]={}; std::time_t t = std::chrono::system_clock::to_time_t(tp); std::tm tm = *std::gmtime(&t); std::strftime(buf, sizeof(buf), "%FT%TZ", &tm); return {buf, mr}; } } // namespace ranczo::date