Add ZonedDateType definition & helper structures
This commit is contained in:
parent
1e04831295
commit
0d4b057491
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Memgraph Ltd.
|
// Copyright 2024 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
namespace memgraph::utils {
|
namespace memgraph::utils {
|
||||||
|
|
||||||
|
class Timezone;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept Chrono = requires(T) {
|
concept Chrono = requires(T) {
|
||||||
typename T::rep;
|
typename T::rep;
|
||||||
@ -192,8 +194,13 @@ struct LocalTimeParameters {
|
|||||||
bool operator==(const LocalTimeParameters &) const = default;
|
bool operator==(const LocalTimeParameters &) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// boolean indicates whether the parsed string was in extended format
|
struct LocalTimeParsing {
|
||||||
std::pair<LocalTimeParameters, bool> ParseLocalTimeParameters(std::string_view string);
|
LocalTimeParameters parameters;
|
||||||
|
bool extended_format;
|
||||||
|
uint64_t remainder_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalTimeParsing ParseLocalTimeParameters(std::string_view string, bool in_zoned_dt = false);
|
||||||
|
|
||||||
struct LocalTime {
|
struct LocalTime {
|
||||||
explicit LocalTime() : LocalTime{LocalTimeParameters{}} {}
|
explicit LocalTime() : LocalTime{LocalTimeParameters{}} {}
|
||||||
@ -251,7 +258,13 @@ struct LocalTimeHash {
|
|||||||
size_t operator()(const LocalTime &local_time) const;
|
size_t operator()(const LocalTime &local_time) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::pair<DateParameters, LocalTimeParameters> ParseLocalDateTimeParameters(std::string_view string);
|
struct LocalDateTimeParsing {
|
||||||
|
DateParameters date_parameters;
|
||||||
|
LocalTimeParameters local_time_parameters;
|
||||||
|
uint64_t remainder_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalDateTimeParsing ParseLocalDateTimeParameters(std::string_view string, bool in_zoned_dt = false);
|
||||||
|
|
||||||
struct LocalDateTime {
|
struct LocalDateTime {
|
||||||
explicit LocalDateTime(int64_t microseconds);
|
explicit LocalDateTime(int64_t microseconds);
|
||||||
@ -294,6 +307,132 @@ struct LocalDateTimeHash {
|
|||||||
size_t operator()(const LocalDateTime &local_date_time) const;
|
size_t operator()(const LocalDateTime &local_date_time) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Timezone {
|
||||||
|
private:
|
||||||
|
std::variant<std::chrono::minutes, const std::chrono::time_zone *> offset_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Timezone(const std::chrono::minutes offset) : offset_{offset} {}
|
||||||
|
explicit Timezone(const std::chrono::time_zone *timezone) : offset_{timezone} {}
|
||||||
|
explicit Timezone(const std::string &timezone_name) : offset_{std::chrono::locate_zone(timezone_name)} {}
|
||||||
|
|
||||||
|
const Timezone *operator->() const { return this; }
|
||||||
|
|
||||||
|
bool operator==(const Timezone &) const = default;
|
||||||
|
|
||||||
|
template <class DurationT>
|
||||||
|
std::chrono::minutes OffsetInMinutes(std::chrono::sys_time<DurationT> time_point) const {
|
||||||
|
if (std::holds_alternative<std::chrono::minutes>(offset_)) {
|
||||||
|
return std::get<std::chrono::minutes>(offset_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::chrono::duration_cast<std::chrono::minutes>(
|
||||||
|
std::get<const std::chrono::time_zone *>(offset_)->get_info(time_point).offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class DurationT>
|
||||||
|
std::chrono::sys_info get_info(std::chrono::sys_time<DurationT> time_point) const {
|
||||||
|
if (std::holds_alternative<std::chrono::minutes>(offset_)) {
|
||||||
|
const auto offset = std::get<std::chrono::minutes>(offset_);
|
||||||
|
return std::chrono::sys_info{
|
||||||
|
.begin = std::chrono::sys_seconds::min(),
|
||||||
|
.end = std::chrono::sys_seconds::max(),
|
||||||
|
.offset = std::chrono::duration_cast<std::chrono::seconds>(offset),
|
||||||
|
.save = std::chrono::minutes{0},
|
||||||
|
.abbrev = "",
|
||||||
|
// offset >= std::chrono::minutes{0} ? "+" + std::format("{0:%H}:{0:%M}", offset)
|
||||||
|
// : "-" + std::format("{0:%H}:{0:%M}", -offset)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return std::get<const std::chrono::time_zone *>(offset_)->get_info(time_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class DurationT>
|
||||||
|
auto to_local(std::chrono::sys_time<DurationT> time_point) const {
|
||||||
|
if (std::holds_alternative<std::chrono::minutes>(offset_)) {
|
||||||
|
using local_time = std::chrono::local_time<std::common_type_t<DurationT, std::chrono::minutes>>;
|
||||||
|
return local_time{(time_point + OffsetInMinutes(time_point)).time_since_epoch()};
|
||||||
|
}
|
||||||
|
return std::get<const std::chrono::time_zone *>(offset_)->to_local(time_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class DurationT>
|
||||||
|
auto to_sys(std::chrono::local_time<DurationT> time_point) const {
|
||||||
|
if (std::holds_alternative<std::chrono::minutes>(offset_)) {
|
||||||
|
using sys_time = std::chrono::sys_time<std::common_type_t<DurationT, std::chrono::minutes>>;
|
||||||
|
return sys_time{(time_point - std::get<std::chrono::minutes>(offset_)).time_since_epoch()};
|
||||||
|
}
|
||||||
|
return std::get<const std::chrono::time_zone *>(offset_)->to_sys(time_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view TimezoneName() const {
|
||||||
|
if (std::holds_alternative<std::chrono::minutes>(offset_)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return std::get<const std::chrono::time_zone *>(offset_)->name();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace memgraph::utils
|
||||||
|
|
||||||
|
namespace std::chrono {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct zoned_traits<memgraph::utils::Timezone> {
|
||||||
|
static memgraph::utils::Timezone default_zone() { return memgraph::utils::Timezone{minutes{0}}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std::chrono
|
||||||
|
|
||||||
|
namespace memgraph::utils {
|
||||||
|
|
||||||
|
struct ZonedDateTimeParameters {
|
||||||
|
DateParameters date;
|
||||||
|
LocalTimeParameters local_time;
|
||||||
|
Timezone timezone;
|
||||||
|
|
||||||
|
bool operator==(const ZonedDateTimeParameters &) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
ZonedDateTimeParameters ParseZonedDateTimeParameters(std::string_view string);
|
||||||
|
|
||||||
|
struct ZonedDateTime {
|
||||||
|
explicit ZonedDateTime(const ZonedDateTimeParameters &zoned_date_time_parameters);
|
||||||
|
explicit ZonedDateTime(const ZonedDateTime &zoned_date_time);
|
||||||
|
explicit ZonedDateTime(const std::chrono::zoned_time<std::chrono::microseconds, Timezone> &zoned_time);
|
||||||
|
|
||||||
|
int64_t MicrosecondsSinceEpoch() const;
|
||||||
|
int64_t SecondsSinceEpoch() const;
|
||||||
|
int64_t SubSecondsAsNanoseconds() const;
|
||||||
|
std::string ToString() const;
|
||||||
|
|
||||||
|
bool operator==(const ZonedDateTime &other) const;
|
||||||
|
|
||||||
|
std::strong_ordering operator<=>(const ZonedDateTime &other) const;
|
||||||
|
|
||||||
|
std::chrono::minutes OffsetInMinutes() const {
|
||||||
|
return zoned_time.get_time_zone().OffsetInMinutes(zoned_time.get_sys_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view TimezoneName() const { return zoned_time.get_time_zone().TimezoneName(); }
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &os, const ZonedDateTime &zdt) { return os << zdt.ToString(); }
|
||||||
|
|
||||||
|
friend ZonedDateTime operator+(const ZonedDateTime &zdt, const Duration &dur) {
|
||||||
|
return ZonedDateTime(std::chrono::zoned_time(
|
||||||
|
zdt.zoned_time.get_time_zone(), zdt.zoned_time.get_sys_time() + std::chrono::microseconds(dur.microseconds)));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend ZonedDateTime operator+(const Duration &dur, const ZonedDateTime &zdt) { return zdt + dur; }
|
||||||
|
|
||||||
|
friend ZonedDateTime operator-(const ZonedDateTime &zdt, const Duration &dur) { return zdt + (-dur); }
|
||||||
|
|
||||||
|
friend Duration operator-(const ZonedDateTime &lhs, const ZonedDateTime &rhs) {
|
||||||
|
return Duration(lhs.MicrosecondsSinceEpoch()) - Duration(rhs.MicrosecondsSinceEpoch());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::zoned_time<std::chrono::microseconds, Timezone> zoned_time;
|
||||||
|
};
|
||||||
|
|
||||||
Date CurrentDate();
|
Date CurrentDate();
|
||||||
LocalTime CurrentLocalTime();
|
LocalTime CurrentLocalTime();
|
||||||
LocalDateTime CurrentLocalDateTime();
|
LocalDateTime CurrentLocalDateTime();
|
||||||
|
Loading…
Reference in New Issue
Block a user