boat
C++23 geospatial library
Loading...
Searching...
No Matches
time_point.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef BOAT_DB_ADAPTED_TIME_POINT_HPP
4#define BOAT_DB_ADAPTED_TIME_POINT_HPP
5
6#include <boat/db/variant.hpp>
7#include <boat/detail/string.hpp>
8#include <chrono>
9#include <regex>
10
11namespace boat::db {
12
15template <class Clock, class Duration>
16void read(variant const& in, std::chrono::time_point<Clock, Duration>& out)
17{
18 if (!in.has_value()) {
19 out = {};
20 return;
21 }
22 // std::chrono::parse("%F %T", out)
23 namespace sc = std::chrono;
24 static auto const regex = std::regex{
25 R"(^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(\.(\d+))?$)"};
26 auto& str = std::get<std::string>(in);
27 auto m = std::cmatch{};
28 check(std::regex_match(str.data(), str.data() + str.size(), m, regex), str);
29 auto ymd = sc::year_month_day(
30 sc::year(from_chars<int>(m[1].first, m[1].length())),
31 sc::month(from_chars<int>(m[2].first, m[2].length())),
32 sc::day(from_chars<int>(m[3].first, m[3].length())));
33 auto h = from_chars<int>(m[4].first, m[4].length());
34 auto min = from_chars<int>(m[5].first, m[5].length());
35 auto s = from_chars<int>(m[6].first, m[6].length());
36 auto fraction = m[8].str();
37 fraction.resize(6, '0');
38 auto us = from_chars<int>(fraction.data(), fraction.size());
39 check(ymd.ok() && h < 24 && min < 60 && s < 60, str.data());
40 out = sc::time_point_cast<Duration>(
41 sc::time_point<Clock, sc::microseconds>{
42 sc::duration_cast<sc::microseconds>(
43 sc::sys_days(ymd).time_since_epoch())} +
44 sc::hours{h} + sc::minutes{min} + sc::seconds{s} +
45 sc::microseconds{us});
46}
47
49template <class Clock, class Duration>
50void write(variant& out, std::chrono::time_point<Clock, Duration> in)
51{
52 // std::format("{:L%F %T}", in)
53 namespace sc = std::chrono;
54 auto epoch = in.time_since_epoch();
55 auto days = sc::floor<sc::days>(epoch);
56 auto ymd = sc::year_month_day{sc::sys_days(days)};
57 auto hms = sc::hh_mm_ss{sc::duration_cast<sc::microseconds>(epoch - days)};
58 auto os = std::ostringstream{};
59 os.imbue(std::locale::classic());
60 os << std::setfill('0') << std::setw(4) << static_cast<int>(ymd.year())
61 << "-" << std::setw(2) << static_cast<unsigned>(ymd.month()) << "-"
62 << std::setw(2) << static_cast<unsigned>(ymd.day()) << " " << hms;
63 auto& str = out.emplace<std::string>(std::move(os).str());
64 str.erase(str.find_last_not_of('0') + 1);
65 if (str.ends_with('.'))
66 str.pop_back();
67}
68
69template <specialized<std::chrono::time_point> T>
70struct kind<T> {
71 static constexpr auto value = "timestamp";
72};
73
74} // namespace boat::db
75
76#endif // BOAT_DB_ADAPTED_TIME_POINT_HPP
Definition geometry.hpp:9
void write(variant &out, geometry::ogc99 auto const &in)
Serializes an OGC geometry as WKB in a blob.
Definition geometry.hpp:21
void read(variant const &in, geometry::ogc99 auto &out)
Reads WKB from a blob; NULL produces a default-constructed geometry.
Definition geometry.hpp:12
Definition variant.hpp:14
bool has_value() const
Definition variant.hpp:18