~aleteoryx/muditaos

ref: 09761da170faa207c5d899d2132a3cc67dad5a31 muditaos/module-utils/time/time_conversion.hpp -rw-r--r-- 10.0 KiB
09761da1 — DariuszSabala [BH-369] Fixed UTF8 unit test CI run 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#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 <log.hpp>

#include <vector>
#include <string>

namespace utils
{
    namespace time
    {
        inline constexpr auto secondsInMinute        = 60;
        inline constexpr auto minutesInHour          = 60;
        inline constexpr auto hoursInday             = 24;
        inline constexpr auto minutesInQuarterOfHour = 15;
        inline constexpr auto secondsInHour          = minutesInHour * secondsInMinute;
        inline constexpr auto secondsInDay           = hoursInday * secondsInHour;
        inline constexpr auto milisecondsInSecond    = 1000;

        enum class GetParameters
        {
            Hour,
            Minute,
            Day,
            Month,
            Year
        };

        // helper class to not put everything in time
        struct Localer
        {
            /// see specifiers_replacements description above
            enum Replacements
            {
                DayAbbrev,
                DayLong,
                MonthAbbrev,
                MonthLong,
                Timezone,
            };

            UTF8 get_replacement(Replacements val, const struct tm &timeinfo);
        };

        class Duration; // fw decl

        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;
            }

          public:
            Timestamp();
            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 *fmt);
            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;
            }
            friend Duration operator-(const Timestamp &lhs, const Timestamp &rhs);
            friend Timestamp operator-(const Timestamp &lhs, const Duration &rhs);
            friend Timestamp operator+(const Timestamp &lhs, const Duration &rhs);
            friend Timestamp operator+(const Duration &lhs, const Timestamp &rhs);

            friend inline bool operator==(const Timestamp &lhs, const Timestamp &rhs)
            {
                return lhs.time == rhs.time;
            }
            friend inline bool operator!=(const Timestamp &lhs, const Timestamp &rhs)
            {
                return lhs.time != rhs.time;
            }
            friend inline bool operator<(const Timestamp &lhs, const Timestamp &rhs)
            {
                return lhs.time < rhs.time;
            }
            friend inline bool operator>(const Timestamp &lhs, const Timestamp &rhs)
            {
                return lhs.time > rhs.time;
            }
            friend inline bool operator<=(const Timestamp &lhs, const Timestamp &rhs)
            {
                return lhs.time <= rhs.time;
            }
            friend inline bool operator>=(const Timestamp &lhs, const Timestamp &rhs)
            {
                return lhs.time >= rhs.time;
            }

            /// 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() const
            {
                return time;
            };

            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
        /// 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)
                : Timestamp(std::time(nullptr)), 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 fmt = "");
            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;
        };

        class Duration
        {
          public:
            /// Duration display format is generally in a form of hh:mm::ss or mm::ss with and without leading 0s
            /// @note hh may exceed 24, mm may exceed 60
            ///
            /// All the predefined format are stored in language json files.
            /// They are configurable by string replacement specifiers with (e.g. %0H) and without (e.g. %H) leading 0s.
            /// * %H / %0H - hours
            /// * %M / %0M - minutes
            /// * %N / %0N - hours and minutes (in minutes)
            /// * %S / %0S - seconds
            enum class DisplayedFormat
            {
                Fixed0M0S,  /// fixed format                          e.g.   00:00,   01:01,   12:12,   89:01,  1643:14
                FixedH0M0S, /// fixed format                          e.g. 0:00:00, 0:01:01, 0:12:12, 1:29:01, 27:23:14
                AutoM,      /// auto format without leading 0 in min  e.g.    0:00,    1:01,   12:12, 1:29:01, 27:23:14
                Auto0M      /// auto format with leading 0 in min     e.g.   00:00,   01:01,   12:12, 1:29:01, 27:23:14
            };

            Duration(time_t duration = 0);
            Duration(time_t stop, time_t start);
            Duration(const Timestamp &stop, const Timestamp &start);

            time_t get() const
            {
                return duration;
            }

            time_t getMinutes() const
            {
                return minutes;
            }

            time_t getHours() const
            {
                return hours;
            }

            UTF8 str(DisplayedFormat displayedFormat = DisplayedFormat::Auto0M) const;

            // uses default format
            friend inline std::ostream &operator<<(std::ostream &os, Duration t)
            {
                os << t.str();
                return os;
            }

            friend Timestamp operator-(const Timestamp &lhs, const Duration &rhs);
            friend Timestamp operator+(const Timestamp &lhs, const Duration &rhs);
            friend Timestamp operator+(const Duration &lhs, const Timestamp &rhs);

            friend inline Duration operator+(const Duration &lhs, const Duration &rhs)
            {
                return Duration(lhs.duration + rhs.duration);
            }
            friend inline Duration operator-(const Duration &lhs, const Duration &rhs)
            {
                return Duration(lhs.duration > rhs.duration ? lhs.duration - rhs.duration : 0);
            }
            friend inline bool operator==(const Duration &lhs, const Duration &rhs)
            {
                return lhs.duration == rhs.duration;
            }
            friend inline bool operator!=(const Duration &lhs, const Duration &rhs)
            {
                return lhs.duration != rhs.duration;
            }
            friend inline bool operator<(const Duration &lhs, const Duration &rhs)
            {
                return lhs.duration < rhs.duration;
            }
            friend inline bool operator>(const Duration &lhs, const Duration &rhs)
            {
                return lhs.duration > rhs.duration;
            }
            friend inline bool operator<=(const Duration &lhs, const Duration &rhs)
            {
                return lhs.duration <= rhs.duration;
            }
            friend inline bool operator>=(const Duration &lhs, const Duration &rhs)
            {
                return lhs.duration >= rhs.duration;
            }

          private:
            void fillStr(std::string &formatlong) const;
            void calculate();
            time_t duration         = 0;
            unsigned long hours     = 0;
            unsigned long hmminutes = 0;
            unsigned long minutes   = 0;
            unsigned long seconds   = 0;
        };

        Timestamp getCurrentTimestamp();
    } // namespace time
} // namespace utils