Time Shield Library
C++ library for working with time
Loading...
Searching...
No Matches
date_time_conversions.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2#pragma once
3#ifndef _TIME_SHIELD_DATE_TIME_CONVERSIONS_HPP_INCLUDED
4#define _TIME_SHIELD_DATE_TIME_CONVERSIONS_HPP_INCLUDED
5
8
9#include "config.hpp"
10#include "constants.hpp"
11#include "date_conversions.hpp"
12#include "date_struct.hpp"
13#include "date_time_struct.hpp"
14#include "detail/fast_date.hpp"
15#include "detail/floor_math.hpp"
16#include "enums.hpp"
18#include "time_utils.hpp"
19#include "types.hpp"
21#include "validation.hpp"
22
23#include <cmath>
24#include <ctime>
25#include <limits>
26#include <stdexcept>
27#include <type_traits>
28
29namespace time_shield {
30
33
34 namespace legacy {
35
46 template<class T1 = DateTimeStruct, class T2 = ts_t>
48 // 9223372029693630000 - значение на момент 292277024400 от 2000 года
49 // Такое значение приводит к неправильному вычислению умножения n_400_years * SEC_PER_400_YEARS
50 // Поэтому пришлось снизить до 9223371890843040000
51 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
52 constexpr int64_t BIAS_2000 = 946684800LL;
53
54 int64_t y = MAX_YEAR;
55 int64_t secs = -((static_cast<int64_t>(ts) - BIAS_2000) - BIAS_292277022000);
56
57 const int64_t n_400_years = secs / SEC_PER_400_YEARS;
58 secs -= n_400_years * SEC_PER_400_YEARS;
59 y -= n_400_years * 400LL;
60
61 const int64_t n_100_years = secs / SEC_PER_100_YEARS;
62 secs -= n_100_years * SEC_PER_100_YEARS;
63 y -= n_100_years * 100LL;
64
65 const int64_t n_4_years = secs / SEC_PER_4_YEARS;
66 secs -= n_4_years * SEC_PER_4_YEARS;
67 y -= n_4_years * 4LL;
68
69 const int64_t n_1_years = secs / SEC_PER_YEAR;
70 secs -= n_1_years * SEC_PER_YEAR;
71 y -= n_1_years;
72
73 T1 date_time;
74
75 if (secs == 0) {
76 date_time.year = y;
77 date_time.mon = 1;
78 date_time.day = 1;
79 return date_time;
80 }
81
82 date_time.year = y - 1;
83 const bool is_leap_year = is_leap_year_date(date_time.year);
84 secs = is_leap_year ? SEC_PER_LEAP_YEAR - secs : SEC_PER_YEAR - secs;
85 const int days = static_cast<int>(secs / SEC_PER_DAY);
86
87 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60 - 1;
88 constexpr int TABLE_MONTH_OF_YEAR[] = {
89 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 31 январь
90 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 28 февраль
91 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 31 март
92 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 30 апрель
93 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
94 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
95 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
96 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
97 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
98 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
99 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
100 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
101 };
102 constexpr int TABLE_DAY_OF_YEAR[] = {
103 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, // 31 январь
104 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, // 28 февраль
105 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, // 31 март
106 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, // 30 апрель
107 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,
108 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,
109 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,
110 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,
111 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,
112 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,
113 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,
114 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,
115 };
116
117 if (is_leap_year) {
118 const int prev_days = days - 1;
119 date_time.day = days == JAN_AND_FEB_DAY_LEAP_YEAR ? (TABLE_DAY_OF_YEAR[prev_days] + 1) :
120 (days > JAN_AND_FEB_DAY_LEAP_YEAR ? TABLE_DAY_OF_YEAR[prev_days] : TABLE_DAY_OF_YEAR[days]);
121 date_time.mon = days >= JAN_AND_FEB_DAY_LEAP_YEAR ? TABLE_MONTH_OF_YEAR[prev_days] : TABLE_MONTH_OF_YEAR[days];
122 } else {
123 date_time.day = TABLE_DAY_OF_YEAR[days];
124 date_time.mon = TABLE_MONTH_OF_YEAR[days];
125 }
126
127 ts_t day_secs = static_cast<ts_t>(detail::floor_mod(secs, SEC_PER_DAY));
128 date_time.hour = static_cast<decltype(date_time.hour)>(day_secs / SEC_PER_HOUR);
129 ts_t min_secs = static_cast<ts_t>(day_secs - date_time.hour * SEC_PER_HOUR);
130 date_time.min = static_cast<decltype(date_time.min)>(min_secs / SEC_PER_MIN);
131 date_time.sec = static_cast<decltype(date_time.sec)>(min_secs - date_time.min * SEC_PER_MIN);
132# ifdef TIME_SHIELD_CPP17
133 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T2>::value) {
134 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
135 } else date_time.ms = 0;
136# else
137 if (std::is_floating_point<T2>::value) {
138 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
139 } else date_time.ms = 0;
140# endif
141 return date_time;
142 }
143
144 } // namespace legacy
145
159 template<class T1 = DateTimeStruct, class T2 = ts_t>
161 const int64_t whole_sec = static_cast<int64_t>(ts);
162 const detail::DaySplit split = detail::split_unix_day(whole_sec);
164
165 T1 date_time{};
166 date_time.year = static_cast<decltype(date_time.year)>(date.year);
167 date_time.mon = static_cast<decltype(date_time.mon)>(date.month);
168 date_time.day = static_cast<decltype(date_time.day)>(date.day);
169
170 const ts_t day_secs = static_cast<ts_t>(split.sec_of_day);
171 date_time.hour = static_cast<decltype(date_time.hour)>(day_secs / SEC_PER_HOUR);
172 const ts_t min_secs = static_cast<ts_t>(day_secs - date_time.hour * SEC_PER_HOUR);
173 date_time.min = static_cast<decltype(date_time.min)>(min_secs / SEC_PER_MIN);
174 date_time.sec = static_cast<decltype(date_time.sec)>(min_secs - date_time.min * SEC_PER_MIN);
175# ifdef TIME_SHIELD_CPP17
176 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T2>::value) {
177 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
178 } else date_time.ms = 0;
179# else
180 if (std::is_floating_point<T2>::value) {
181 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
182 } else date_time.ms = 0;
183# endif
184 return date_time;
185 }
186
192 template<class T>
194 const ts_t sec = ms_to_sec<ts_t, ts_ms_t>(ts);
195 T date_time = to_date_time<T, ts_t>(sec);
196 date_time.ms = ms_of_ts(ts); // Extract and set the ms component
197 return date_time;
198 }
199
200 namespace legacy {
201
232 template<class T1 = year_t, class T2 = int>
233 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp(
234 T1 year,
235 T2 month,
236 T2 day,
237 T2 hour = 0,
238 T2 min = 0,
239 T2 sec = 0) {
240
241 if (day >= UNIX_EPOCH && year <= 31) {
242 return to_timestamp((T1)day, month, (T2)year, hour, min, sec);
243 }
244 if (!is_valid_date_time(year, month, day, hour, min, sec)) {
245 throw std::invalid_argument("Invalid date-time combination");
246 }
247
248 int64_t secs = 0;
249 int64_t years = (static_cast<int64_t>(MAX_YEAR) - year);
250
251 const int64_t n_400_years = years / 400LL;
252 secs += n_400_years * SEC_PER_400_YEARS;
253 years -= n_400_years * 400LL;
254
255 const int64_t n_100_years = years / 100LL;
256 secs += n_100_years * SEC_PER_100_YEARS;
257 years -= n_100_years * 100LL;
258
259 const int64_t n_4_years = years / 4LL;
260 secs += n_4_years * SEC_PER_4_YEARS;
261 years -= n_4_years * 4LL;
262
263 secs += years * SEC_PER_YEAR;
264
265 // 9223372029693630000 - значение на момент 292277024400 от 2000 года
266 // Такое значение приводит к неправильному вычислению умножения n_400_years * SEC_PER_400_YEARS
267 // Поэтому пришлось снизить до 9223371890843040000
268 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
269 constexpr int64_t BIAS_2000 = 946684800LL;
270
271 secs = BIAS_292277022000 - secs;
272 secs += BIAS_2000;
273
274 if (month == 1 && day == 1 &&
275 hour == 0 && min == 0 &&
276 sec == 0) {
277 return secs;
278 }
279
280 constexpr int lmos[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
281 constexpr int mos[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
282
283 secs += (is_leap_year_date(year) ? (lmos[month - 1] + day - 1) : (mos[month - 1] + day - 1)) * SEC_PER_DAY;
284 secs += SEC_PER_HOUR * hour + SEC_PER_MIN * min + sec;
285 return secs;
286 }
287
305 template<class T1 = year_t, class T2 = int>
306 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp_unchecked(
307 T1 year,
308 T2 month,
309 T2 day,
310 T2 hour = 0,
311 T2 min = 0,
312 T2 sec = 0) noexcept {
313
314 if (day >= UNIX_EPOCH && year <= 31) {
315 return to_timestamp_unchecked((T1)day, month, (T2)year, hour, min, sec);
316 }
317
318 int64_t secs = 0;
319 int64_t years = (static_cast<int64_t>(MAX_YEAR) - year);
320
321 const int64_t n_400_years = years / 400LL;
322 secs += n_400_years * SEC_PER_400_YEARS;
323 years -= n_400_years * 400LL;
324
325 const int64_t n_100_years = years / 100LL;
326 secs += n_100_years * SEC_PER_100_YEARS;
327 years -= n_100_years * 100LL;
328
329 const int64_t n_4_years = years / 4LL;
330 secs += n_4_years * SEC_PER_4_YEARS;
331 years -= n_4_years * 4LL;
332
333 secs += years * SEC_PER_YEAR;
334
335 // 9223372029693630000 - значение на момент 292277024400 от 2000 года
336 // Такое значение приводит к неправильному вычислению умножения n_400_years * SEC_PER_400_YEARS
337 // Поэтому пришлось снизить до 9223371890843040000
338 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
339 constexpr int64_t BIAS_2000 = 946684800LL;
340
341 secs = BIAS_292277022000 - secs;
342 secs += BIAS_2000;
343
344 if (month == 1 && day == 1 &&
345 hour == 0 && min == 0 &&
346 sec == 0) {
347 return secs;
348 }
349
350 constexpr int lmos[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
351 constexpr int mos[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
352
353 secs += (is_leap_year_date(year) ? (lmos[month - 1] + day - 1) : (mos[month - 1] + day - 1)) * SEC_PER_DAY;
354 secs += SEC_PER_HOUR * hour + SEC_PER_MIN * min + sec;
355 return secs;
356 }
357
358 } // namespace legacy
359
381 template<class T1 = year_t, class T2 = int>
382 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp_unchecked(
383 T1 year,
384 T2 month,
385 T2 day,
386 T2 hour = 0,
387 T2 min = 0,
388 T2 sec = 0) noexcept {
389
390 if (day >= UNIX_EPOCH && year <= 31) {
391 return to_timestamp_unchecked((T1)day, month, (T2)year, hour, min, sec);
392 }
393
394 const dse_t unix_day = date_to_unix_day(year, month, day);
395 return static_cast<ts_t>(unix_day * SEC_PER_DAY
396 + SEC_PER_HOUR * static_cast<int64_t>(hour)
397 + SEC_PER_MIN * static_cast<int64_t>(min)
398 + static_cast<int64_t>(sec));
399 }
400
435 template<class T1 = year_t, class T2 = int>
436 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp(
437 T1 year,
438 T2 month,
439 T2 day,
440 T2 hour = 0,
441 T2 min = 0,
442 T2 sec = 0) {
443
444 if (day >= UNIX_EPOCH && year <= 31) {
445 return to_timestamp((T1)day, month, (T2)year, hour, min, sec);
446 }
447 if (!is_valid_date_time(year, month, day, hour, min, sec)) {
448 throw std::invalid_argument("Invalid date-time combination");
449 }
450
451 return to_timestamp_unchecked(year, month, day, hour, min, sec);
452 }
453
464 template<class T>
465 TIME_SHIELD_CONSTEXPR inline ts_t dt_to_timestamp(
466 const T& date_time) {
467 return to_timestamp(
468 date_time.year,
469 date_time.mon,
470 date_time.day,
471 date_time.hour,
472 date_time.min,
473 date_time.sec
474 );
475 }
476
485 TIME_SHIELD_CONSTEXPR inline ts_t tm_to_timestamp(
486 const std::tm *timeinfo) {
487 return to_timestamp(
488 static_cast<year_t>(timeinfo->tm_year + 1900),
489 static_cast<int>(timeinfo->tm_mon + 1),
490 static_cast<int>(timeinfo->tm_mday),
491 static_cast<int>(timeinfo->tm_hour),
492 static_cast<int>(timeinfo->tm_min),
493 static_cast<int>(timeinfo->tm_sec)
494 );
495 }
496
514 template<class T1 = year_t, class T2 = int>
515 TIME_SHIELD_CONSTEXPR inline ts_ms_t to_timestamp_ms(
516 T1 year,
517 T2 month,
518 T2 day,
519 T2 hour = 0,
520 T2 min = 0,
521 T2 sec = 0,
522 T2 ms = 0) {
523 int64_t sec_value = static_cast<int64_t>(to_timestamp<T1, T2>(year, month, day, hour, min, sec));
524 int64_t ms_value = static_cast<int64_t>(ms);
525 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
526 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
527 if ((sec_value > 0 &&
528 sec_value > ((std::numeric_limits<int64_t>::max)() - ms_value) / MS_PER_SEC) ||
529 (sec_value < 0 &&
530 sec_value < (std::numeric_limits<int64_t>::min)() / MS_PER_SEC)) {
531 return ERROR_TIMESTAMP;
532 }
533 return static_cast<ts_ms_t>(sec_value * MS_PER_SEC + ms_value);
534 }
535
546 template<class T>
547 TIME_SHIELD_CONSTEXPR inline ts_ms_t dt_to_timestamp_ms(
548 const T& date_time) {
549 int64_t sec_value = static_cast<int64_t>(dt_to_timestamp(date_time));
550 int64_t ms_value = static_cast<int64_t>(date_time.ms);
551 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
552 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
553 if ((sec_value > 0 &&
554 sec_value > ((std::numeric_limits<int64_t>::max)() - ms_value) / MS_PER_SEC) ||
555 (sec_value < 0 &&
556 sec_value < (std::numeric_limits<int64_t>::min)() / MS_PER_SEC)) {
557 return ERROR_TIMESTAMP;
558 }
559 return static_cast<ts_ms_t>(sec_value * MS_PER_SEC + ms_value);
560 }
561
570 TIME_SHIELD_CONSTEXPR inline ts_t tm_to_timestamp_ms(
571 const std::tm *timeinfo) {
572 return sec_to_ms(tm_to_timestamp(timeinfo));
573 }
574
593 template<class T1 = year_t, class T2 = int, class T3 = int>
594 TIME_SHIELD_CONSTEXPR inline fts_t to_ftimestamp(
595 T1 year,
596 T2 month,
597 T2 day,
598 T2 hour = 0,
599 T2 min = 0,
600 T2 sec = 0,
601 T3 ms = 0) {
602 int64_t sec_value = static_cast<int64_t>(to_timestamp(year, month, day, hour, min, sec));
603 int64_t ms_value = static_cast<int64_t>(ms);
604 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
605 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
606 return static_cast<fts_t>(sec_value) +
607 static_cast<fts_t>(ms_value) / static_cast<fts_t>(MS_PER_SEC);
608 }
609
621 template<class T>
622 TIME_SHIELD_CONSTEXPR inline fts_t dt_to_ftimestamp(
623 const T& date_time) {
624 int64_t sec_value = static_cast<int64_t>(to_timestamp(date_time));
625 int64_t ms_value = static_cast<int64_t>(date_time.ms);
626 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
627 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
628 return static_cast<fts_t>(sec_value) +
629 static_cast<fts_t>(ms_value) / static_cast<fts_t>(MS_PER_SEC);
630 }
631
641 TIME_SHIELD_CONSTEXPR inline fts_t tm_to_ftimestamp(
642 const std::tm* timeinfo) {
643 return static_cast<fts_t>(tm_to_timestamp(timeinfo));
644 }
645
653 constexpr ts_t start_of_day(ts_t ts = time_shield::ts()) noexcept {
655 }
656
664 template<class T = int>
665 constexpr ts_t start_of_prev_day(ts_t ts = time_shield::ts(), T days = 1) noexcept {
667 }
668
679
690
699 template<class T = int>
700 constexpr ts_t start_of_next_day(ts_t ts, T days = 1) noexcept {
701 return start_of_day(ts) + days * SEC_PER_DAY;
702 }
703
712 template<class T = int>
713 constexpr ts_ms_t start_of_next_day_ms(ts_ms_t ts_ms, T days = 1) noexcept {
715 }
716
724 template<class T = int>
725 constexpr ts_t next_day(ts_t ts, T days = 1) noexcept {
726 return ts + days * SEC_PER_DAY;
727 }
728
736 template<class T = int>
737 constexpr ts_ms_t next_day_ms(ts_ms_t ts_ms, T days = 1) noexcept {
738 return ts_ms + days * MS_PER_DAY;
739 }
740
747 constexpr ts_t end_of_day(ts_t ts = time_shield::ts()) noexcept {
749 }
750
759 }
760
770
774 template<class T = year_t>
775 TIME_SHIELD_CONSTEXPR inline ts_t start_of_year_date(T year) {
776 const ts_t year_ts = to_timestamp(year, 1, 1);
777
778 return start_of_day(year_ts);
779 }
780
788 template<class T = year_t>
789 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_year_date_ms(T year) {
791 }
792
800 TIME_SHIELD_CONSTEXPR inline ts_t start_of_year(ts_t ts) noexcept {
801 constexpr ts_t BIAS_2100 = 4102444800;
802 if (ts >= 0 && ts < BIAS_2100) {
803 constexpr ts_t SEC_PER_YEAR_X2 = SEC_PER_YEAR * 2;
804 ts_t year_start_ts = detail::floor_mod(ts, SEC_PER_4_YEARS);
805 if (year_start_ts < SEC_PER_YEAR) {
806 return ts - year_start_ts;
807 } else if (year_start_ts < SEC_PER_YEAR_X2) {
808 return ts + SEC_PER_YEAR - year_start_ts;
809 } else if (year_start_ts < (SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR)) {
810 return ts + SEC_PER_YEAR_X2 - year_start_ts;
811 }
812 return ts + (SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR) - year_start_ts;
813 }
814
815 constexpr ts_t BIAS_2000 = 946684800;
816 ts_t secs = ts - BIAS_2000;
817
818 ts_t offset_y400 = detail::floor_mod(secs, SEC_PER_400_YEARS);
819 ts_t start_ts = secs - offset_y400 + BIAS_2000;
820 secs = offset_y400;
821
822 if (secs >= SEC_PER_FIRST_100_YEARS) {
824 start_ts += SEC_PER_FIRST_100_YEARS;
825 while (secs >= SEC_PER_100_YEARS) {
826 secs -= SEC_PER_100_YEARS;
827 start_ts += SEC_PER_100_YEARS;
828 }
829
830 constexpr ts_t SEC_PER_4_YEARS_V2 = 4 * SEC_PER_YEAR;
831 if (secs >= SEC_PER_4_YEARS_V2) {
832 secs -= SEC_PER_4_YEARS_V2;
833 start_ts += SEC_PER_4_YEARS_V2;
834 } else {
835 start_ts += secs - detail::floor_mod(secs, SEC_PER_YEAR);
836 return start_ts;
837 }
838 }
839
840 ts_t offset_4y = detail::floor_mod(secs, SEC_PER_4_YEARS);
841 start_ts += secs - offset_4y;
842 secs = offset_4y;
843
844 if (secs >= SEC_PER_LEAP_YEAR) {
845 secs -= SEC_PER_LEAP_YEAR;
846 start_ts += SEC_PER_LEAP_YEAR;
847 start_ts += secs - detail::floor_mod(secs, SEC_PER_YEAR);
848 return start_ts;
849 }
850
851 start_ts += secs - detail::floor_mod(secs, SEC_PER_YEAR);
852 return start_ts;
853 }
854
858 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) {
860 }
861
868 TIME_SHIELD_CONSTEXPR inline ts_t end_of_year(ts_t ts = time_shield::ts()) {
870 const ts_t year_days = static_cast<ts_t>(num_days_in_year_ts(ts));
871 return year_start + year_days * SEC_PER_DAY - 1;
872 }
873
880 template<class T = year_t>
881 TIME_SHIELD_CONSTEXPR inline ts_ms_t end_of_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) {
883 }
884
891 template<class T = int>
893 return static_cast<T>(((ts - start_of_year(ts)) / SEC_PER_DAY) + 1);
894 }
895
902 template<class T = Month>
903 TIME_SHIELD_CONSTEXPR inline T month_of_year(ts_t ts) noexcept {
904 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60;
905 constexpr int TABLE_MONTH_OF_YEAR[] = {
906 0,
907 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 31 январь
908 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 28 февраль
909 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 31 март
910 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, // 30 апрель
911 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
912 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
913 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
914 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
915 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
916 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
917 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
918 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
919 };
920 const size_t dy = day_of_year<size_t>(ts);
921 return static_cast<T>((is_leap_year(ts) && dy >= JAN_AND_FEB_DAY_LEAP_YEAR) ? TABLE_MONTH_OF_YEAR[dy - 1] : TABLE_MONTH_OF_YEAR[dy]);
922 }
923
930 template<class T = int>
931 TIME_SHIELD_CONSTEXPR inline T day_of_month(ts_t ts = time_shield::ts()) {
932 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60;
933 // таблица для обычного года, не високосного
934 constexpr int TABLE_DAY_OF_YEAR[] = {
935 0,
936 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, // 31 январь
937 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, // 28 февраль
938 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, // 31 март
939 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, // 30 апрель
940 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,
941 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,
942 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,
943 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,
944 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,
945 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,
946 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,
947 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,
948 };
949 const size_t dy = day_of_year<size_t>(ts);
950 if(is_leap_year(ts)) {
951 if(dy == JAN_AND_FEB_DAY_LEAP_YEAR) return TABLE_DAY_OF_YEAR[dy - 1] + 1;
952 if(dy > JAN_AND_FEB_DAY_LEAP_YEAR) return TABLE_DAY_OF_YEAR[dy - 1];
953 }
954 return TABLE_DAY_OF_YEAR[dy];
955 }
956
964 template<class T1 = int, class T2 = year_t, class T3 = int>
965 TIME_SHIELD_CONSTEXPR T1 num_days_in_month(T2 year, T3 month) noexcept {
966 constexpr T1 num_days[13] = {0,31,30,31,30,31,30,31,31,30,31,30,31};
967 return (month > MONTHS_PER_YEAR || month < 0)
968 ? static_cast<T1>(0)
969 : (month == FEB ? static_cast<T1>(is_leap_year_date(year) ? 29 : 28) : num_days[month]);
970 }
971
978 template<class T1 = int>
979 TIME_SHIELD_CONSTEXPR T1 num_days_in_month_ts(ts_t ts = time_shield::ts()) noexcept {
980 constexpr T1 num_days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
981 const int month = month_of_year<int>(ts);
982 if (month == FEB) {
983 return is_leap_year(ts) ? 29 : 28;
984 }
985 return num_days[month];
986 }
987
991 template<class T = Weekday>
992 constexpr T weekday_of_ts(ts_t ts) noexcept {
994 return static_cast<T>(detail::floor_mod(days + THU, DAYS_PER_WEEK));
995 }
996
1000 template<class T = Weekday>
1004
1007 template<class T = Weekday>
1008 constexpr T get_weekday_from_ts(ts_t ts) noexcept {
1009 return weekday_of_ts<T>(ts);
1010 }
1011
1014 template<class T = Weekday>
1016 return weekday_of_ts_ms<T>(ts_ms);
1017 }
1018
1026 TIME_SHIELD_CONSTEXPR inline ts_t start_of_month(ts_t ts = time_shield::ts()) {
1027 return start_of_day(ts) - (day_of_month(ts) - 1) * SEC_PER_DAY;
1028 }
1029
1037 TIME_SHIELD_CONSTEXPR inline ts_t end_of_month(ts_t ts = time_shield::ts()) {
1039 }
1040
1048 TIME_SHIELD_CONSTEXPR inline ts_t last_sunday_of_month(ts_t ts = time_shield::ts()) {
1050 }
1051
1059 template<class T1 = int, class T2 = year_t, class T3 = int>
1060 TIME_SHIELD_CONSTEXPR inline T1 last_sunday_month_day(T2 year, T3 month) {
1061 const T1 days = num_days_in_month(year, month);
1062 return days - day_of_week_date(year, month, days);
1063 }
1064
1075
1085 }
1086
1097
1098
1105 constexpr ts_t start_of_hour(ts_t ts = time_shield::ts()) noexcept {
1107 }
1108
1118
1126
1130 constexpr ts_t end_of_hour(ts_t ts = time_shield::ts()) noexcept {
1132 }
1133
1139 }
1140
1147
1151 constexpr ts_t start_of_min(ts_t ts = time_shield::ts()) noexcept {
1153 }
1154
1158 constexpr ts_t end_of_min(ts_t ts = time_shield::ts()) noexcept {
1160 }
1161
1166 template<class T = int>
1167 constexpr T min_of_day(ts_t ts = time_shield::ts()) noexcept {
1168 const ts_t minutes = detail::floor_div(ts, SEC_PER_MIN);
1169 return static_cast<T>(detail::floor_mod(minutes, MIN_PER_DAY));
1170 }
1171
1176 template<class T = int>
1177 constexpr T hour_of_day(ts_t ts = time_shield::ts()) noexcept {
1178 const ts_t hours = detail::floor_div(ts, SEC_PER_HOUR);
1179 return static_cast<T>(detail::floor_mod(hours, HOURS_PER_DAY));
1180 }
1181
1186 template<class T = int>
1187 constexpr T min_of_hour(ts_t ts = time_shield::ts()) noexcept {
1188 const ts_t minutes = detail::floor_div(ts, SEC_PER_MIN);
1189 return static_cast<T>(detail::floor_mod(minutes, MIN_PER_HOUR));
1190 }
1191
1196 template<class T = int>
1198 return ts - detail::floor_mod(ts, static_cast<ts_t>(p));
1199 }
1200
1205 template<class T = int>
1207 return ts - detail::floor_mod(ts, static_cast<ts_t>(p)) + p - 1;
1208 }
1209
1211
1212}; // namespace time_shield
1213
1214#endif // _TIME_SHIELD_DATE_TIME_CONVERSIONS_HPP_INCLUDED
Configuration macros for the library.
Header file with time-related constants.
Conversions related to calendar dates and DateStruct helpers.
Header for date structure and related functions.
Header for date and time structure and related functions.
Header file with enumerations for weekdays, months, and other time-related categories.
Fast date conversion helpers.
Floor division and modulus helpers.
constexpr int64_t MIN_PER_HOUR
Minutes per hour.
constexpr int64_t ERROR_TIMESTAMP
Error timestamp value.
constexpr int64_t DAYS_PER_WEEK
Days per week.
constexpr int64_t SEC_PER_YEAR
Seconds per year (365 days)
constexpr int64_t SEC_PER_FIRST_100_YEARS
Seconds per first 100 years.
const int64_t MONTHS_PER_YEAR
Months per year.
constexpr int64_t HOURS_PER_DAY
Hours per day.
constexpr int64_t SEC_PER_100_YEARS
Seconds per 100 years.
constexpr int64_t MAX_YEAR
Maximum representable year.
constexpr int64_t SEC_PER_LEAP_YEAR
Seconds per leap year (366 days)
constexpr int64_t MIN_PER_DAY
Minutes per day.
constexpr int64_t SEC_PER_HOUR
Seconds per hour.
constexpr int64_t UNIX_EPOCH
Start year of UNIX time.
constexpr int64_t MS_PER_DAY
Milliseconds per day.
Definition constants.hpp:97
constexpr int64_t MS_PER_SEC
Milliseconds per second.
Definition constants.hpp:77
constexpr int64_t SEC_PER_400_YEARS
Seconds per 400 years.
constexpr int64_t SEC_PER_DAY
Seconds per day.
constexpr int64_t SEC_PER_MIN
Seconds per minute.
constexpr int64_t MS_PER_HOUR
Milliseconds per hour.
Definition constants.hpp:90
constexpr int64_t SEC_PER_4_YEARS
Seconds per 4 years.
constexpr T unix_day(ts_t ts=time_shield::ts()) noexcept
Alias for days_since_epoch function.
TIME_SHIELD_CONSTEXPR ts_t ts(year_t year, int month, int day)
Alias for to_timestamp.
constexpr T ms_of_ts(ts_ms_t ts) noexcept
Alias for ms_part.
TIME_SHIELD_CONSTEXPR T1 day_of_week_date(T2 year, T3 month, T4 day)
Get the day of the week.
TIME_SHIELD_CONSTEXPR ts_ms_t ts_ms(year_t year, int month, int day)
Alias for to_timestamp_ms.
TIME_SHIELD_CONSTEXPR ts_t year_start(ts_t ts=time_shield::ts())
Alias for start_of_year function.
constexpr T1 ms_to_sec(T2 ts_ms) noexcept
Converts a timestamp from milliseconds to seconds.
TIME_SHIELD_CONSTEXPR T num_days_in_year_ts(ts_t ts=time_shield::ts())
Get the number of days in the current year.
constexpr T days(ts_t start, ts_t stop) noexcept
Alias for days_between function.
constexpr T1 sec_to_ms(T2 ts) noexcept
Converts a timestamp from seconds to milliseconds.
TIME_SHIELD_CONSTEXPR T year(ts_t ts=time_shield::ts())
Alias for year_of function.
@ FEB
February.
Definition enums.hpp:95
@ SAT
Saturday.
Definition enums.hpp:34
@ THU
Thursday.
Definition enums.hpp:32
TIME_SHIELD_CONSTEXPR ts_t tm_to_timestamp(const std::tm *timeinfo)
Converts a std::tm structure to a timestamp.
TIME_SHIELD_CONSTEXPR T day_of_month(ts_t ts=time_shield::ts())
Get the day of the month.
constexpr ts_t end_of_hour(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the end of the hour.
TIME_SHIELD_CONSTEXPR fts_t dt_to_ftimestamp(const T &date_time)
Converts a date-time structure to a floating-point timestamp.
TIME_SHIELD_CONSTEXPR fts_t tm_to_ftimestamp(const std::tm *timeinfo)
Converts a std::tm structure to a floating-point timestamp.
TIME_SHIELD_CONSTEXPR ts_t to_timestamp_unchecked(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0) noexcept
Converts a date and time to a timestamp without validation.
constexpr ts_t start_of_saturday(ts_t ts=time_shield::ts())
Get the timestamp of the start of Saturday.
constexpr ts_t end_of_week(ts_t ts=time_shield::ts())
Get the timestamp of the end of the week.
constexpr ts_t start_of_period(T p, ts_t ts=time_shield::ts())
Get the timestamp of the start of the period.
TIME_SHIELD_CONSTEXPR ts_ms_t end_of_year_ms(ts_ms_t ts_ms=time_shield::ts_ms())
Get the timestamp in milliseconds of the end of the year.
T to_date_time_ms(ts_ms_t ts)
Converts a timestamp in milliseconds to a date-time structure with milliseconds.
constexpr ts_t start_of_min(ts_t ts=time_shield::ts()) noexcept
Get the timestamp of the beginning of the minute.
TIME_SHIELD_CONSTEXPR T month_of_year(ts_t ts) noexcept
Get the month of the year.
TIME_SHIELD_CONSTEXPR T1 last_sunday_month_day(T2 year, T3 month)
Get the day of the last Sunday of the given month and year.
constexpr T weekday_of_ts_ms(ts_ms_t ts_ms)
Get the weekday from a timestamp in milliseconds.
constexpr ts_ms_t end_of_hour_ms(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the end of the hour in milliseconds.
constexpr ts_ms_t end_of_day_ms(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the end of the day in milliseconds.
TIME_SHIELD_CONSTEXPR ts_t end_of_year(ts_t ts=time_shield::ts())
Get the end-of-year timestamp.
constexpr ts_ms_t start_of_day_ms(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the start of the day timestamp in milliseconds.
constexpr T min_of_hour(ts_t ts=time_shield::ts()) noexcept
Get minute of hour. This function returns a value between 0 to 59.
constexpr ts_t start_of_hour(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the start of the hour.
constexpr T hour_of_day(ts_t ts=time_shield::ts()) noexcept
Get hour of day. This function returns a value between 0 to 23.
TIME_SHIELD_CONSTEXPR ts_t start_of_year(ts_t ts) noexcept
Get the start of the year timestamp.
constexpr ts_t end_of_day(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the end of the day.
T day_of_year(ts_t ts=time_shield::ts())
Get the day of the year.
TIME_SHIELD_CONSTEXPR ts_t tm_to_timestamp_ms(const std::tm *timeinfo)
Converts a std::tm structure to a timestamp in milliseconds.
TIME_SHIELD_CONSTEXPR ts_t start_of_month(ts_t ts=time_shield::ts())
Get the timestamp at the start of the current month.
TIME_SHIELD_CONSTEXPR ts_ms_t dt_to_timestamp_ms(const T &date_time)
Converts a date-time structure to a timestamp in milliseconds.
constexpr T get_weekday_from_ts_ms(ts_ms_t ts_ms)
Alias for weekday_of_ts_ms.
TIME_SHIELD_CONSTEXPR ts_t dt_to_timestamp(const T &date_time)
Converts a date-time structure to a timestamp.
constexpr ts_ms_t start_of_hour_ms(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the start of the hour. This function sets the minute and second to zero.
TIME_SHIELD_CONSTEXPR T1 num_days_in_month_ts(ts_t ts=time_shield::ts()) noexcept
Get the number of days in the month of the given timestamp.
TIME_SHIELD_CONSTEXPR fts_t to_ftimestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0)
Converts a date and time to a floating-point timestamp.
TIME_SHIELD_CONSTEXPR ts_t end_of_month(ts_t ts=time_shield::ts())
Get the last timestamp of the current month.
constexpr ts_t start_of_day(ts_t ts=time_shield::ts()) noexcept
Get the start of the day timestamp.
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_year_ms(ts_ms_t ts_ms=time_shield::ts_ms())
Get the timestamp at the start of the year in milliseconds.
constexpr ts_t end_of_hour_sec(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the end of the hour in seconds.
TIME_SHIELD_CONSTEXPR ts_t to_timestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0)
Converts a date and time to a timestamp.
constexpr ts_t end_of_min(ts_t ts=time_shield::ts()) noexcept
Get the timestamp of the end of the minute.
constexpr ts_ms_t start_of_next_day_ms(ts_ms_t ts_ms, T days=1) noexcept
Get the timestamp of the start of the day after a specified number of days.
TIME_SHIELD_CONSTEXPR ts_t last_sunday_of_month(ts_t ts=time_shield::ts())
Get the timestamp of the last Sunday of the current month.
TIME_SHIELD_CONSTEXPR ts_t start_of_year_date(T year)
Get the timestamp of the start of the year.
constexpr ts_ms_t next_day_ms(ts_ms_t ts_ms, T days=1) noexcept
Calculate the timestamp for a specified number of days in the future (milliseconds).
constexpr ts_t end_of_period(T p, ts_t ts=time_shield::ts())
Get the timestamp of the end of the period.
constexpr ts_t start_of_next_day(ts_t ts, T days=1) noexcept
Get the timestamp of the start of the day after a specified number of days.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
constexpr ts_t next_day(ts_t ts, T days=1) noexcept
Calculate the timestamp for a specified number of days in the future.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
constexpr ts_t start_of_week(ts_t ts=time_shield::ts())
Get the timestamp of the beginning of the week.
constexpr ts_t start_of_day_sec(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the start of the day timestamp in seconds.
constexpr T weekday_of_ts(ts_t ts) noexcept
Get the second of the week day from a timestamp.
TIME_SHIELD_CONSTEXPR T1 num_days_in_month(T2 year, T3 month) noexcept
Get the number of days in a month.
constexpr T min_of_day(ts_t ts=time_shield::ts()) noexcept
Get minute of day. This function returns a value between 0 to 1439 (minute of day).
constexpr ts_t start_of_prev_day(ts_t ts=time_shield::ts(), T days=1) noexcept
Get timestamp of the start of the previous day.
constexpr T get_weekday_from_ts(ts_t ts) noexcept
Alias for weekday_of_ts.
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_year_date_ms(T year)
Get the timestamp in milliseconds of the start of the year.
constexpr ts_t start_of_hour_sec(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the start of the hour.
constexpr ts_t end_of_day_sec(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the end of the day in seconds.
TIME_SHIELD_CONSTEXPR ts_ms_t to_timestamp_ms(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T2 ms=0)
Converts a date-time structure to a timestamp in milliseconds.
int64_t ts_t
Unix timestamp in seconds since 1970‑01‑01T00:00:00Z.
Definition types.hpp:49
int64_t dse_t
Unix day count since 1970‑01‑01 (days since epoch).
Definition types.hpp:42
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:50
double fts_t
Floating-point timestamp (fractional seconds since epoch).
Definition types.hpp:52
int64_t year_t
Year as an integer (e.g., 2024).
Definition types.hpp:41
TIME_SHIELD_CONSTEXPR bool is_leap_year(ts_t ts)
Alias for is_leap_year_ts function.
TIME_SHIELD_CONSTEXPR bool is_valid_date_time(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0) noexcept
Checks the correctness of a date and time.
constexpr bool is_leap_year_date(T year) noexcept
Checks if the given year is a leap year.
TIME_SHIELD_CONSTEXPR T floor_mod(T a, T b) noexcept
Floor-mod for positive modulus (returns r in [0..b)).
TIME_SHIELD_CONSTEXPR DaySplit split_unix_day(ts_t p_ts) noexcept
Split UNIX seconds into whole days and seconds-of-day.
Definition fast_date.hpp:39
TIME_SHIELD_CONSTEXPR T floor_div(T a, T b) noexcept
Floor division for positive divisor.
FastDate fast_date_from_days(int64_t p_days) noexcept
Convert days since Unix epoch to date using a fast algorithm.
TIME_SHIELD_CONSTEXPR ts_t to_timestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0)
Converts a date and time to a timestamp.
TIME_SHIELD_CONSTEXPR ts_t to_timestamp_unchecked(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0) noexcept
Converts a date and time to a timestamp without validation.
Main namespace for the Time Shield library.
TIME_SHIELD_CONSTEXPR dse_t date_to_unix_day(Year year, Month month, Day day) noexcept
Convert a calendar date to UNIX day count.
Helper functions for unit conversions between seconds, minutes, hours, and milliseconds.
Header file with time-related utility functions.
Type definitions for time-related units and formats.
Conversions related to UNIX-based time units and epochs.
Header file with time-related validation functions.