Mercurial > minori
view src/core/time.cc @ 327:b5d6c27c308f
anime: refactor Anime::SeriesSeason to Season class
ToLocalString has also been altered to take in both season
and year because lots of locales actually treat formatting
seasons differently! most notably is Russian which adds a
suffix at the end to notate seasons(??)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Thu, 13 Jun 2024 01:49:18 -0400 |
parents | d928ec7b6a0d |
children |
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(); } Timestamp ParseISO8601Time(const std::string& str) { return QDateTime::fromString(Strings::ToQString(str), Qt::ISODateWithMs).toUTC().toSecsSinceEpoch(); } } // namespace Time