diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 04:48:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 04:48:35 +0000 |
commit | 207df6fc406e81bfeebdff7f404bd242ff3f099f (patch) | |
tree | a1a796b056909dd0a04ffec163db9363a8757808 /src/base/time_util.cc | |
parent | Releasing progress-linux version 0.11.2-1~progress7.99u1. (diff) | |
download | lnav-207df6fc406e81bfeebdff7f404bd242ff3f099f.tar.xz lnav-207df6fc406e81bfeebdff7f404bd242ff3f099f.zip |
Merging upstream version 0.12.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/base/time_util.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/base/time_util.cc b/src/base/time_util.cc index 0d46107..5aee017 100644 --- a/src/base/time_util.cc +++ b/src/base/time_util.cc @@ -30,10 +30,15 @@ */ #include <chrono> +#include <map> #include "time_util.hh" +#include <date/ptz.h> + #include "config.h" +#include "lnav_log.hh" +#include "optional.hpp" namespace lnav { @@ -75,8 +80,66 @@ strftime_rfc3339( return index; } +static nonstd::optional<Posix::time_zone> +get_posix_zone(const char* name) +{ + if (name == nullptr) { + return nonstd::nullopt; + } + + try { + return date::zoned_traits<Posix::time_zone>::locate_zone(name); + } catch (const std::runtime_error& e) { + log_error("invalid TZ value: %s -- %s", name, e.what()); + return nonstd::nullopt; + } +} + +static const date::time_zone* +get_date_zone(const char* name) +{ + if (name == nullptr) { + return date::current_zone(); + } + + try { + return date::locate_zone(name); + } catch (const std::runtime_error& e) { + log_error("invalid TZ value: %s -- %s", name, e.what()); + return date::current_zone(); + } +} + +date::sys_seconds +to_sys_time(date::local_seconds secs) +{ + static const auto* TZ = getenv("TZ"); + static const auto TZ_POSIX_ZONE = get_posix_zone(TZ); + static const auto* TZ_DATE_ZONE = get_date_zone(TZ); + + if (TZ_POSIX_ZONE) { + return TZ_POSIX_ZONE.value().to_sys(secs); + } + + return TZ_DATE_ZONE->to_sys(secs); +} + +date::local_seconds +to_local_time(date::sys_seconds secs) +{ + static const auto* TZ = getenv("TZ"); + static const auto TZ_POSIX_ZONE = get_posix_zone(TZ); + static const auto* TZ_DATE_ZONE = get_date_zone(TZ); + + if (TZ_POSIX_ZONE) { + return TZ_POSIX_ZONE.value().to_local(secs); + } + + return TZ_DATE_ZONE->to_local(secs); } +} // namespace lnav + static time_t BAD_DATE = -1; time_t @@ -225,15 +288,68 @@ secs2tm(lnav::time64_t tim, struct tm* res) return (res); } +exttm +exttm::from_tv(const timeval& tv) +{ + auto retval = exttm{}; + + retval.et_tm = *gmtime(&tv.tv_sec); + retval.et_nsec = tv.tv_usec * 1000; + + return retval; +} + struct timeval exttm::to_timeval() const { struct timeval retval; retval.tv_sec = tm2sec(&this->et_tm); + retval.tv_sec -= this->et_gmtoff; retval.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>( std::chrono::nanoseconds(this->et_nsec)) .count(); return retval; } + +time_range& +time_range::operator|=(const time_range& rhs) +{ + if (rhs.tr_begin < this->tr_begin) { + this->tr_begin = rhs.tr_begin; + } + if (this->tr_end < rhs.tr_end) { + this->tr_end = rhs.tr_end; + } + + return *this; +} + +void +time_range::extend_to(const timeval& tv) +{ + if (tv < this->tr_begin) { + // logs aren't always in time-order + this->tr_begin = tv; + } else if (this->tr_end < tv) { + this->tr_end = tv; + } +} + +std::chrono::milliseconds +time_range::duration() const +{ + auto diff = this->tr_end - this->tr_begin; + + return std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::seconds(diff.tv_sec)) + + std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::microseconds(diff.tv_usec)); +} + +bool +time_range::contains_inclusive(const timeval& tv) const +{ + return (this->tr_begin <= tv) && (tv <= this->tr_end); +} |