Files
MuditaOS/module-utils/time/time_conversion.hpp
Radoslaw Wicik a8573a404c Apply new style
2020-03-17 10:03:16 +01:00

172 lines
5.5 KiB
C++

#pragma once
/// beware time_t size might vary, as i.e. on linux it's long int (64b -> 8B != 4B)
/// this calss uses strftime to convert timestamp to text, but for UTF8 elements (mon,day) it uses our locale
/// as stdlib builtin locale doesn't provide way to substitute C-LOCALE
#include "time/time_locale.hpp"
#include <bsp/rtc/rtc.hpp>
#include <vector>
#include <string>
#include <log/log.hpp>
namespace utils
{
namespace time
{
enum class GetParameters
{
Hour,
Minute,
Day,
Month,
Year
};
// helper class to not put everything in time
struct Localer
{
const unsigned int abbrev_len = 3;
/// order matters, it's used in replace_locale with enum Replacements
const std::vector<std::string> specifiers_replacement = {"%a", // day abbrew
"%A", // day long
"%b", // month abbrew
"%B", // month long
"%Z"}; // timezone
/// see specifiers_replacements description above
enum Replacements
{
DayAbbrev,
DayLong,
MonthAbbrev,
MonthLong,
Timezone,
};
UTF8 get_replacement(Replacements val, const struct tm &timeinfo);
};
class Timestamp : protected Localer
{
protected:
time_t time = 0;
struct tm timeinfo;
/// only reformat on: new format
std::string format = "";
explicit operator UTF8 *() const
{
return nullptr;
}
static const uint32_t datasize = 128;
char data[datasize];
/// replace day mon specifiers (first 2 characters)
/// cant use std::replace -> due to fact that it doesn't support multiple element replace (or i cant find
/// it) cant use string::replace -> expcetion out_of_range on size when replacing with bigger (our case)
/// please be vary when using begin_pos/found_pos (as format in next loops might be in totally different
/// place)
void replace_specifiers();
public:
Timestamp()
{
auto err = bsp::rtc_GetCurrentTimestamp(&time);
if (err) {
LOG_ERROR("rtc_GetCurrentTimestamp failure!");
}
timeinfo = *localtime(&time);
}
Timestamp(time_t newtime) : time(newtime)
{
timeinfo = *localtime(&time);
}
/// set Time time_t value held (set timestamp)
void set_time(time_t newtime);
/// set Time from string
void set_time(std::string time, const char *format);
void set_format(std::string format)
{
this->format = format;
}
operator UTF8()
{
return str();
}
friend std::ostream &operator<<(std::ostream &os, Timestamp t)
{
os << t.str();
return os;
}
/// get Time in any format possible via strftime
virtual UTF8 str(std::string format = "");
/// get day UTF8 value
UTF8 day(bool abbrev = false);
/// get month UTF8 value
UTF8 month(bool abbrev = false);
// get timestamp value
time_t getTime(void)
{
return time;
};
UTF8 get_date_time_substr(GetParameters param);
uint32_t get_date_time_sub_value(GetParameters param);
};
/// helper class to operate on time now
/// takes timestamp and can show time in past
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
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, DateTime t)
{
os << t.str();
return os;
}
/// converter -> returns time in past: (val) and stores localtime in ref_time
void before_n_sec(time_t val);
/// Time have str(std::string ) this one uses presets
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;
};
}; // namespace time
}; // namespace utils