Mercurial > minori
view src/core/time.cc @ 308:da2c5a8ff306
time: don't use time_t!
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Tue, 11 Jun 2024 04:24:19 -0400 |
parents | f4538a4c91ba |
children | d928ec7b6a0d |
line wrap: on
line source
#include "core/time.h" #include "core/strings.h" #include <cassert> #include <cmath> #include <cstdint> #include <ctime> #include <string> #include <QDateTime> namespace Time { static Timestamp GetSecondsInMinutes(Timestamp length) { return std::llround(static_cast<double>(length) / 60.0); } static Timestamp GetSecondsInHours(Timestamp length) { return std::llround(static_cast<double>(length) / 3600.0); } static Timestamp GetSecondsInDays(Timestamp length) { return std::llround(static_cast<double>(length) / 86400.0); } std::string GetSecondsAsRelativeString(Timestamp length) { std::string result; auto get = [](Timestamp val, const std::string& s, const std::string& p) { return Strings::ToUtf8String(val) + " " + (val == 1 ? s : p); }; if (length < 60) result = get(length, "second", "seconds"); else if (GetSecondsInMinutes(length) < 60) result = get(GetSecondsInMinutes(length), "minute", "minutes"); else if (GetSecondsInHours(length) < 24) result = get(GetSecondsInHours(length), "hour", "hours"); else if (GetSecondsInDays(length) < 28) result = get(GetSecondsInDays(length), "day", "days"); else if (GetSecondsInDays(length) < 365) result = get(GetSecondsInDays(length) / 30, "month", "months"); else result = get(GetSecondsInDays(length) / 365, "year", "years"); if (length < 0) result = "In " + result; else result += " ago"; return result; } /* "amount" does not have to be in seconds, and can be any unit if the correct ratio to seconds * is passed to "unit_in_seconds" (for example, if the input is minutes, pass 60.0) */ std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds) { /* avoid calculating this twice */ const double years_conv = (31556952.0 / unit_in_seconds); const double months_conv = (2629746.0 / unit_in_seconds); const double days_conv = (86400.0 / unit_in_seconds); const double hours_conv = (3600.0 / unit_in_seconds); const double minutes_conv = (60.0 / unit_in_seconds); const double seconds_conv = (1.0 / unit_in_seconds); const int years = amount / years_conv; const int months = std::fmod(amount, years_conv) / months_conv; const int days = std::fmod(amount, months_conv) / days_conv; const int hours = std::fmod(amount, days_conv) / hours_conv; const int minutes = std::fmod(amount, hours_conv) / minutes_conv; const int seconds = std::fmod(amount, minutes_conv) / seconds_conv; const auto add_time_segment = [](std::ostringstream& str, int64_t amount, const std::string_view& singular, const std::string_view& plural, bool always = false) { if (amount > 0 || always) str << amount << ((amount == 1) ? singular : plural); }; /* for now, this function is very en_US specific */ std::ostringstream string; add_time_segment(string, years, " year ", " years "); add_time_segment(string, months, " month ", " months "); add_time_segment(string, days, " day ", " days "); add_time_segment(string, hours, " hour ", " hours "); if (unit_cutoff == Units::Minutes) { add_time_segment(string, minutes, " minute", " minutes", true); return string.str(); } else { add_time_segment(string, minutes, " minute ", " minutes "); } add_time_segment(string, seconds, " second", " seconds", true); return string.str(); } Timestamp GetSystemTime() { return QDateTime::currentDateTime().toUTC().toSecsSinceEpoch(); } } // namespace Time