M changelog.md => changelog.md +4 -0
@@ 14,6 14,10 @@
* `[alarms]` Database refactor
+### Other
+
+* `[utils]` Added unit tests for time display.
+
## [0.48.1 2020-11-23]
### Added
M module-apps/application-calendar/CMakeLists.txt => module-apps/application-calendar/CMakeLists.txt +0 -1
@@ 38,7 38,6 @@
"${CMAKE_CURRENT_LIST_DIR}/widgets/CalendarStyle.hpp"
"${CMAKE_CURRENT_LIST_DIR}/data/OptionParser.hpp"
"${CMAKE_CURRENT_LIST_DIR}/data/CalendarData.hpp"
- "${CMAKE_CURRENT_LIST_DIR}/data/TimeDisplayParser.hpp"
)
target_link_libraries(${PROJECT_NAME}
D module-apps/application-calendar/data/TimeDisplayParser.hpp => module-apps/application-calendar/data/TimeDisplayParser.hpp +0 -102
@@ 1,102 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-#include "module-apps/application-calendar/widgets/CalendarStyle.hpp"
-#include <Utils.hpp>
-#include <module-db/Interface/EventsRecord.hpp>
-#include <time/time_locale.hpp>
-
-class TimeDisplayParser
-{
-
- private:
- std::string getAMorPM(bool is_am)
- {
- if (is_am) {
- return utils::localize.get(utils::time::Locale::getAM());
- }
- else {
- return utils::localize.get(utils::time::Locale::getPM());
- }
- }
-
- public:
- TimeDisplayParser() = default;
-
- std::string getTimeString(const std::shared_ptr<EventsRecord> &event,
- bool isShortVersion = false,
- bool isMode24H = false)
- {
- auto start_time = TimePointToHourMinSec(event->date_from);
- auto end_time = TimePointToHourMinSec(event->date_till);
-
- if (start_time.hours().count() == 0 && start_time.minutes().count() == 0 &&
- end_time.hours().count() == style::window::calendar::time::max_hour_24H_mode &&
- end_time.minutes().count() == style::window::calendar::time::max_minutes) {
- return utils::localize.get("app_calendar_all_day");
- }
- else {
- bool start_is_am = true;
- bool end_is_am = true;
- auto start_h = std::to_string(start_time.hours().count());
- auto start_min = std::to_string(start_time.minutes().count());
- auto end_h = std::to_string(end_time.hours().count());
- auto end_min = std::to_string(end_time.minutes().count());
-
- if (start_min.length() < style::window::calendar::time::max_time_length) {
- start_min.insert(0, style::window::calendar::time::max_time_length / 2, '0');
- }
- if (end_min.length() < style::window::calendar::time::max_time_length) {
- end_min.insert(0, style::window::calendar::time::max_time_length / 2, '0');
- }
-
- if (!isMode24H) {
- start_is_am = date::is_am(start_time.hours());
- end_is_am = date::is_am(end_time.hours());
- start_h = std::to_string(date::make12(start_time.hours()).count());
- end_h = std::to_string(date::make12(end_time.hours()).count());
- }
-
- if (start_h.length() < style::window::calendar::time::max_time_length) {
- start_h.insert(0, style::window::calendar::time::max_time_length / 2, '0');
- }
- if (end_h.length() < style::window::calendar::time::max_time_length) {
- end_h.insert(0, style::window::calendar::time::max_time_length / 2, '0');
- }
-
- if (isShortVersion) {
- if (!isMode24H) {
- return TimePointToHourString12H(event->date_from) + ":" +
- TimePointToMinutesString(event->date_from) + " " + getAMorPM(start_is_am);
- }
- else {
- return TimePointToHourString24H(event->date_from) + ":" +
- TimePointToMinutesString(event->date_from);
- }
- }
- else {
- if (!isMode24H) {
- if (start_is_am != end_is_am) {
- return TimePointToHourString12H(event->date_from) + ":" +
- TimePointToMinutesString(event->date_from) + " " + getAMorPM(start_is_am) + " - " +
- TimePointToHourString12H(event->date_till) + ":" +
- TimePointToMinutesString(event->date_till) + " " + getAMorPM(end_is_am);
- }
- else {
- return TimePointToHourString12H(event->date_from) + ":" +
- TimePointToMinutesString(event->date_from) + " - " +
- TimePointToHourString12H(event->date_till) + ":" +
- TimePointToMinutesString(event->date_till) + " " + getAMorPM(start_is_am);
- }
- }
- else {
- return TimePointToHourString24H(event->date_from) + ":" +
- TimePointToMinutesString(event->date_from) + " - " +
- TimePointToMinutesString(event->date_till) + ":" +
- TimePointToMinutesString(event->date_till);
- }
- }
- }
- }
-};
M module-apps/application-calendar/data/dateCommon.hpp => module-apps/application-calendar/data/dateCommon.hpp +8 -6
@@ 6,6 6,7 @@
#include <module-utils/date/include/date/date.h>
#include <time/time_conversion.hpp>
+#include <Utils.hpp>
#include <random>
using namespace std::chrono;
@@ 227,16 228,17 @@ inline uint32_t TimePointToHour12H(const TimePoint &tp)
inline std::string TimePointToHourString12H(const TimePoint &tp)
{
- auto hour = TimePointToHour12H(tp);
- auto hourString = std::to_string(hour);
- return hourString;
+ auto hour =
+ utils::time::Timestamp(TimePointToTimeT(tp)).get_UTC_date_time_sub_value(utils::time::GetParameters::Hour);
+ auto hour12h = date::make12(std::chrono::hours(hour)).count();
+ return utils::to_string(hour12h);
}
inline std::string TimePointToHourString24H(const TimePoint &tp)
{
- auto hour = TimePointToHour24H(tp);
- auto hourString = std::to_string(hour);
- return hourString;
+ auto hour =
+ utils::time::Timestamp(TimePointToTimeT(tp)).get_UTC_date_time_sub_value(utils::time::GetParameters::Hour);
+ return utils::to_string(hour);
}
inline std::string TimePointToMinutesString(const TimePoint &tp)
M module-apps/application-calendar/widgets/AllEventsItem.cpp => module-apps/application-calendar/widgets/AllEventsItem.cpp +3 -3
@@ 3,12 3,11 @@
#include "AllEventsItem.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
-#include "application-calendar/data/TimeDisplayParser.hpp"
#include "CalendarListItem.hpp"
#include <Style.hpp>
#include <gui/widgets/Label.hpp>
#include <time/time_conversion.hpp>
-#include <module-utils/date/include/date/date.h>
+#include <module-utils/time/TimeRangeParser.hpp>
namespace gui
{
@@ 82,7 81,8 @@ namespace gui
this->record = rec;
if (rec != nullptr) {
description->setText(this->record->title.c_str());
- startTime->setText(TimeDisplayParser().getTimeString(record, true));
+ startTime->setText(utils::time::TimeRangeParser().getCalendarTimeString(
+ record->date_from, record->date_till, utils::time::Version::abbrev));
}
}
} /* namespace gui */
M module-apps/application-calendar/widgets/DayEventsItem.cpp => module-apps/application-calendar/widgets/DayEventsItem.cpp +2 -2
@@ 3,10 3,10 @@
#include "DayEventsItem.hpp"
#include "CalendarStyle.hpp"
-#include "application-calendar/data/TimeDisplayParser.hpp"
#include <ListView.hpp>
#include <gui/widgets/Label.hpp>
#include <Style.hpp>
+#include <module-utils/time/TimeRangeParser.hpp>
namespace gui
{
@@ 49,7 49,7 @@ namespace gui
if (rec != nullptr) {
description->setText(this->record->title.c_str());
- title->setText(TimeDisplayParser().getTimeString(record));
+ title->setText(utils::time::TimeRangeParser().getCalendarTimeString(record->date_from, record->date_till));
if (record->reminder == static_cast<uint32_t>(Reminder::never)) {
clock->setVisible(false);
}
M module-apps/application-calendar/widgets/EventDetailDescriptionItem.cpp => module-apps/application-calendar/widgets/EventDetailDescriptionItem.cpp +3 -2
@@ 3,10 3,10 @@
#include "EventDetailDescriptionItem.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
-#include "application-calendar/data/TimeDisplayParser.hpp"
#include <Style.hpp>
#include <time/time_conversion.hpp>
#include <module-utils/date/include/date/date.h>
+#include <module-utils/time/TimeRangeParser.hpp>
namespace gui
{
@@ 79,7 79,8 @@ namespace gui
title->setText(utils::localize.get("app_calendar_event_detail"));
onLoadCallback = [&](std::shared_ptr<EventsRecord> event) {
description->setText(event->title);
- eventTime->setText(TimeDisplayParser().getTimeString(event));
+ eventTime->setText(
+ utils::time::TimeRangeParser().getCalendarTimeString(event->date_from, event->date_till));
};
}
M module-utils/CMakeLists.txt => module-utils/CMakeLists.txt +1 -0
@@ 34,6 34,7 @@ set (SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/country.hpp
${CMAKE_CURRENT_SOURCE_DIR}/state/ServiceState.hpp
${CMAKE_CURRENT_SOURCE_DIR}/ical/ParserICS.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/time/TimeRangeParser.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${BOARD_SOURCES})
M module-utils/test/CMakeLists.txt => module-utils/test/CMakeLists.txt +11 -0
@@ 85,6 85,17 @@ add_catch2_executable(
# module-utils
#)
+# time display tests
+#add_catch2_executable(
+# NAME
+# utils-time_display
+# SRCS
+# unittest_TimeRangeParser.cpp
+# LIBS
+# module-utils
+# module-db
+#)
+
###########################################
# Log functional tests project
project(test_module-utils_log VERSION 1.0
A module-utils/test/unittest_TimeRangeParser.cpp => module-utils/test/unittest_TimeRangeParser.cpp +143 -0
@@ 0,0 1,143 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+#include "time/TimeRangeParser.hpp"
+#include <module-apps/application-calendar/data/dateCommon.hpp>
+#include <module-db/Interface/EventsRecord.hpp>
+
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+
+TEST_CASE("Time display parser")
+{
+ using utils::time::Version;
+ SECTION("After noon time input (mode12h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2020-10-10 14:24:00");
+ event.date_till = TimePointFromString("2020-10-10 15:36:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::normal, false);
+ REQUIRE("2020-10-10 14:24:00" == TimePointToString(event.date_from));
+ REQUIRE("2020-10-10 15:36:00" == TimePointToString(event.date_till));
+ REQUIRE("2" == TimePointToHourString12H(event.date_from));
+ REQUIRE("24" == TimePointToMinutesString(event.date_from));
+ REQUIRE("3" == TimePointToHourString12H(event.date_till));
+ REQUIRE("36" == TimePointToMinutesString(event.date_till));
+ REQUIRE(returnString == "2:24 - 3:36 " + utils::localize.get(utils::time::Locale::getPM()));
+ }
+
+ SECTION("Before noon time input (mode12h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2020-12-31 05:59:00");
+ event.date_till = TimePointFromString("2020-12-31 07:45:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::normal, false);
+ REQUIRE("2020-12-31 05:59:00" == TimePointToString(event.date_from));
+ REQUIRE("2020-12-31 07:45:00" == TimePointToString(event.date_till));
+ REQUIRE("5" == TimePointToHourString12H(event.date_from));
+ REQUIRE("59" == TimePointToMinutesString(event.date_from));
+ REQUIRE("7" == TimePointToHourString12H(event.date_till));
+ REQUIRE("45" == TimePointToMinutesString(event.date_till));
+ REQUIRE(returnString == "5:59 - 7:45 " + utils::localize.get(utils::time::Locale::getAM()));
+ }
+
+ SECTION("Mixed time input (mode12h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2021-01-01 01:05:00");
+ event.date_till = TimePointFromString("2021-01-01 19:55:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::normal, false);
+ REQUIRE("2021-01-01 01:05:00" == TimePointToString(event.date_from));
+ REQUIRE("2021-01-01 19:55:00" == TimePointToString(event.date_till));
+ REQUIRE("1" == TimePointToHourString12H(event.date_from));
+ REQUIRE("05" == TimePointToMinutesString(event.date_from));
+ REQUIRE("7" == TimePointToHourString12H(event.date_till));
+ REQUIRE("55" == TimePointToMinutesString(event.date_till));
+ REQUIRE(returnString == "1:05 " + utils::localize.get(utils::time::Locale::getAM()) + " - 7:55 " +
+ utils::localize.get(utils::time::Locale::getPM()));
+ }
+
+ SECTION("Before noon time input - short version (mode12h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2020-12-31 00:05:00");
+ event.date_till = TimePointFromString("2020-12-31 19:55:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::abbrev, false);
+ REQUIRE("2020-12-31 00:05:00" == TimePointToString(event.date_from));
+ REQUIRE("2020-12-31 19:55:00" == TimePointToString(event.date_till));
+ REQUIRE("12" == TimePointToHourString12H(event.date_from));
+ REQUIRE("05" == TimePointToMinutesString(event.date_from));
+ REQUIRE(returnString == "12:05 " + utils::localize.get(utils::time::Locale::getAM()));
+ }
+
+ SECTION("After noon time input - short version (mode12h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2020-12-31 12:05:00");
+ event.date_till = TimePointFromString("2020-12-31 19:55:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::abbrev, false);
+ REQUIRE("2020-12-31 12:05:00" == TimePointToString(event.date_from));
+ REQUIRE("2020-12-31 19:55:00" == TimePointToString(event.date_till));
+ REQUIRE("12" == TimePointToHourString12H(event.date_from));
+ REQUIRE("05" == TimePointToMinutesString(event.date_from));
+ REQUIRE(returnString == "12:05 " + utils::localize.get(utils::time::Locale::getPM()));
+ }
+
+ SECTION("Time input (mode24h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2021-01-01 01:05:00");
+ event.date_till = TimePointFromString("2021-01-01 19:55:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::normal, true);
+ REQUIRE("2021-01-01 01:05:00" == TimePointToString(event.date_from));
+ REQUIRE("2021-01-01 19:55:00" == TimePointToString(event.date_till));
+ REQUIRE("1" == TimePointToHourString24H(event.date_from));
+ REQUIRE("05" == TimePointToMinutesString(event.date_from));
+ REQUIRE("19" == TimePointToHourString24H(event.date_till));
+ REQUIRE("55" == TimePointToMinutesString(event.date_till));
+ REQUIRE(returnString == "1:05 - 19:55");
+ }
+
+ SECTION("Time input - short version (mode24h)")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2021-01-01 18:05:00");
+ event.date_till = TimePointFromString("2021-01-01 19:55:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::abbrev, true);
+ REQUIRE("2021-01-01 18:05:00" == TimePointToString(event.date_from));
+ REQUIRE("2021-01-01 19:55:00" == TimePointToString(event.date_till));
+ REQUIRE("18" == TimePointToHourString24H(event.date_from));
+ REQUIRE("05" == TimePointToMinutesString(event.date_from));
+ REQUIRE(returnString == "18:05");
+ }
+
+ SECTION("All day time input")
+ {
+ auto event = EventsRecord();
+ event.date_from = TimePointFromString("2020-10-20 00:00:00");
+ event.date_till = TimePointFromString("2020-10-20 23:59:00");
+
+ auto returnString = utils::time::TimeRangeParser().getCalendarTimeString(
+ event.date_from, event.date_till, Version::normal, false);
+ REQUIRE("2020-10-20 00:00:00" == TimePointToString(event.date_from));
+ REQUIRE("2020-10-20 23:59:00" == TimePointToString(event.date_till));
+ REQUIRE(returnString == utils::localize.get("app_calendar_all_day"));
+ }
+}
A module-utils/time/TimeRangeParser.cpp => module-utils/time/TimeRangeParser.cpp +72 -0
@@ 0,0 1,72 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "TimeRangeParser.hpp"
+
+namespace utils::time
+{
+ namespace
+ {
+ constexpr int max_hour = 23;
+ constexpr int max_minutes = 59;
+ } // namespace
+
+ std::string TimeRangeParser::AMPMtoString(bool isAm)
+ {
+ if (isAm) {
+ return utils::localize.get(utils::time::Locale::getAM());
+ }
+ return utils::localize.get(utils::time::Locale::getPM());
+ }
+
+ std::string TimeRangeParser::getCalendarTimeString(TimePoint startDate,
+ TimePoint endDate,
+ Version version,
+ bool isMode24H)
+ {
+ auto startTime = TimePointToHourMinSec(startDate);
+ auto endTime = TimePointToHourMinSec(endDate);
+
+ if (startTime.hours().count() == 0 && startTime.minutes().count() == 0 && endTime.hours().count() == max_hour &&
+ endTime.minutes().count() == max_minutes) {
+ return utils::localize.get("app_calendar_all_day");
+ }
+ else {
+ bool startIsAm = true;
+ bool endIsAm = true;
+
+ if (!isMode24H) {
+ startIsAm = date::is_am(startTime.hours());
+ endIsAm = date::is_am(endTime.hours());
+ }
+
+ if (version == Version::abbrev) {
+ if (!isMode24H) {
+ return TimePointToHourString12H(startDate) + ":" + TimePointToMinutesString(startDate) + " " +
+ AMPMtoString(startIsAm);
+ }
+ else {
+ return TimePointToHourString24H(startDate) + ":" + TimePointToMinutesString(startDate);
+ }
+ }
+ else {
+ if (!isMode24H) {
+ if (startIsAm != endIsAm) {
+ return TimePointToHourString12H(startDate) + ":" + TimePointToMinutesString(startDate) + " " +
+ AMPMtoString(startIsAm) + " - " + TimePointToHourString12H(endDate) + ":" +
+ TimePointToMinutesString(endDate) + " " + AMPMtoString(endIsAm);
+ }
+ else {
+ return TimePointToHourString12H(startDate) + ":" + TimePointToMinutesString(startDate) + " - " +
+ TimePointToHourString12H(endDate) + ":" + TimePointToMinutesString(endDate) + " " +
+ AMPMtoString(startIsAm);
+ }
+ }
+ else {
+ return TimePointToHourString24H(startDate) + ":" + TimePointToMinutesString(startDate) + " - " +
+ TimePointToHourString24H(endDate) + ":" + TimePointToMinutesString(endDate);
+ }
+ }
+ }
+ }
+} // namespace utils::time
A module-utils/time/TimeRangeParser.hpp => module-utils/time/TimeRangeParser.hpp +28 -0
@@ 0,0 1,28 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+#include "Utils.hpp"
+#include <module-apps/application-calendar/data/dateCommon.hpp>
+
+namespace utils::time
+{
+ enum class Version
+ {
+ abbrev,
+ normal
+ };
+
+ class TimeRangeParser
+ {
+
+ private:
+ std::string AMPMtoString(bool isAm);
+
+ public:
+ std::string getCalendarTimeString(TimePoint startDate,
+ TimePoint endDate,
+ Version version = Version::normal,
+ bool isMode24H = false);
+ };
+} // namespace utils::time
M module-utils/time/time_conversion.cpp => module-utils/time/time_conversion.cpp +18 -0
@@ 234,6 234,24 @@ namespace utils::time
}
return UINT32_MAX;
}
+ uint32_t Timestamp::get_UTC_date_time_sub_value(GetParameters param)
+ {
+ std::tm tm = *std::gmtime(&time);
+ switch (param) {
+ case GetParameters::Hour:
+ return tm.tm_hour;
+ case GetParameters::Minute:
+ return tm.tm_min;
+ case GetParameters::Day:
+ return tm.tm_mday;
+ case GetParameters::Month:
+ return tm.tm_mon + 1;
+ case GetParameters::Year:
+ return tm.tm_year + 1900;
+ }
+ return UINT32_MAX;
+ }
+
UTF8 Date::str(std::string format)
{
if (!format.empty()) {
M module-utils/time/time_conversion.hpp => module-utils/time/time_conversion.hpp +1 -0
@@ 137,6 137,7 @@ namespace utils
UTF8 get_date_time_substr(GetParameters param);
uint32_t get_date_time_sub_value(GetParameters param);
+ uint32_t get_UTC_date_time_sub_value(GetParameters param);
};
/// helper class to operate on time now