Time Shield Library 2.0.0
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_HEADER_CONVERSIONS_DATE_TIME_CONVERSIONS_HPP_INCLUDED
4#define TIME_SHIELD_HEADER_CONVERSIONS_DATE_TIME_CONVERSIONS_HPP_INCLUDED
5
8
10#include "date_conversions.hpp"
11#include "detail/fast_date.hpp"
12#include "detail/floor_math.hpp"
15
16#include <cmath>
17#include <ctime>
18#include <limits>
19#include <stdexcept>
20#include <type_traits>
21
22namespace time_shield {
23
26
27 namespace legacy {
28
39 template<class T1 = DateTimeStruct, class T2 = ts_t>
41 // 9223372029693630000 reaches year 292277024400 from the 2000 epoch.
42 // This value overflows the n_400_years * SEC_PER_400_YEARS calculation.
43 // The supported bound is reduced to 9223371890843040000.
44 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
45 constexpr int64_t BIAS_2000 = 946684800LL;
46
47 int64_t y = MAX_YEAR;
48 int64_t secs = -((static_cast<int64_t>(ts) - BIAS_2000) - BIAS_292277022000);
49
50 const int64_t n_400_years = secs / SEC_PER_400_YEARS;
51 secs -= n_400_years * SEC_PER_400_YEARS;
52 y -= n_400_years * 400LL;
53
54 const int64_t n_100_years = secs / SEC_PER_100_YEARS;
55 secs -= n_100_years * SEC_PER_100_YEARS;
56 y -= n_100_years * 100LL;
57
58 const int64_t n_4_years = secs / SEC_PER_4_YEARS;
59 secs -= n_4_years * SEC_PER_4_YEARS;
60 y -= n_4_years * 4LL;
61
62 const int64_t n_1_years = secs / SEC_PER_YEAR;
63 secs -= n_1_years * SEC_PER_YEAR;
64 y -= n_1_years;
65
66 T1 date_time;
67
68 if (secs == 0) {
69 date_time.year = y;
70 date_time.mon = 1;
71 date_time.day = 1;
72 return date_time;
73 }
74
75 date_time.year = y - 1;
76 const bool is_leap_year = is_leap_year_date(date_time.year);
77 secs = is_leap_year ? SEC_PER_LEAP_YEAR - secs : SEC_PER_YEAR - secs;
78 const int days = static_cast<int>(secs / SEC_PER_DAY);
79
80 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60 - 1;
81 constexpr int TABLE_MONTH_OF_YEAR[] = {
82 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, // January (31 days)
83 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, // February (28 days)
84 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, // March (31 days)
85 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, // April (30 days)
86 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,
87 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,
88 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,
89 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,
90 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,
91 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,
92 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,
93 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,
94 };
95 constexpr int TABLE_DAY_OF_YEAR[] = {
96 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, // January (31 days)
97 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, // February (28 days)
98 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, // March (31 days)
99 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, // April (30 days)
100 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,
101 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,
102 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,
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,
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,29,30,
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,
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,
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 };
109
110 if (is_leap_year) {
111 const int prev_days = days - 1;
112 date_time.day = days == JAN_AND_FEB_DAY_LEAP_YEAR ? (TABLE_DAY_OF_YEAR[prev_days] + 1) :
113 (days > JAN_AND_FEB_DAY_LEAP_YEAR ? TABLE_DAY_OF_YEAR[prev_days] : TABLE_DAY_OF_YEAR[days]);
114 date_time.mon = days >= JAN_AND_FEB_DAY_LEAP_YEAR ? TABLE_MONTH_OF_YEAR[prev_days] : TABLE_MONTH_OF_YEAR[days];
115 } else {
116 date_time.day = TABLE_DAY_OF_YEAR[days];
117 date_time.mon = TABLE_MONTH_OF_YEAR[days];
118 }
119
120 ts_t day_secs = static_cast<ts_t>(detail::floor_mod(secs, SEC_PER_DAY));
121 date_time.hour = static_cast<decltype(date_time.hour)>(day_secs / SEC_PER_HOUR);
122 ts_t min_secs = static_cast<ts_t>(day_secs - date_time.hour * SEC_PER_HOUR);
123 date_time.min = static_cast<decltype(date_time.min)>(min_secs / SEC_PER_MIN);
124 date_time.sec = static_cast<decltype(date_time.sec)>(min_secs - date_time.min * SEC_PER_MIN);
125# ifdef TIME_SHIELD_CPP17
126 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T2>::value) {
127 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
128 } else date_time.ms = 0;
129# else
130 if (std::is_floating_point<T2>::value) {
131 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
132 } else date_time.ms = 0;
133# endif
134 return date_time;
135 }
136
137 } // namespace legacy
138
152 template<class T1 = DateTimeStruct, class T2 = ts_t>
154 const int64_t whole_sec = static_cast<int64_t>(ts);
155 const detail::DaySplit split = detail::split_unix_day(whole_sec);
157
158 T1 date_time{};
159 date_time.year = static_cast<decltype(date_time.year)>(date.year);
160 date_time.mon = static_cast<decltype(date_time.mon)>(date.month);
161 date_time.day = static_cast<decltype(date_time.day)>(date.day);
162
163 const ts_t day_secs = static_cast<ts_t>(split.sec_of_day);
164 date_time.hour = static_cast<decltype(date_time.hour)>(day_secs / SEC_PER_HOUR);
165 const ts_t min_secs = static_cast<ts_t>(day_secs - date_time.hour * SEC_PER_HOUR);
166 date_time.min = static_cast<decltype(date_time.min)>(min_secs / SEC_PER_MIN);
167 date_time.sec = static_cast<decltype(date_time.sec)>(min_secs - date_time.min * SEC_PER_MIN);
168# ifdef TIME_SHIELD_CPP17
169 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T2>::value) {
170 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
171 } else date_time.ms = 0;
172# else
173 if (std::is_floating_point<T2>::value) {
174 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
175 } else date_time.ms = 0;
176# endif
177 return date_time;
178 }
179
185 template<class T>
187 const ts_t sec = ms_to_sec<ts_t, ts_ms_t>(ts);
188 T date_time = to_date_time<T, ts_t>(sec);
189 date_time.ms = ms_of_ts(ts); // Extract and set the ms component
190 return date_time;
191 }
192
193 namespace legacy {
194
225 template<class T1 = year_t, class T2 = int>
226 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp(
227 T1 year,
228 T2 month,
229 T2 day,
230 T2 hour = 0,
231 T2 min = 0,
232 T2 sec = 0) {
233
234 if (day >= UNIX_EPOCH && year <= 31) {
235 return to_timestamp((T1)day, month, (T2)year, hour, min, sec);
236 }
237 if (!is_valid_date_time(year, month, day, hour, min, sec)) {
238 throw std::invalid_argument("Invalid date-time combination");
239 }
240
241 int64_t secs = 0;
242 int64_t years = (static_cast<int64_t>(MAX_YEAR) - year);
243
244 const int64_t n_400_years = years / 400LL;
245 secs += n_400_years * SEC_PER_400_YEARS;
246 years -= n_400_years * 400LL;
247
248 const int64_t n_100_years = years / 100LL;
249 secs += n_100_years * SEC_PER_100_YEARS;
250 years -= n_100_years * 100LL;
251
252 const int64_t n_4_years = years / 4LL;
253 secs += n_4_years * SEC_PER_4_YEARS;
254 years -= n_4_years * 4LL;
255
256 secs += years * SEC_PER_YEAR;
257
258 // 9223372029693630000 reaches year 292277024400 from the 2000 epoch.
259 // This value overflows the n_400_years * SEC_PER_400_YEARS calculation.
260 // The supported bound is reduced to 9223371890843040000.
261 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
262 constexpr int64_t BIAS_2000 = 946684800LL;
263
264 secs = BIAS_292277022000 - secs;
265 secs += BIAS_2000;
266
267 if (month == 1 && day == 1 &&
268 hour == 0 && min == 0 &&
269 sec == 0) {
270 return secs;
271 }
272
273 constexpr int lmos[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
274 constexpr int mos[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
275
276 secs += (is_leap_year_date(year) ? (lmos[month - 1] + day - 1) : (mos[month - 1] + day - 1)) * SEC_PER_DAY;
277 secs += SEC_PER_HOUR * hour + SEC_PER_MIN * min + sec;
278 return secs;
279 }
280
298 template<class T1 = year_t, class T2 = int>
299 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp_unchecked(
300 T1 year,
301 T2 month,
302 T2 day,
303 T2 hour = 0,
304 T2 min = 0,
305 T2 sec = 0) noexcept {
306
307 if (day >= UNIX_EPOCH && year <= 31) {
308 return to_timestamp_unchecked((T1)day, month, (T2)year, hour, min, sec);
309 }
310
311 int64_t secs = 0;
312 int64_t years = (static_cast<int64_t>(MAX_YEAR) - year);
313
314 const int64_t n_400_years = years / 400LL;
315 secs += n_400_years * SEC_PER_400_YEARS;
316 years -= n_400_years * 400LL;
317
318 const int64_t n_100_years = years / 100LL;
319 secs += n_100_years * SEC_PER_100_YEARS;
320 years -= n_100_years * 100LL;
321
322 const int64_t n_4_years = years / 4LL;
323 secs += n_4_years * SEC_PER_4_YEARS;
324 years -= n_4_years * 4LL;
325
326 secs += years * SEC_PER_YEAR;
327
328 // 9223372029693630000 reaches year 292277024400 from the 2000 epoch.
329 // This value overflows the n_400_years * SEC_PER_400_YEARS calculation.
330 // The supported bound is reduced to 9223371890843040000.
331 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
332 constexpr int64_t BIAS_2000 = 946684800LL;
333
334 secs = BIAS_292277022000 - secs;
335 secs += BIAS_2000;
336
337 if (month == 1 && day == 1 &&
338 hour == 0 && min == 0 &&
339 sec == 0) {
340 return secs;
341 }
342
343 constexpr int lmos[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
344 constexpr int mos[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
345
346 secs += (is_leap_year_date(year) ? (lmos[month - 1] + day - 1) : (mos[month - 1] + day - 1)) * SEC_PER_DAY;
347 secs += SEC_PER_HOUR * hour + SEC_PER_MIN * min + sec;
348 return secs;
349 }
350
351 } // namespace legacy
352
374 template<class T1 = year_t, class T2 = int>
375 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp_unchecked(
376 T1 year,
377 T2 month,
378 T2 day,
379 T2 hour = 0,
380 T2 min = 0,
381 T2 sec = 0) noexcept {
382
383 if (day >= UNIX_EPOCH && year <= 31) {
384 return to_timestamp_unchecked((T1)day, month, (T2)year, hour, min, sec);
385 }
386
387 const dse_t unix_day = date_to_unix_day(year, month, day);
388 return static_cast<ts_t>(unix_day * SEC_PER_DAY
389 + SEC_PER_HOUR * static_cast<int64_t>(hour)
390 + SEC_PER_MIN * static_cast<int64_t>(min)
391 + static_cast<int64_t>(sec));
392 }
393
428 template<class T1 = year_t, class T2 = int>
429 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp(
430 T1 year,
431 T2 month,
432 T2 day,
433 T2 hour = 0,
434 T2 min = 0,
435 T2 sec = 0) {
436
437 if (day >= UNIX_EPOCH && year <= 31) {
438 return to_timestamp((T1)day, month, (T2)year, hour, min, sec);
439 }
440 if (!is_valid_date_time(year, month, day, hour, min, sec)) {
441 throw std::invalid_argument("Invalid date-time combination");
442 }
443
444 return to_timestamp_unchecked(year, month, day, hour, min, sec);
445 }
446
457 template<class T>
458 TIME_SHIELD_CONSTEXPR inline ts_t dt_to_timestamp(
459 const T& date_time) {
460 return to_timestamp(
461 date_time.year,
462 date_time.mon,
463 date_time.day,
464 date_time.hour,
465 date_time.min,
466 date_time.sec
467 );
468 }
469
478 TIME_SHIELD_CONSTEXPR inline ts_t tm_to_timestamp(
479 const std::tm *timeinfo) {
480 return to_timestamp(
481 static_cast<year_t>(timeinfo->tm_year + 1900),
482 static_cast<int>(timeinfo->tm_mon + 1),
483 static_cast<int>(timeinfo->tm_mday),
484 static_cast<int>(timeinfo->tm_hour),
485 static_cast<int>(timeinfo->tm_min),
486 static_cast<int>(timeinfo->tm_sec)
487 );
488 }
489
507 template<class T1 = year_t, class T2 = int>
508 TIME_SHIELD_CONSTEXPR inline ts_ms_t to_timestamp_ms(
509 T1 year,
510 T2 month,
511 T2 day,
512 T2 hour = 0,
513 T2 min = 0,
514 T2 sec = 0,
515 T2 ms = 0) {
516 int64_t sec_value = static_cast<int64_t>(to_timestamp<T1, T2>(year, month, day, hour, min, sec));
517 int64_t ms_value = static_cast<int64_t>(ms);
518 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
519 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
520 if ((sec_value > 0 &&
521 sec_value > ((std::numeric_limits<int64_t>::max)() - ms_value) / MS_PER_SEC) ||
522 (sec_value < 0 &&
523 sec_value < (std::numeric_limits<int64_t>::min)() / MS_PER_SEC)) {
524 return ERROR_TIMESTAMP;
525 }
526 return static_cast<ts_ms_t>(sec_value * MS_PER_SEC + ms_value);
527 }
528
539 template<class T>
540 TIME_SHIELD_CONSTEXPR inline ts_ms_t dt_to_timestamp_ms(
541 const T& date_time) {
542 int64_t sec_value = static_cast<int64_t>(dt_to_timestamp(date_time));
543 int64_t ms_value = static_cast<int64_t>(date_time.ms);
544 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
545 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
546 if ((sec_value > 0 &&
547 sec_value > ((std::numeric_limits<int64_t>::max)() - ms_value) / MS_PER_SEC) ||
548 (sec_value < 0 &&
549 sec_value < (std::numeric_limits<int64_t>::min)() / MS_PER_SEC)) {
550 return ERROR_TIMESTAMP;
551 }
552 return static_cast<ts_ms_t>(sec_value * MS_PER_SEC + ms_value);
553 }
554
563 TIME_SHIELD_CONSTEXPR inline ts_t tm_to_timestamp_ms(
564 const std::tm *timeinfo) {
565 return sec_to_ms(tm_to_timestamp(timeinfo));
566 }
567
586 template<class T1 = year_t, class T2 = int, class T3 = int>
587 TIME_SHIELD_CONSTEXPR inline fts_t to_ftimestamp(
588 T1 year,
589 T2 month,
590 T2 day,
591 T2 hour = 0,
592 T2 min = 0,
593 T2 sec = 0,
594 T3 ms = 0) {
595 int64_t sec_value = static_cast<int64_t>(to_timestamp(year, month, day, hour, min, sec));
596 int64_t ms_value = static_cast<int64_t>(ms);
597 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
598 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
599 return static_cast<fts_t>(sec_value) +
600 static_cast<fts_t>(ms_value) / static_cast<fts_t>(MS_PER_SEC);
601 }
602
614 template<class T>
615 TIME_SHIELD_CONSTEXPR inline fts_t dt_to_ftimestamp(
616 const T& date_time) {
617 int64_t sec_value = static_cast<int64_t>(to_timestamp(date_time));
618 int64_t ms_value = static_cast<int64_t>(date_time.ms);
619 sec_value += detail::floor_div(ms_value, static_cast<int64_t>(MS_PER_SEC));
620 ms_value = detail::floor_mod(ms_value, static_cast<int64_t>(MS_PER_SEC));
621 return static_cast<fts_t>(sec_value) +
622 static_cast<fts_t>(ms_value) / static_cast<fts_t>(MS_PER_SEC);
623 }
624
634 TIME_SHIELD_CONSTEXPR inline fts_t tm_to_ftimestamp(
635 const std::tm* timeinfo) {
636 return static_cast<fts_t>(tm_to_timestamp(timeinfo));
637 }
638
646 TIME_SHIELD_CONSTEXPR inline ts_t start_of_day(ts_t ts = time_shield::ts()) noexcept {
648 }
649
657 template<class T = int>
658 TIME_SHIELD_CONSTEXPR ts_t start_of_prev_day(ts_t ts = time_shield::ts(), T days = 1) noexcept {
660 }
661
669 TIME_SHIELD_CONSTEXPR inline ts_t start_of_day_sec(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
671 }
672
680 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_day_ms(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
682 }
683
692 template<class T = int>
693 TIME_SHIELD_CONSTEXPR ts_t start_of_next_day(ts_t ts, T days = 1) noexcept {
694 return start_of_day(ts) + days * SEC_PER_DAY;
695 }
696
705 template<class T = int>
706 TIME_SHIELD_CONSTEXPR ts_ms_t start_of_next_day_ms(ts_ms_t ts_ms, T days = 1) noexcept {
708 }
709
717 template<class T = int>
718 TIME_SHIELD_CONSTEXPR ts_t next_day(ts_t ts, T days = 1) noexcept {
719 return ts + days * SEC_PER_DAY;
720 }
721
729 template<class T = int>
730 TIME_SHIELD_CONSTEXPR ts_ms_t next_day_ms(ts_ms_t ts_ms, T days = 1) noexcept {
731 return ts_ms + days * MS_PER_DAY;
732 }
733
740 TIME_SHIELD_CONSTEXPR inline ts_t end_of_day(ts_t ts = time_shield::ts()) noexcept {
742 }
743
750 TIME_SHIELD_CONSTEXPR inline ts_t end_of_day_sec(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
752 }
753
760 TIME_SHIELD_CONSTEXPR inline ts_ms_t end_of_day_ms(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
762 }
763
767 template<class T = year_t>
768 TIME_SHIELD_CONSTEXPR inline ts_t start_of_year_date(T year) {
769 const ts_t year_ts = to_timestamp(year, 1, 1);
770
771 return start_of_day(year_ts);
772 }
773
781 template<class T = year_t>
782 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_year_date_ms(T year) {
784 }
785
793 TIME_SHIELD_CONSTEXPR inline ts_t start_of_year(ts_t ts) noexcept {
794 constexpr ts_t BIAS_2100 = 4102444800;
795 if (ts >= 0 && ts < BIAS_2100) {
796 constexpr ts_t SEC_PER_YEAR_X2 = SEC_PER_YEAR * 2;
797 ts_t year_start_ts = detail::floor_mod(ts, SEC_PER_4_YEARS);
798 if (year_start_ts < SEC_PER_YEAR) {
799 return ts - year_start_ts;
800 } else if (year_start_ts < SEC_PER_YEAR_X2) {
801 return ts + SEC_PER_YEAR - year_start_ts;
802 } else if (year_start_ts < (SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR)) {
803 return ts + SEC_PER_YEAR_X2 - year_start_ts;
804 }
805 return ts + (SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR) - year_start_ts;
806 }
807
808 constexpr ts_t BIAS_2000 = 946684800;
809 ts_t secs = ts - BIAS_2000;
810
811 ts_t offset_y400 = detail::floor_mod(secs, SEC_PER_400_YEARS);
812 ts_t start_ts = secs - offset_y400 + BIAS_2000;
813 secs = offset_y400;
814
815 if (secs >= SEC_PER_FIRST_100_YEARS) {
817 start_ts += SEC_PER_FIRST_100_YEARS;
818 while (secs >= SEC_PER_100_YEARS) {
819 secs -= SEC_PER_100_YEARS;
820 start_ts += SEC_PER_100_YEARS;
821 }
822
823 constexpr ts_t SEC_PER_4_YEARS_V2 = 4 * SEC_PER_YEAR;
824 if (secs >= SEC_PER_4_YEARS_V2) {
825 secs -= SEC_PER_4_YEARS_V2;
826 start_ts += SEC_PER_4_YEARS_V2;
827 } else {
828 start_ts += secs - detail::floor_mod(secs, SEC_PER_YEAR);
829 return start_ts;
830 }
831 }
832
833 ts_t offset_4y = detail::floor_mod(secs, SEC_PER_4_YEARS);
834 start_ts += secs - offset_4y;
835 secs = offset_4y;
836
837 if (secs >= SEC_PER_LEAP_YEAR) {
838 secs -= SEC_PER_LEAP_YEAR;
839 start_ts += SEC_PER_LEAP_YEAR;
840 start_ts += secs - detail::floor_mod(secs, SEC_PER_YEAR);
841 return start_ts;
842 }
843
844 start_ts += secs - detail::floor_mod(secs, SEC_PER_YEAR);
845 return start_ts;
846 }
847
851 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) {
853 }
854
861 TIME_SHIELD_CONSTEXPR inline ts_t end_of_year(ts_t ts = time_shield::ts()) {
863 const ts_t year_days = static_cast<ts_t>(num_days_in_year_ts(ts));
864 return year_start + year_days * SEC_PER_DAY - 1;
865 }
866
873 template<class T = year_t>
874 TIME_SHIELD_CONSTEXPR inline ts_ms_t end_of_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) {
876 }
877
884 template<class T = int>
886 return static_cast<T>(((ts - start_of_year(ts)) / SEC_PER_DAY) + 1);
887 }
888
895 template<class T = Month>
896 TIME_SHIELD_CONSTEXPR inline T month_of_year(ts_t ts) noexcept {
897 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60;
898 constexpr int TABLE_MONTH_OF_YEAR[] = {
899 0,
900 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, // January (31 days)
901 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, // February (28 days)
902 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, // March (31 days)
903 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, // April (30 days)
904 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,
905 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,
906 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,
907 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,
908 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,
909 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,
910 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,
911 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,
912 };
913 const size_t dy = day_of_year<size_t>(ts);
914 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]);
915 }
916
923 template<class T = int>
924 TIME_SHIELD_CONSTEXPR inline T day_of_month(ts_t ts = time_shield::ts()) {
925 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60;
926 // Month numbers for a common year.
927 constexpr int TABLE_DAY_OF_YEAR[] = {
928 0,
929 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, // January (31 days)
930 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, // February (28 days)
931 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, // March (31 days)
932 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, // April (30 days)
933 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,
934 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,
935 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,
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,
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,29,30,
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,
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,
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 };
942 const size_t dy = day_of_year<size_t>(ts);
943 if(is_leap_year(ts)) {
944 if(dy == JAN_AND_FEB_DAY_LEAP_YEAR) return TABLE_DAY_OF_YEAR[dy - 1] + 1;
945 if(dy > JAN_AND_FEB_DAY_LEAP_YEAR) return TABLE_DAY_OF_YEAR[dy - 1];
946 }
947 return TABLE_DAY_OF_YEAR[dy];
948 }
949
957 template<class T1 = int, class T2 = year_t, class T3 = int>
958 TIME_SHIELD_CONSTEXPR T1 num_days_in_month(T2 year, T3 month) noexcept {
959 constexpr T1 num_days[13] = {0,31,30,31,30,31,30,31,31,30,31,30,31};
960 return (month > MONTHS_PER_YEAR || month < 0)
961 ? static_cast<T1>(0)
962 : (month == FEB ? static_cast<T1>(is_leap_year_date(year) ? 29 : 28) : num_days[month]);
963 }
964
971 template<class T1 = int>
972 TIME_SHIELD_CONSTEXPR T1 num_days_in_month_ts(ts_t ts = time_shield::ts()) noexcept {
973 constexpr T1 num_days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
974 const int month = month_of_year<int>(ts);
975 if (month == FEB) {
976 return is_leap_year(ts) ? 29 : 28;
977 }
978 return num_days[month];
979 }
980
984 template<class T = Weekday>
985 TIME_SHIELD_CONSTEXPR T weekday_of_ts(ts_t ts) noexcept {
987 return static_cast<T>(detail::floor_mod(days + THU, DAYS_PER_WEEK));
988 }
989
993 template<class T = Weekday>
994 TIME_SHIELD_CONSTEXPR T weekday_of_ts_ms(ts_ms_t ts_ms) {
996 }
997
1005 TIME_SHIELD_CONSTEXPR inline ts_t start_of_month(ts_t ts = time_shield::ts()) {
1006 return start_of_day(ts) - (day_of_month(ts) - 1) * SEC_PER_DAY;
1007 }
1008
1016 TIME_SHIELD_CONSTEXPR inline ts_t end_of_month(ts_t ts = time_shield::ts()) {
1018 }
1019
1027 TIME_SHIELD_CONSTEXPR inline ts_t last_sunday_of_month(ts_t ts = time_shield::ts()) {
1028 const ts_t month_end = end_of_month(ts);
1029 return start_of_day(month_end) - weekday_of_ts(month_end) * SEC_PER_DAY;
1030 }
1031
1039 template<class T1 = int, class T2 = year_t, class T3 = int>
1040 TIME_SHIELD_CONSTEXPR inline T1 last_sunday_month_day(T2 year, T3 month) {
1041 const T1 days = num_days_in_month(year, month);
1042 return days - day_of_week_date(year, month, days);
1043 }
1044
1052 TIME_SHIELD_CONSTEXPR inline ts_t start_of_week(ts_t ts = time_shield::ts()) {
1054 }
1055
1063 TIME_SHIELD_CONSTEXPR inline ts_t end_of_week(ts_t ts = time_shield::ts()) {
1065 }
1066
1074 TIME_SHIELD_CONSTEXPR inline ts_t start_of_saturday(ts_t ts = time_shield::ts()) {
1075 return start_of_day(ts) + (SAT - weekday_of_ts(ts)) * SEC_PER_DAY;
1076 }
1077
1078
1085 TIME_SHIELD_CONSTEXPR inline ts_t start_of_hour(ts_t ts = time_shield::ts()) noexcept {
1087 }
1088
1095 TIME_SHIELD_CONSTEXPR inline ts_t start_of_hour_sec(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
1097 }
1098
1103 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_hour_ms(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
1105 }
1106
1110 TIME_SHIELD_CONSTEXPR inline ts_t end_of_hour(ts_t ts = time_shield::ts()) noexcept {
1112 }
1113
1117 TIME_SHIELD_CONSTEXPR inline ts_t end_of_hour_sec(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
1119 }
1120
1124 TIME_SHIELD_CONSTEXPR inline ts_ms_t end_of_hour_ms(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
1126 }
1127
1131 TIME_SHIELD_CONSTEXPR inline ts_t start_of_min(ts_t ts = time_shield::ts()) noexcept {
1133 }
1134
1138 TIME_SHIELD_CONSTEXPR inline ts_t end_of_min(ts_t ts = time_shield::ts()) noexcept {
1140 }
1141
1146 template<class T = int>
1147 TIME_SHIELD_CONSTEXPR T min_of_day(ts_t ts = time_shield::ts()) noexcept {
1148 const ts_t minutes = detail::floor_div(ts, SEC_PER_MIN);
1149 return static_cast<T>(detail::floor_mod(minutes, MIN_PER_DAY));
1150 }
1151
1156 template<class T = int>
1157 TIME_SHIELD_CONSTEXPR T hour_of_day(ts_t ts = time_shield::ts()) noexcept {
1158 const ts_t hours = detail::floor_div(ts, SEC_PER_HOUR);
1159 return static_cast<T>(detail::floor_mod(hours, HOURS_PER_DAY));
1160 }
1161
1166 template<class T = int>
1167 TIME_SHIELD_CONSTEXPR T min_of_hour(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_HOUR));
1170 }
1171
1176 template<class T = int>
1177 TIME_SHIELD_CONSTEXPR ts_t start_of_period(T p, ts_t ts = time_shield::ts()) {
1178 const ts_t period = static_cast<ts_t>(p);
1179 return period <= 0 ? ERROR_TIMESTAMP : ts - detail::floor_mod(ts, period);
1180 }
1181
1186 template<class T = int>
1187 TIME_SHIELD_CONSTEXPR ts_t end_of_period(T p, ts_t ts = time_shield::ts()) {
1188 const ts_t period = static_cast<ts_t>(p);
1189 return period <= 0 ? ERROR_TIMESTAMP : ts - detail::floor_mod(ts, period) + period - 1;
1190 }
1191
1193
1194}; // namespace time_shield
1195
1196#endif // TIME_SHIELD_HEADER_CONVERSIONS_DATE_TIME_CONVERSIONS_HPP_INCLUDED
Conversions related to calendar dates and DateStruct helpers.
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.
TIME_SHIELD_CONSTEXPR T1 ms_to_sec(T2 ts_ms) noexcept
Converts a timestamp from milliseconds to seconds.
TIME_SHIELD_CONSTEXPR T unix_day(ts_t ts=time_shield::ts()) noexcept
Alias for days_since_epoch function.
TIME_SHIELD_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 T days(ts_t start, ts_t stop) noexcept
Alias for days_between function.
TIME_SHIELD_CONSTEXPR ts_t year_start(ts_t ts=time_shield::ts())
Alias for start_of_year function.
TIME_SHIELD_CONSTEXPR T num_days_in_year_ts(ts_t ts=time_shield::ts())
Get the number of days in the current year.
TIME_SHIELD_CONSTEXPR T year(ts_t ts=time_shield::ts())
Alias for year_of function.
TIME_SHIELD_CONSTEXPR T1 sec_to_ms(T2 ts) noexcept
Converts a timestamp from seconds to milliseconds.
@ 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.
TIME_SHIELD_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 start_of_day_sec(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the start of the day timestamp in seconds.
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 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.
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 end_of_hour(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the end of the hour.
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.
TIME_SHIELD_CONSTEXPR T weekday_of_ts(ts_t ts) noexcept
Get the second of the week day from a timestamp.
TIME_SHIELD_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 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_hour(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the start of the hour.
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.
TIME_SHIELD_CONSTEXPR ts_t end_of_min(ts_t ts=time_shield::ts()) noexcept
Get the timestamp of the end 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.
TIME_SHIELD_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 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).
TIME_SHIELD_CONSTEXPR ts_t end_of_year(ts_t ts=time_shield::ts())
Get the end-of-year timestamp.
TIME_SHIELD_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 end_of_period(T p, ts_t ts=time_shield::ts())
Get the timestamp of the end of the period.
TIME_SHIELD_CONSTEXPR ts_t start_of_year(ts_t ts) noexcept
Get the start of the year timestamp.
TIME_SHIELD_CONSTEXPR ts_t start_of_day(ts_t ts=time_shield::ts()) noexcept
Get the start of the day timestamp.
T day_of_year(ts_t ts=time_shield::ts())
Get the day of the year.
TIME_SHIELD_CONSTEXPR ts_t next_day(ts_t ts, T days=1) noexcept
Calculate the timestamp for a specified number of days in the future.
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_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).
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 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.
TIME_SHIELD_CONSTEXPR ts_ms_t dt_to_timestamp_ms(const T &date_time)
Converts a date-time structure to a timestamp in milliseconds.
TIME_SHIELD_CONSTEXPR ts_t dt_to_timestamp(const T &date_time)
Converts a date-time structure to a timestamp.
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 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 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 start_of_hour_sec(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the timestamp at the start of the hour.
TIME_SHIELD_CONSTEXPR ts_t end_of_month(ts_t ts=time_shield::ts())
Get the last timestamp of the current month.
TIME_SHIELD_CONSTEXPR ts_t start_of_week(ts_t ts=time_shield::ts())
Get the timestamp of the beginning of the week.
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.
TIME_SHIELD_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_t start_of_saturday(ts_t ts=time_shield::ts())
Get the timestamp of the start of Saturday.
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 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.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
TIME_SHIELD_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 T min_of_hour(ts_t ts=time_shield::ts()) noexcept
Get minute of hour. This function returns a value between 0 to 59.
TIME_SHIELD_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.
TIME_SHIELD_CONSTEXPR T1 num_days_in_month(T2 year, T3 month) noexcept
Get the number of days in a month.
TIME_SHIELD_CONSTEXPR ts_t end_of_week(ts_t ts=time_shield::ts())
Get the timestamp of the end of the week.
TIME_SHIELD_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.
TIME_SHIELD_CONSTEXPR ts_t end_of_day(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the end of the day.
TIME_SHIELD_CONSTEXPR T weekday_of_ts_ms(ts_ms_t ts_ms)
Get the weekday from a timestamp in milliseconds.
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_year_date_ms(T year)
Get the timestamp in milliseconds of the start of the year.
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:48
int64_t dse_t
Unix day count since 1970‑01‑01 (days since epoch).
Definition types.hpp:41
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:49
double fts_t
Floating-point timestamp (fractional seconds since epoch).
Definition types.hpp:51
int64_t year_t
Year as an integer (e.g., 2024).
Definition types.hpp:40
ts_t ts() noexcept
Get the current UTC timestamp in seconds.
ts_ms_t ts_ms() noexcept
Get the current UTC timestamp in milliseconds.
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.
TIME_SHIELD_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.
Conversions related to UNIX-based time units and epochs.