summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2020-03-01 21:54:33 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2020-03-10 21:47:29 +0100
commit9076a13c78cf64a6afafe98817aed31feda568b1 (patch)
tree2ee915d7708d54035727f7cc3aebe8b10a113120 /src
parent240edf7494745dc4df2128644fe5c1a73ec2d513 (diff)
Date and time record item type
Diffstat (limited to 'src')
-rw-r--r--src/storage.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/storage.cpp b/src/storage.cpp
index e0819d4..525d83d 100644
--- a/src/storage.cpp
+++ b/src/storage.cpp
@@ -536,6 +536,34 @@ const Storage & Ref::storage() const
}
+ZonedTime::ZonedTime(string str)
+{
+ intmax_t t;
+ unsigned int h, m;
+ char sign[2];
+ if (sscanf(str.c_str(), "%jd %1[+-]%2u%2u", &t, sign, &h, &m) != 4)
+ throw runtime_error("invalid zoned time");
+
+ time = std::chrono::system_clock::time_point(std::chrono::seconds(t));
+ zone = std::chrono::minutes((sign[0] == '-' ? -1 : 1) * (60 * h + m));
+}
+
+ZonedTime::operator string() const
+{
+ char buf[32];
+ unsigned int az = std::chrono::abs(zone).count();
+ snprintf(buf, sizeof(buf), "%jd %c%02u%02u",
+ (intmax_t) std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count(),
+ zone < decltype(zone)::zero() ? '-' : '+', az / 60, az % 60);
+ return string(buf);
+}
+
+ZonedTime ZonedTime::now()
+{
+ return ZonedTime(std::chrono::system_clock::now());
+}
+
+
UUID::UUID(string str)
{
if (uuid_parse(str.c_str(), uuid) != 0)
@@ -591,6 +619,14 @@ optional<vector<uint8_t>> RecordT<S>::Item::asBinary() const
}
template<class S>
+optional<ZonedTime> RecordT<S>::Item::asDate() const
+{
+ if (holds_alternative<ZonedTime>(value))
+ return std::get<ZonedTime>(value);
+ return nullopt;
+}
+
+template<class S>
optional<UUID> RecordT<S>::Item::asUUID() const
{
if (holds_alternative<UUID>(value))
@@ -655,6 +691,8 @@ optional<RecordT<S>> RecordT<S>::decode(const S & st,
items->emplace_back(name, value);
else if (type == "b")
items->emplace_back(name, base64::decode(value));
+ else if (type == "d")
+ items->emplace_back(name, ZonedTime(value));
else if (type == "u")
items->emplace_back(name, UUID(value));
else if (type == "r.b2") {
@@ -736,6 +774,9 @@ vector<uint8_t> RecordT<S>::encodeInner() const
} else if (auto x = item.asBinary()) {
type = "b";
value = base64::encode(*x);
+ } else if (auto x = item.asDate()) {
+ type = "d";
+ value = string(*x);
} else if (auto x = item.asUUID()) {
type = "u";
value = string(*x);