mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-07-18 12:04:03 -04:00
321 lines
10 KiB
C++
321 lines
10 KiB
C++
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#ifndef DATECOMMON_H
|
|
#define DATECOMMON_H
|
|
|
|
#include <module-utils/date/include/date/date.h>
|
|
#include <module-utils/time/DateAndTimeSettings.hpp>
|
|
#include <time/time_conversion.hpp>
|
|
#include <Utils.hpp>
|
|
#include <random>
|
|
|
|
using Clock = std::chrono::system_clock;
|
|
using TimePoint = std::chrono::time_point<Clock>;
|
|
|
|
namespace calendar
|
|
{
|
|
using YearMonthDay = date::year_month_day;
|
|
using YearMonthDayLast = date::year_month_day_last;
|
|
} // namespace calendar
|
|
|
|
inline constexpr auto max_month_day = 31;
|
|
inline constexpr auto unix_epoch_year = 1900;
|
|
|
|
enum class Reminder
|
|
{
|
|
never = 0xFFFF,
|
|
event_time = 0,
|
|
five_min_before = 5,
|
|
fifteen_min_before = 15,
|
|
thirty_min_before = 30,
|
|
one_hour_before = 60,
|
|
two_hour_before = 120,
|
|
one_day_before = 1440,
|
|
two_days_before = 2880,
|
|
one_week_before = 10080
|
|
};
|
|
|
|
enum class Repeat
|
|
{
|
|
never,
|
|
daily,
|
|
weekly,
|
|
biweekly,
|
|
monthly,
|
|
yearly
|
|
};
|
|
|
|
inline constexpr TimePoint TIME_POINT_INVALID = date::sys_days{date::January / 1 / 1970};
|
|
inline constexpr uint32_t yearDigitsNumb = 4, monthDigitsNumb = 2, dayDigitsNumb = 2, HourDigitsNumb = 2,
|
|
MinDigitsNumb = 2, SecDigitsNumb = 2;
|
|
|
|
inline std::tm CreateTmStruct(int year, int month, int day, int hour, int minutes, int seconds)
|
|
{
|
|
struct tm tm_ret;
|
|
|
|
tm_ret.tm_isdst = -1;
|
|
tm_ret.tm_sec = seconds;
|
|
tm_ret.tm_min = minutes;
|
|
tm_ret.tm_hour = hour;
|
|
tm_ret.tm_mday = day;
|
|
tm_ret.tm_mon = month - 1;
|
|
tm_ret.tm_year = year - 1900;
|
|
|
|
return tm_ret;
|
|
}
|
|
|
|
inline time_t GetDiffLocalWithUTCTime()
|
|
{
|
|
std::tm tm = CreateTmStruct(2000, 1, 1, 0, 0, 0);
|
|
|
|
std::time_t basetime = std::mktime(&tm);
|
|
std::time_t diff;
|
|
|
|
tm = *std::localtime(&basetime);
|
|
tm.tm_isdst = -1;
|
|
diff = std::mktime(&tm);
|
|
|
|
tm = *std::gmtime(&basetime);
|
|
tm.tm_isdst = -1;
|
|
diff -= std::mktime(&tm);
|
|
|
|
return diff;
|
|
}
|
|
|
|
inline time_t GetAsUTCTime(int year, int month, int day, int hour = 0, int minutes = 0, int seconds = 0)
|
|
{
|
|
std::tm tm = CreateTmStruct(year, month, day, hour, minutes, seconds);
|
|
std::time_t basetime = std::mktime(&tm);
|
|
|
|
return basetime + GetDiffLocalWithUTCTime();
|
|
}
|
|
|
|
inline TimePoint TimePointFromTimeT(const time_t &time)
|
|
{
|
|
return std::chrono::system_clock::from_time_t(time);
|
|
}
|
|
|
|
inline time_t TimePointToTimeT(const TimePoint &tp)
|
|
{
|
|
return std::chrono::system_clock::to_time_t(tp);
|
|
}
|
|
|
|
inline TimePoint TimePointNow()
|
|
{
|
|
utils::time::Timestamp timestamp;
|
|
return TimePointFromTimeT(timestamp.getTime());
|
|
}
|
|
|
|
inline std::string TimePointToString(const TimePoint &tp)
|
|
{
|
|
return date::format("%F %T", std::chrono::time_point_cast<std::chrono::seconds>(tp));
|
|
}
|
|
|
|
inline auto TimePointToHourMinSec(const TimePoint &tp)
|
|
{
|
|
auto dp = date::floor<date::days>(tp);
|
|
return date::make_time(tp - dp);
|
|
}
|
|
|
|
inline uint32_t TimePointToHour24H(const TimePoint &tp)
|
|
{
|
|
auto time = TimePointToTimeT(tp);
|
|
utils::time::Timestamp timestamp(time);
|
|
auto hour = timestamp.get_date_time_sub_value(utils::time::GetParameters::Hour);
|
|
return hour;
|
|
}
|
|
|
|
inline auto LocalizedHoursToUtcHours(int hour = 0)
|
|
{
|
|
std::tm tm = CreateTmStruct(unix_epoch_year, 1, 1, hour, 0, 0);
|
|
std::time_t basetime = std::mktime(&tm);
|
|
basetime -= utils::time::Time::getTimeZoneOffset();
|
|
return TimePointToHour24H(TimePointFromTimeT(basetime));
|
|
}
|
|
|
|
inline uint32_t TimePointToMinutes(const TimePoint &tp)
|
|
{
|
|
auto time = TimePointToTimeT(tp);
|
|
utils::time::Timestamp timestamp(time);
|
|
auto minute = timestamp.get_date_time_sub_value(utils::time::GetParameters::Minute);
|
|
return minute;
|
|
}
|
|
|
|
inline TimePoint getFirstWeekDay(const TimePoint &tp)
|
|
{
|
|
auto time_of_day = TimePointToHourMinSec(tp);
|
|
auto yearMonthDay = date::year_month_day{date::floor<date::days>(tp)};
|
|
while (date::weekday{yearMonthDay} != date::mon) {
|
|
auto decrementedDay = --yearMonthDay.day();
|
|
yearMonthDay = yearMonthDay.year() / yearMonthDay.month() / decrementedDay;
|
|
}
|
|
auto finalDate = date::sys_days{yearMonthDay.year() / yearMonthDay.month() / yearMonthDay.day()};
|
|
auto finalDateTime = finalDate + time_of_day.hours() + time_of_day.minutes();
|
|
|
|
return finalDateTime;
|
|
}
|
|
|
|
inline std::string TimePointToString(const TimePoint &tp, date::months months)
|
|
{
|
|
date::year_month_day yearMonthDay = date::year_month_day{date::floor<date::days>(tp)};
|
|
date::year_month_day yearMonthDayLast = yearMonthDay.year() / yearMonthDay.month() / date::last;
|
|
auto tpHourMinuteSecond = TimePointToHourMinSec(tp).to_duration();
|
|
|
|
TimePoint timePoint;
|
|
|
|
if ((static_cast<unsigned>(yearMonthDay.month()) + months.count()) <= 12) {
|
|
if (yearMonthDayLast.day() == yearMonthDay.day()) {
|
|
yearMonthDayLast = yearMonthDay.year() / (yearMonthDay.month() + months) / date::last;
|
|
timePoint = date::sys_days{yearMonthDayLast.year() / yearMonthDayLast.month() / yearMonthDayLast.day()};
|
|
}
|
|
else {
|
|
timePoint = date::sys_days{yearMonthDay.year() / (yearMonthDay.month() + months) / yearMonthDay.day()};
|
|
}
|
|
}
|
|
else {
|
|
date::month incrementedMonths = date::month(months.count()) - (date::month(12) - yearMonthDay.month());
|
|
yearMonthDay = (yearMonthDay.year() + date::years{1}) / incrementedMonths / yearMonthDay.day();
|
|
if (yearMonthDayLast.day() == yearMonthDay.day()) {
|
|
yearMonthDayLast = yearMonthDay.year() / incrementedMonths / date::last;
|
|
timePoint = date::sys_days{yearMonthDayLast.year() / yearMonthDayLast.month() / yearMonthDayLast.day()};
|
|
}
|
|
else {
|
|
timePoint = date::sys_days{yearMonthDay.year() / yearMonthDay.month() / yearMonthDay.day()};
|
|
}
|
|
}
|
|
|
|
auto time_of_day = TimePointToHourMinSec(tp);
|
|
return date::format(
|
|
"%F %T",
|
|
std::chrono::time_point_cast<std::chrono::seconds>(timePoint + time_of_day.hours() + time_of_day.minutes()));
|
|
}
|
|
|
|
inline std::string TimePointToString(const TimePoint &tp, date::years years)
|
|
{
|
|
auto yearMonthDay = date::year_month_day{date::floor<date::days>(tp)};
|
|
auto yearMonthDayLast = (yearMonthDay.year() + date::years(years)) / yearMonthDay.month() / date::last;
|
|
|
|
TimePoint timePoint =
|
|
date::sys_days{yearMonthDayLast.year() / yearMonthDayLast.month() /
|
|
((yearMonthDayLast.day() == yearMonthDay.day()) ? yearMonthDayLast.day() : yearMonthDay.day())};
|
|
|
|
auto time_of_day = TimePointToHourMinSec(tp);
|
|
return date::format(
|
|
"%F %T",
|
|
std::chrono::time_point_cast<std::chrono::seconds>(timePoint + time_of_day.hours() + time_of_day.minutes()));
|
|
}
|
|
|
|
inline std::string TimePointToLocalizedDateString(const TimePoint &tp, const std::string format = "")
|
|
{
|
|
auto time = TimePointToTimeT(tp);
|
|
utils::time::Date timestamp(time);
|
|
return timestamp.str(format);
|
|
}
|
|
|
|
inline std::string TimePointToLocalizedTimeString(const TimePoint &tp, const std::string format = "")
|
|
{
|
|
auto time = TimePointToTimeT(tp);
|
|
utils::time::Time timestamp(time);
|
|
return timestamp.str(format);
|
|
}
|
|
|
|
inline std::string TimePointToLocalizedHourMinString(const TimePoint &tp)
|
|
{
|
|
return utils::dateAndTimeSettings.isTimeFormat12() ? TimePointToLocalizedDateString(tp, "%I:%M")
|
|
: TimePointToLocalizedDateString(tp, "%H:%M");
|
|
}
|
|
|
|
inline TimePoint TimePointFromString(const char *s1)
|
|
{
|
|
TimePoint tp;
|
|
std::istringstream(s1) >> date::parse("%F %T", tp);
|
|
return tp;
|
|
}
|
|
|
|
inline calendar::YearMonthDay TimePointToYearMonthDay(const TimePoint &tp)
|
|
{
|
|
return date::year_month_day{date::floor<date::days>(tp)};
|
|
}
|
|
|
|
inline TimePoint TimePointFromYearMonthDay(const calendar::YearMonthDay &ymd)
|
|
{
|
|
return date::sys_days{ymd.year() / ymd.month() / ymd.day()};
|
|
}
|
|
|
|
inline time_t TimePointToMin(const TimePoint &tp)
|
|
{
|
|
auto time = TimePointToTimeT(tp);
|
|
auto duration = new utils::time::Duration(time);
|
|
auto minutes = duration->getMinutes();
|
|
return minutes;
|
|
}
|
|
|
|
inline uint32_t TimePointToHour12H(const TimePoint &tp)
|
|
{
|
|
auto time = TimePointToTimeT(tp);
|
|
utils::time::Timestamp timestamp(time);
|
|
auto hour = timestamp.get_date_time_sub_value(utils::time::GetParameters::Hour);
|
|
if (hour > 12) {
|
|
hour -= 12;
|
|
}
|
|
return hour;
|
|
}
|
|
|
|
inline std::string TimePointToHourString12H(const TimePoint &tp)
|
|
{
|
|
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 TimePointToLocalizedHourString(const TimePoint &tp)
|
|
{
|
|
return utils::dateAndTimeSettings.isTimeFormat12() ? TimePointToLocalizedDateString(tp, "%I")
|
|
: TimePointToLocalizedDateString(tp, "%H");
|
|
}
|
|
|
|
inline std::string TimePointToHourString24H(const TimePoint &tp)
|
|
{
|
|
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)
|
|
{
|
|
auto minute = TimePointToMinutes(tp);
|
|
auto minuteString = std::to_string(minute);
|
|
if (minute < 10) {
|
|
minuteString = "0" + minuteString;
|
|
}
|
|
return minuteString;
|
|
}
|
|
|
|
// 0: Monday, 1: Tuesday ... 6: Sunday
|
|
inline unsigned int WeekdayIndexFromTimePoint(const TimePoint &tp)
|
|
{
|
|
auto ymw = date::year_month_weekday{std::chrono::floor<date::days>(tp)};
|
|
return ymw.weekday().iso_encoding() - 1;
|
|
}
|
|
|
|
inline std::string createUID()
|
|
{
|
|
constexpr uint32_t bufferLimit = 16;
|
|
char Buffer[bufferLimit];
|
|
utils::time::Timestamp timestamp;
|
|
std::string UID{timestamp.str("%Y%m%dT%H%M%S")};
|
|
UID += '-';
|
|
std::random_device rd;
|
|
std::mt19937 gen(rd());
|
|
std::uniform_int_distribution<> distrib(1, 100);
|
|
sprintf(Buffer, "%d", distrib(gen));
|
|
UID += Buffer;
|
|
|
|
return UID;
|
|
}
|
|
|
|
#endif
|
|
// DATECOMMON_H
|