#include "clock_model.h" #include #include #include namespace roro { bool ClockModel::set(int64_t utcSeconds, TimeSource source, uint32_t nowMs) { if (source < source_) return false; source_ = source; utcAtSet_ = utcSeconds; msAtSet_ = nowMs; return true; } int64_t ClockModel::utcNow(uint32_t nowMs) const { // Unsigned subtraction handles the millis() wraparound. Uptime beyond 49 days between two // sets would lose 49 days; sources refresh far more often than that. return utcAtSet_ + static_cast(static_cast(nowMs - msAtSet_) / 1000); } void ClockModel::applyTimezone(const char* posixTz) { setenv("TZ", posixTz, 1); tzset(); } std::string ClockModel::formatLocalTime(int64_t utcSeconds) { time_t t = static_cast(utcSeconds); struct tm local; localtime_r(&t, &local); char buf[8]; std::snprintf(buf, sizeof(buf), "%02d:%02d", local.tm_hour, local.tm_min); return buf; } std::string ClockModel::formatLocalDate(int64_t utcSeconds) { time_t t = static_cast(utcSeconds); struct tm local; localtime_r(&t, &local); char buf[12]; std::snprintf(buf, sizeof(buf), "%04d-%02d-%02d", local.tm_year + 1900, local.tm_mon + 1, local.tm_mday); return buf; } std::string ClockModel::formatAge(int64_t seconds) { char buf[24]; if (seconds < 60) return "now"; if (seconds < 3600) std::snprintf(buf, sizeof(buf), "%d min ago", static_cast(seconds / 60)); else if (seconds < 86400) std::snprintf(buf, sizeof(buf), "%d h ago", static_cast(seconds / 3600)); else std::snprintf(buf, sizeof(buf), "%d d ago", static_cast(seconds / 86400)); return buf; } } // namespace roro