summaryrefslogtreecommitdiffstats
path: root/src/base/time_util.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 04:48:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 04:48:35 +0000
commit207df6fc406e81bfeebdff7f404bd242ff3f099f (patch)
treea1a796b056909dd0a04ffec163db9363a8757808 /src/base/time_util.cc
parentReleasing progress-linux version 0.11.2-1~progress7.99u1. (diff)
downloadlnav-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.cc116
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);
+}