Time Shield Library
C++ library for working with time
Loading...
Searching...
No Matches
time_parser.hpp
Go to the documentation of this file.
1#pragma once
7#ifndef _TIME_SHIELD_TIME_PARSER_HPP_INCLUDED
8#define _TIME_SHIELD_TIME_PARSER_HPP_INCLUDED
9
10#include "enums.hpp"
11#include "constants.hpp"
12#include "date_time_struct.hpp"
13#include "time_zone_struct.hpp"
14#include "validation.hpp"
15#include "time_conversions.hpp"
16#include <regex>
17#include <algorithm>
18#include <locale>
19#include <array>
20#include <stdexcept>
21
22namespace time_shield {
23
29 template<class T = Month>
30 const T get_month_number(const std::string& month) {
31 if (month.empty()) throw std::invalid_argument("Invalid month name");
32
33 std::string month_copy = month;
34 std::transform(month_copy .begin(), month_copy .end(), month_copy .begin(), [](char &ch) {
35 return std::use_facet<std::ctype<char>>(std::locale()).tolower(ch);
36 });
37 month_copy [0] = toupper(month_copy [0]);
38
39 static const std::array<std::string, 12> short_names = {
40 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
41 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
42 };
43 static const std::array<std::string, 12> full_names = {
44 "January", "February", "March", "April", "May", "June",
45 "July", "August", "September", "October", "November", "December"
46 };
47
48 for(int i = 0; i < MONTHS_PER_YEAR; ++i) {
49 if (month == short_names[i] || month == full_names[i]) {
50 return static_cast<T>(i + 1);
51 }
52 }
53 throw std::invalid_argument("Invalid month name");
54 }
55
58 template<class T = Month>
59 const T month_of_year(const std::string& month) {
60 return get_month_number(month);
61 }
62
63//------------------------------------------------------------------------------
64
70 template<class T = Month>
71 const bool try_get_month_number(const std::string& month, T& value) {
72 if (month.empty()) return false;
73
74 std::string month_copy = month;
75 std::transform(month_copy.begin(), month_copy.end(), month_copy.begin(), [](char &ch) {
76 return std::use_facet<std::ctype<char>>(std::locale()).tolower(ch);
77 });
78 month_copy[0] = toupper(month_copy[0]);
79
80 static const std::array<std::string, MONTHS_PER_YEAR> short_names = {
81 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
82 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
83 };
84 static const std::array<std::string, MONTHS_PER_YEAR> full_names = {
85 "January", "February", "March", "April", "May", "June",
86 "July", "August", "September", "October", "November", "December"
87 };
88
89 for (int i = 0; i < MONTHS_PER_YEAR; ++i) {
90 if (month_copy == short_names[i] || month_copy == full_names[i]) {
91 value = static_cast<T>(i + 1);
92 return true;
93 }
94 }
95 return false;
96 }
97
100 template<class T = Month>
101 const bool get_month_number(const std::string& month, T& value) {
102 return try_get_month_number(month, value);
103 }
104
107 template<class T = Month>
108 const bool month_of_year(const std::string& month, T& value) {
109 return try_get_month_number(month, value);
110 }
111
112//------------------------------------------------------------------------------
113
120 const bool parse_time_zone(const std::string& tz_str, TimeZoneStruct &tz) {
121 if (tz_str.empty()) {
122 tz.hour = 0;
123 tz.min = 0;
124 tz.is_positive = true;
125 return true;
126 }
127 if (tz_str == "Z") {
128 tz.hour = 0;
129 tz.min = 0;
130 tz.is_positive = true;
131 return true;
132 }
133 tz.is_positive = (tz_str[0] == '+');
134 tz.hour = std::stoi(tz_str.substr(1, 2));
135 tz.min = std::stoi(tz_str.substr(4, 2));
136 return is_valid_time_zone(tz);
137 }
138
141 inline const bool parse_tz(const std::string& tz_str, TimeZoneStruct &tz) {
142 return parse_time_zone(tz_str, tz);
143 }
144
145//------------------------------------------------------------------------------
146
154 const bool parse_iso8601(
155 const std::string& input,
156 DateTimeStruct &dt,
157 TimeZoneStruct &tz) {
158 // Регулярное выражение для даты в формате ISO8601
159 static const std::regex date_regex(R"((\d{4})[-\/\.](\d{2})[-\/\.](\d{2}))");
160 std::smatch date_match;
161
162 // Регулярное выражение для времени в формате ISO8601 с часовым поясом и без
163 static const std::regex time_regex(R"((\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:\d{2})?)");
164 std::smatch time_match;
165
167 tz = create_time_zone_struct(0, 0);
168
169 // Парсинг даты
170 if (std::regex_search(input, date_match, date_regex)) {
171 dt.year = std::stoll(date_match[1].str());
172 dt.mon = std::stoi(date_match[2].str());
173 dt.day = std::stoi(date_match[3].str());
174 } else {
175 return false;
176 }
177
178 // Парсинг времени и часового пояса
179 if (std::regex_search(input, time_match, time_regex)) {
180 dt.hour = std::stoi(time_match[1].str());
181 dt.min = std::stoi(time_match[2].str());
182 dt.sec = std::stoi(time_match[3].str());
183 if (time_match[4].matched) {
184 dt.ms = std::stoi(time_match[4].str());
185 }
186 if (time_match[5].matched) {
187 if (!parse_time_zone(time_match[5].str(), tz)) return false;
188 }
189 return is_valid_date_time(dt);
190 }
191 return true;
192 }
193
199 inline const bool str_to_ts(const std::string &str, ts_t& ts) {
202 if (!parse_iso8601(str, dt, tz)) return false;
203 try {
204 ts = to_timestamp(dt) + to_offset(tz);
205 return true;
206 } catch(...) {}
207 return false;
208 }
209
215 inline const bool str_to_ts_ms(const std::string &str, ts_ms_t& ts) {
218 if (!parse_iso8601(str, dt, tz)) return false;
219 try {
221 return true;
222 } catch(...) {}
223 return false;
224 }
225
231 inline const bool str_to_fts(const std::string &str, fts_t& ts) {
234 if (!parse_iso8601(str, dt, tz)) return false;
235 try {
236 ts = to_ftimestamp(dt) + static_cast<fts_t>(to_offset(tz));
237 return true;
238 } catch(...) {}
239 return false;
240 }
241
247 inline const ts_t ts(const std::string& str) {
248 ts_t ts = 0;
249 str_to_ts(str, ts);
250 return ts;
251 }
252
258 inline const ts_ms_t ts_ms(const std::string& str) {
259 ts_ms_t ts = 0;
260 str_to_ts_ms(str, ts);
261 return ts;
262 }
263
269 inline const fts_t fts(const std::string& str) {
270 fts_t ts = 0;
271 str_to_fts(str, ts);
272 return ts;
273 }
274
275
281 inline const ts_t ts(const char *str) {
282 ts_t ts = 0;
283 str_to_ts(str, ts);
284 return ts;
285 }
286
292 inline const ts_ms_t ts_ms(const char *str) {
293 ts_ms_t ts = 0;
294 str_to_ts_ms(str, ts);
295 return ts;
296 }
297
303 inline const fts_t fts(const char *str) {
304 fts_t ts = 0;
305 str_to_fts(str, ts);
306 return ts;
307 }
308};
309
310#endif // _TIME_SHIELD_TIME_PARSER_HPP_INCLUDED
Header file with time-related constants.
Header for date and time structure and related functions.
Header file with enumerations for weekdays, months, and other time-related categories.
Main namespace for the Time Shield library.
Definition constants.hpp:12
const int64_t MONTHS_PER_YEAR
Months per year.
Definition constants.hpp:56
const bool try_get_month_number(const std::string &month, T &value)
Get the month number by name, with output parameter.
TIME_SHIELD_CONSTEXPR const T month_of_year(const ts_t &ts) noexcept
Get the month of the year.
int64_t ts_t
Integer timestamp type.
Definition types.hpp:15
TIME_SHIELD_CONSTEXPR const fts_t to_ftimestamp(const T1 &year, const T2 &month, const T2 &day, const T2 &hour=0, const T2 &min=0, const T2 &sec=0, const T3 &ms=0)
Converts a date and time to a floating-point timestamp.
const TimeZoneStruct create_time_zone_struct(const int &hour, const int &min, const bool &is_positive=true)
Creates a TimeZoneStruct instance.
const bool parse_time_zone(const std::string &tz_str, TimeZoneStruct &tz)
Parse a time zone string into a TimeZoneStruct.
TIME_SHIELD_CONSTEXPR const ts_t to_timestamp(const T1 &year, const T2 &month, const T2 &day, const T2 &hour=0, const T2 &min=0, const T2 &sec=0)
Converts a date and time to a timestamp.
TIME_SHIELD_CONSTEXPR const bool is_valid_time_zone(const T &hour, const T &min) noexcept
Check if the time zone is valid.
const bool str_to_fts(const std::string &str, fts_t &ts)
Convert an ISO8601 string to a floating-point timestamp (fts_t).
int64_t ts_ms_t
Integer timestamp milliseconds type.
Definition types.hpp:16
const bool str_to_ts_ms(const std::string &str, ts_ms_t &ts)
Convert an ISO8601 string to a millisecond timestamp (ts_ms_t).
const bool str_to_ts(const std::string &str, ts_t &ts)
Convert an ISO8601 string to a timestamp (ts_t).
const bool parse_tz(const std::string &tz_str, TimeZoneStruct &tz)
Alias for parse_time_zone function.
constexpr const T1 sec_to_ms(const T2 &ts) noexcept
Converts a timestamp from seconds to milliseconds.
const ts_ms_t ts_ms() noexcept
Get the current UTC timestamp in milliseconds.
const DateTimeStruct create_date_time_struct(const int64_t &year, const int &mon=1, const int &day=1, const int &hour=0, const int &min=0, const int &sec=0, const int &ms=0)
Creates a DateTimeStruct instance.
double fts_t
Floating point timestamp type.
Definition types.hpp:18
const T get_month_number(const std::string &month)
Get the month number by name.
const fts_t fts() noexcept
Get the current UTC timestamp in floating-point seconds.
TIME_SHIELD_CONSTEXPR const bool is_valid_date_time(const T1 &year, const T2 &month, const T2 &day, const T2 &hour=0, const T2 &min=0, const T2 &sec=0, const T3 &ms=0) noexcept
Checks the correctness of a date and time.
const ts_t ts() noexcept
Get the current UTC timestamp in seconds.
TIME_SHIELD_CONSTEXPR const ts_ms_t to_timestamp_ms(const T1 &year, const T2 &month, const T2 &day, const T2 &hour=0, const T2 &min=0, const T2 &sec=0, const T2 &ms=0)
Converts a date and time to a timestamp in milliseconds.
const bool parse_iso8601(const std::string &input, DateTimeStruct &dt, TimeZoneStruct &tz)
Parse a date and time string in ISO8601 format.
const tz_t to_offset(const TimeZoneStruct &tz)
Alias for time_zone_struct_to_offset function.
Structure to represent date and time.
int ms
Millisecond component of time (0-999)
int hour
Hour component of time (0-23)
int64_t year
Year component of the date.
int day
Day component of the date (1-31).
int min
Minute component of time (0-59)
int mon
Month component of the date (1-12).
int sec
Second component of time (0-59)
Structure to represent time zone information.
int hour
Hour component of time (0-23)
int min
Minute component of time (0-59)
bool is_positive
True if the time zone offset is positive, false if negative.
Header file for time conversion functions.
Header for time zone structure and related functions.
Header file with time-related validation functions.