From f314da6eda14cb75ef2b2b2fb1f49e350a35a122 Mon Sep 17 00:00:00 2001 From: mateusz Date: Tue, 18 Feb 2020 14:59:47 +0100 Subject: [PATCH] change names to reflect function, add separate Time/Date --- .../widgets/CalllogItem.cpp | 2 +- .../windows/CallLogDetailsWindow.cpp | 8 +- .../widgets/ThreadItem.cpp | 5 +- .../windows/ThreadViewWindow.cpp | 2 +- module-gui/gui/widgets/TopBar.cpp | 6 +- .../service-cellular/ServiceCellular.cpp | 4 +- module-utils/time/README.md | 34 ++++--- module-utils/time/time_conversion.cpp | 98 ++++++++++++++----- module-utils/time/time_conversion.hpp | 50 +++++++--- module-utils/time/time_locale.hpp | 9 +- 10 files changed, 151 insertions(+), 67 deletions(-) diff --git a/module-apps/application-calllog/widgets/CalllogItem.cpp b/module-apps/application-calllog/widgets/CalllogItem.cpp index f75025914..0472539d0 100644 --- a/module-apps/application-calllog/widgets/CalllogItem.cpp +++ b/module-apps/application-calllog/widgets/CalllogItem.cpp @@ -97,7 +97,7 @@ void CalllogItem::setCall( std::shared_ptr& call ) { imageCallType[static_cast(callType)]->setVisible(true); - timestamp->setText( utils::time::SysTime(call->date, false)); // TODO: alek: check for AM/PM and 24h + timestamp->setText(utils::time::DateTime(call->date, false)); // TODO: alek: check for AM/PM and 24h } } /* namespace gui */ diff --git a/module-apps/application-calllog/windows/CallLogDetailsWindow.cpp b/module-apps/application-calllog/windows/CallLogDetailsWindow.cpp index b9b1a1599..994b7836a 100644 --- a/module-apps/application-calllog/windows/CallLogDetailsWindow.cpp +++ b/module-apps/application-calllog/windows/CallLogDetailsWindow.cpp @@ -238,11 +238,11 @@ void CallLogDetailsWindow::onBeforeShow( ShowMode mode, SwitchData* data ) { } typeData->setText(callTypeStr); - durationData->setText(utils::time::Time(record.duration).str("%Mm %Ss")); // TODO: alek: add duration class + durationData->setText(utils::time::Timestamp(record.duration).str("%Mm %Ss")); // TODO: alek: add duration class - utils::time::Time t(record.date); - dateDay->setText(t.day()+","); - dateDate->setText(t.str(utils::localize.get("locale_date_full") + ", " + utils::localize.get("locale_12hour_min"))); // TODO: alek 12/24 h + utils::time::Timestamp t(record.date); + dateDay->setText(t.day() + ","); + dateDate->setText(t.str(utils::localize.get("locale_date_full") + ", " + utils::localize.get("locale_12hour_min"))); // TODO: alek 12/24 h } if( mode == ShowMode::GUI_SHOW_INIT) setFocusItem( rects[static_cast(FocusRects::Call)] ); diff --git a/module-apps/application-messages/widgets/ThreadItem.cpp b/module-apps/application-messages/widgets/ThreadItem.cpp index 46e75aecf..c4ac4c53f 100644 --- a/module-apps/application-messages/widgets/ThreadItem.cpp +++ b/module-apps/application-messages/widgets/ThreadItem.cpp @@ -86,10 +86,9 @@ void ThreadItem::setThreadItem(std::shared_ptr &thread) { contact->setText(cont.primaryName + " " + cont.alternativeName); } - timestamp->setText(utils::time::SysTime(thread->date)); - - preview->setText(thread->snippet); + timestamp->setText(utils::time::DateTime(thread->date)); + preview->setText(thread->snippet); } } /*namespace gui*/ diff --git a/module-apps/application-messages/windows/ThreadViewWindow.cpp b/module-apps/application-messages/windows/ThreadViewWindow.cpp index 675e8b15e..f649101b0 100644 --- a/module-apps/application-messages/windows/ThreadViewWindow.cpp +++ b/module-apps/application-messages/windows/ThreadViewWindow.cpp @@ -102,7 +102,7 @@ namespace gui record.number = title->getText(); record.body = text->getText(); record.type = SMSType::QUEUED; - auto time = utils::time::Time(); + auto time = utils::time::Timestamp(); record.date = time.getTime(); DBServiceAPI::SMSAdd(this->application, record); diff --git a/module-gui/gui/widgets/TopBar.cpp b/module-gui/gui/widgets/TopBar.cpp index 51ba5775b..6c8200f45 100644 --- a/module-gui/gui/widgets/TopBar.cpp +++ b/module-gui/gui/widgets/TopBar.cpp @@ -233,10 +233,10 @@ void TopBar::setTime( const UTF8& time ) { void TopBar::setTime( const uint32_t& time, bool mode24H ) { std::time_t t= time; - setTime(utils::time::SysTime()); + setTime(utils::time::DateTime()); - timeMode = (mode24H?TimeMode::TIME_24H:TimeMode::TIME_12H); - this->time = time; + timeMode = (mode24H ? TimeMode::TIME_24H : TimeMode::TIME_12H); + this->time = time; } UTF8 TopBar::getTimeString() { diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index c86e3cefe..1a56d40e5 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -731,8 +731,8 @@ bool ServiceCellular::receiveSMS(std::string messageNumber) { //parse date tokens[3].erase(std::remove(tokens[3].begin(), tokens[3].end(), '\"'), tokens[3].end()); - utils::time::Time time; - time.set_time(tokens[3] + " " + tokens[4], "%y/%m/%d %H:%M:%S"); + utils::time::Timestamp time; + time.set_time(tokens[3] + " " + tokens[4], "%y/%m/%d %H:%M:%S"); auto messageDate = time.getTime(); //if its single message process diff --git a/module-utils/time/README.md b/module-utils/time/README.md index d8539de28..a66227281 100644 --- a/module-utils/time/README.md +++ b/module-utils/time/README.md @@ -8,23 +8,31 @@ Time conversion utility # How? -There is C-Locale builtin, therefore to convert time when it's possible it's used. +There is C-Locale builtin, therefore it's used to convert time whenever possible. When it's not -> specifiers are substituted with our locale (i18 map) ``` - +--------+ +--------+ - | Time | <=> | Locale | - +--------+ +--------+ - * - | - +-----------+ - | SysTime | - +-----------+ + +------------+ +--------+ + | Timestamp | <=> | Locale | + +------------+ +--------+ + * + | + +------------+ + | DateTime | + +------------+ + * * + / \ + / \ + +------+ +------+ + | Time | | Date | + +------+ +------+ + ``` -Locale - ( utils::time::Locale) class for i18n Time internationalization management -Time - generall class for Time transformations -SysTime - class for most of possible usecases, initialized with system clock, can return time string in reference to past - +Locale - (`utils::time::Locale`) class for i18n Timestamp internationalization management +Timestamp - general class to store time data. Init with a EPOCH timestamp. Has input and output formatters. +DateTime - class for most of possible usecases, initialized with system clock, can return time/date string in reference to past +Date - just a subclass with a default formatter returning the date in particular +Time - just a subclass with a default formatter returning the time, regardless of the date (today/yesterday/5 days ago) For more see headers diff --git a/module-utils/time/time_conversion.cpp b/module-utils/time/time_conversion.cpp index 2610ad24b..c4740d167 100644 --- a/module-utils/time/time_conversion.cpp +++ b/module-utils/time/time_conversion.cpp @@ -42,8 +42,7 @@ UTF8 Localer::get_replacement(Replacements val, const struct tm &timeinfo) return retval; } - -void Time::replace_specifiers() +void Timestamp::replace_specifiers() { int replacements_n = 0; const int strtof_formatter_size = 2; @@ -70,13 +69,13 @@ void Time::replace_specifiers() } } - void Time::set_time(time_t newtime) + void Timestamp::set_time(time_t newtime) { time = newtime; timeinfo = *localtime(&time); } - void Time::set_time(std::string timestr, const char *format) + void Timestamp::set_time(std::string timestr, const char *format) { std::stringstream stream(timestr); @@ -93,7 +92,7 @@ void Time::replace_specifiers() LOG_ERROR("Time::set_time error %s", e.what()); } } - UTF8 Time::str(std::string format) + UTF8 Timestamp::str(std::string format) { if(format.compare("") !=0) this->format = format; UTF8 datetimestr = ""; @@ -103,7 +102,7 @@ void Time::replace_specifiers() return datetimestr; } - UTF8 Time::day(bool abbrev) + UTF8 Timestamp::day(bool abbrev) { if(abbrev) { return get_replacement(Replacements::DayAbbrev, timeinfo); @@ -112,8 +111,7 @@ void Time::replace_specifiers() } } - - UTF8 Time::month(bool abbrev) + UTF8 Timestamp::month(bool abbrev) { if(abbrev) { return get_replacement(Replacements::MonthAbbrev, timeinfo); @@ -122,35 +120,83 @@ void Time::replace_specifiers() } } - void SysTime::before_n_sec(time_t val) + void DateTime::before_n_sec(time_t val) { - ref_time = time; - if(val) { + local_time = time; + if (val) + { set_time(val); } } - UTF8 SysTime::str(std::string format) + bool DateTime::isToday() { - auto newer_timeinfo = *localtime(&ref_time); - const unsigned int seconds_in_2days = 3600 * 24 * 2; + auto newer_timeinfo = *localtime(&local_time); + return (newer_timeinfo.tm_yday == timeinfo.tm_yday && newer_timeinfo.tm_year == timeinfo.tm_year); + } + + bool DateTime::isYesterday() + { + auto newer_timeinfo = *localtime(&local_time); bool is_leap_year = (timeinfo.tm_year % 4 == 0 && timeinfo.tm_year % 100 != 0) || timeinfo.tm_year % 400 == 0; - if(format.compare("") != 0) { - return Time::str(format); + + return (((newer_timeinfo.tm_yday - timeinfo.tm_yday == 1) && (newer_timeinfo.tm_year == timeinfo.tm_year)) // day difference + || (timeinfo.tm_year == 0 && newer_timeinfo.tm_year + 364 + is_leap_year) // day next year day difference + ); + } + + UTF8 DateTime::str(std::string format) + { + if (format.compare("") != 0) + { + return Timestamp::str(format); } - if( newer_timeinfo.tm_yday - timeinfo.tm_yday == 0) { - return Time::str(Locale::format(Locale::Format12HourMin)); - } else if( show_textual_past - && ((newer_timeinfo.tm_yday - timeinfo.tm_yday == 1) // day difference - ||(timeinfo.tm_year == 0 && newer_timeinfo.tm_year + 364 + is_leap_year) // day next year day difference - ) - ) { + if (isToday()) // if the same computer day, then return hour. + { + return Timestamp::str(Locale::format(Locale::Format12HourMin)); + } + else if (show_textual_past && isYesterday()) + { return Locale::yesterday(); - } else { - return Time::str(Locale::format(date_format_long ? Locale::FormatLocaleDateFull : Locale::FormatLocaleDateShort)); + } + else + { + return Timestamp::str(Locale::format(date_format_long ? Locale::FormatLocaleDateFull : Locale::FormatLocaleDateShort)); } } + UTF8 Date::str(std::string format) + { + if (!format.empty()) + { + return Timestamp::str(format); + } + else if (show_textual_past) + { + if (isToday()) + { + return Locale::today(); + } + else if (isYesterday()) + { + return Locale::yesterday(); + } + } -}; //time + return Timestamp::str(Locale::format(date_format_long ? Locale::FormatLocaleDateFull : Locale::FormatLocaleDateShort)); + } + + UTF8 Time::str(std::string format) + { + if (!format.empty()) + { + return Timestamp::str(format); + } + else + { + return Timestamp::str(Locale::format(Locale::Format12HourMin)); + } + } + +}; // namespace time }; // utils diff --git a/module-utils/time/time_conversion.hpp b/module-utils/time/time_conversion.hpp index cb5f109d0..dac480110 100644 --- a/module-utils/time/time_conversion.hpp +++ b/module-utils/time/time_conversion.hpp @@ -33,9 +33,10 @@ struct Localer { UTF8 get_replacement(Replacements val, const struct tm &timeinfo); }; -class Time : protected Localer { - protected: - time_t time=0; +class Timestamp : protected Localer +{ + protected: + time_t time = 0; struct tm timeinfo; /// only reformat on: new format std::string format = ""; @@ -52,14 +53,18 @@ class Time : protected Localer { void replace_specifiers(); public: - Time() { + Timestamp() + { auto err = bsp::rtc_GetCurrentTimestamp(&time); if(err) { LOG_ERROR("rtc_GetCurrentTimestamp failure!"); } - timeinfo =*localtime(&time); + timeinfo = *localtime(&time); + } + Timestamp(time_t newtime) : time(newtime) + { + timeinfo = *localtime(&time); } - Time(time_t newtime) : time(newtime) { timeinfo = *localtime(&time); } /// set Time time_t value held (set timestamp) void set_time(time_t newtime); @@ -68,7 +73,8 @@ class Time : protected Localer { void set_format(std::string format) { this->format = format;} operator UTF8() { return str(); } - friend std::ostream& operator<<(std::ostream &os, Time t) { + friend std::ostream &operator<<(std::ostream &os, Timestamp t) + { os << t.str(); return os; } @@ -91,21 +97,24 @@ class Time : protected Localer { /// helper class to operate on time now /// takes timestamp and can show time in past -class SysTime : public Time { - time_t ref_time = 0; - public: +class DateTime : public Timestamp +{ + time_t local_time = 0; + public: bool show_textual_past = true; bool date_format_long = true; std::string today_format = "%H:%M"; std::string long_ago_format = "%d.%m.%y"; /// shows time in past: time_now - val in seconds - SysTime(time_t val=0, bool date_format_long=true) : date_format_long(date_format_long) { + DateTime(time_t val = 0, bool date_format_long = true) : date_format_long(date_format_long) + { before_n_sec(val); } - friend std::ostream& operator<<(std::ostream &os, SysTime t) { + friend std::ostream &operator<<(std::ostream &os, DateTime t) + { os << t.str(); return os; } @@ -114,8 +123,23 @@ class SysTime : public Time { void before_n_sec(time_t val); /// Time have str(std::string ) this one uses presets - virtual UTF8 str(std::string format=""); + virtual UTF8 str(std::string format = ""); + bool isToday(); + bool isYesterday(); }; +class Date : public DateTime +{ + public: + Date(time_t val = 0, bool date_format_long = true) : DateTime(val, date_format_long){}; + virtual UTF8 str(std::string format = "") final; +}; + +class Time : public DateTime +{ + public: + Time(time_t val = 0, bool date_format_long = true) : DateTime(val, date_format_long){}; + virtual UTF8 str(std::string format = "") final; +}; }; }; diff --git a/module-utils/time/time_locale.hpp b/module-utils/time/time_locale.hpp index a189db2e2..ed8486f20 100644 --- a/module-utils/time/time_locale.hpp +++ b/module-utils/time/time_locale.hpp @@ -35,6 +35,7 @@ class Locale { "locale_date_short", }; + const std::string ltoday = "common_today"; const std::string lyesterday = "common_yesterday"; const std::string ltimezone = "common_timezone"; @@ -70,10 +71,16 @@ class Locale { } } - static const UTF8 yesterday() { + static const UTF8 yesterday() + { return localize.get(tlocale.lyesterday); } + static const UTF8 today() + { + return localize.get(tlocale.ltoday); + } + static const std::string format(enum TimeFormat what) { if(what >= num_formatters || what < 0 ) { LOG_ERROR("Bad value: %d", what);