Time Shield Library
C++ library for working with time
Loading...
Searching...
No Matches
time_conversions.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2#pragma once
3#ifndef _TIME_SHIELD_TIME_CONVERSIONS_HPP_INCLUDED
4#define _TIME_SHIELD_TIME_CONVERSIONS_HPP_INCLUDED
5
11
12#include "enums.hpp"
13#include "validation.hpp"
14#include "time_utils.hpp"
15#include "time_zone_struct.hpp"
16#include "date_time_struct.hpp"
17#include <cmath>
18#include <ctime>
19#include <stdexcept>
20
21namespace time_shield {
22
25
30 template<class T = int>
31 constexpr T ns_of_sec(fts_t ts) noexcept {
32 fts_t temp;
33 return static_cast<T>(std::round(std::modf(ts, &temp) * static_cast<fts_t>(NS_PER_SEC)));
34 }
35
40 template<class T = int>
41 constexpr T us_of_sec(fts_t ts) noexcept {
42 fts_t temp;
43 return static_cast<T>(std::round(std::modf(ts, &temp) * static_cast<fts_t>(US_PER_SEC)));
44 }
45
50 template<class T = int>
51 constexpr T ms_of_sec(fts_t ts) noexcept {
52 fts_t temp;
53 return static_cast<T>(std::round(std::modf(ts, &temp) * static_cast<fts_t>(MS_PER_SEC)));
54 }
55
60 template<class T = int>
61 constexpr T ms_of_ts(ts_ms_t ts) noexcept {
62 return ts % MS_PER_SEC;
63 }
64
65# ifndef TIME_SHIELD_CPP17
71 template<class T>
72 constexpr ts_ms_t sec_to_ms_impl(T t, std::true_type tag) noexcept {
73 return static_cast<ts_ms_t>(std::round(t * static_cast<T>(MS_PER_SEC)));
74 }
75
81 template<class T>
82 constexpr ts_ms_t sec_to_ms_impl(T t, std::false_type tag) noexcept {
83 return static_cast<ts_ms_t>(t) * static_cast<ts_ms_t>(MS_PER_SEC);
84 }
85# endif // TIME_SHIELD_CPP17
86
92 template<class T1 = ts_ms_t, class T2>
93 constexpr T1 sec_to_ms(T2 ts) noexcept {
94# ifdef TIME_SHIELD_CPP17
95 if constexpr (std::is_floating_point_v<T2>) {
96 return static_cast<T1>(std::round(ts * static_cast<T2>(MS_PER_SEC)));
97 } else {
98 return static_cast<T1>(ts) * static_cast<T1>(MS_PER_SEC);
99 }
100# else
101 return sec_to_ms_impl(ts, typename std::conditional<
102 (std::is_same<T2, double>::value || std::is_same<T2, float>::value),
103 std::true_type,
104 std::false_type
105 >::type{});
106# endif
107 }
108
112 inline ts_ms_t fsec_to_ms(fts_t ts) noexcept {
113 return static_cast<ts_ms_t>(std::round(ts * static_cast<fts_t>(MS_PER_SEC)));
114 }
115
121 template<class T1 = ts_t, class T2 = ts_ms_t>
122 constexpr T1 ms_to_sec(T2 ts_ms) noexcept {
123 return static_cast<T1>(ts_ms) / static_cast<T1>(MS_PER_SEC);
124 }
125
130 template<class T = ts_ms_t>
131 constexpr fts_t ms_to_fsec(T ts_ms) noexcept {
132 return static_cast<fts_t>(ts_ms) / static_cast<fts_t>(MS_PER_SEC);
133 }
134
135//----------------------------------------------------------------------------//
136// Minutes -> Milliseconds
137//----------------------------------------------------------------------------//
138# ifndef TIME_SHIELD_CPP17
144 template<class T>
145 constexpr ts_ms_t min_to_ms_impl(T t, std::true_type tag) noexcept {
146 return static_cast<ts_ms_t>(std::round(t * static_cast<T>(MS_PER_MIN)));
147 }
148
154 template<class T>
155 constexpr ts_ms_t min_to_ms_impl(T t, std::false_type tag) noexcept {
156 return static_cast<ts_ms_t>(t) * static_cast<ts_ms_t>(MS_PER_MIN);
157 }
158# endif // TIME_SHIELD_CPP17
159
165 template<class T1 = ts_ms_t, class T2>
166 constexpr T1 min_to_ms(T2 ts) noexcept {
167# ifdef TIME_SHIELD_CPP17
168 if constexpr (std::is_floating_point_v<T2>) {
169 return static_cast<T1>(std::round(ts * static_cast<T2>(MS_PER_MIN)));
170 } else {
171 return static_cast<T1>(ts) * static_cast<T1>(MS_PER_MIN);
172 }
173# else
174 return min_to_ms_impl(ts, typename std::conditional<
175 (std::is_same<T2, double>::value || std::is_same<T2, float>::value),
176 std::true_type,
177 std::false_type
178 >::type{});
179# endif
180 }
181
187 template<class T1 = int, class T2 = ts_ms_t>
188 constexpr T1 ms_to_min(T2 ts) noexcept {
189 return static_cast<T1>(ts) / static_cast<T1>(MS_PER_MIN);
190 }
191
192//----------------------------------------------------------------------------//
193// Minutes -> Seconds
194//----------------------------------------------------------------------------//
195# ifndef TIME_SHIELD_CPP17
201 template<class T>
202 constexpr ts_t min_to_sec_impl(T t, std::true_type tag) noexcept {
203 return static_cast<ts_t>(std::round(t * static_cast<T>(SEC_PER_MIN)));
204 }
205
211 template<class T>
212 constexpr ts_t min_to_sec_impl(T t, std::false_type tag) noexcept {
213 return static_cast<ts_t>(t) * static_cast<ts_t>(SEC_PER_MIN);
214 }
215# endif // TIME_SHIELD_CPP17
216
222 template<class T1 = ts_t, class T2>
223 constexpr T1 min_to_sec(T2 ts) noexcept {
224# ifdef TIME_SHIELD_CPP17
225 if constexpr (std::is_floating_point_v<T2>) {
226 return static_cast<T1>(std::round(ts * static_cast<T2>(SEC_PER_MIN)));
227 } else {
228 return static_cast<T1>(ts) * static_cast<T1>(SEC_PER_MIN);
229 }
230# else
231 return min_to_sec_impl(ts, typename std::conditional<
232 (std::is_same<T2, double>::value || std::is_same<T2, float>::value),
233 std::true_type,
234 std::false_type
235 >::type{});
236# endif
237 }
238
244 template<class T1 = int, class T2 = ts_t>
245 constexpr T1 sec_to_min(T2 ts) noexcept {
246 return static_cast<T1>(ts) / static_cast<T1>(SEC_PER_MIN);
247 }
248
253 template<class T = int>
254 constexpr fts_t min_to_fsec(T min) noexcept {
255 return static_cast<fts_t>(min) * static_cast<fts_t>(SEC_PER_MIN);
256 }
257
262 template<class T = ts_t>
263 constexpr double sec_to_fmin(T ts) noexcept {
264 return static_cast<double>(ts) / static_cast<double>(SEC_PER_MIN);
265 }
266
267//----------------------------------------------------------------------------//
268// Hours -> Milliseconds
269//----------------------------------------------------------------------------//
270
271# ifndef TIME_SHIELD_CPP17
277 template<class T>
278 constexpr ts_ms_t hour_to_ms_impl(T t, std::true_type tag) noexcept {
279 return static_cast<ts_ms_t>(std::round(t * static_cast<T>(MS_PER_HOUR)));
280 }
281
287 template<class T>
288 constexpr ts_ms_t hour_to_ms_impl(T t, std::false_type tag) noexcept {
289 return static_cast<ts_ms_t>(t) * static_cast<ts_ms_t>(MS_PER_HOUR);
290 }
291# endif // TIME_SHIELD_CPP17
292
298 template<class T1 = ts_ms_t, class T2>
299 constexpr T1 hour_to_ms(T2 ts) noexcept {
300# ifdef TIME_SHIELD_CPP17
301 if constexpr (std::is_floating_point_v<T2>) {
302 return static_cast<T1>(std::round(ts * static_cast<T2>(MS_PER_HOUR)));
303 } else {
304 return static_cast<T1>(ts) * static_cast<T1>(MS_PER_HOUR);
305 }
306# else
307 return hour_to_ms_impl(ts, typename std::conditional<
308 (std::is_same<T2, double>::value || std::is_same<T2, float>::value),
309 std::true_type,
310 std::false_type
311 >::type{});
312# endif
313 }
314
320 template<class T1 = int, class T2 = ts_ms_t>
321 constexpr T1 ms_to_hour(T2 ts) noexcept {
322 return static_cast<T1>(ts) / static_cast<T1>(MS_PER_HOUR);
323 }
324
325//----------------------------------------------------------------------------//
326// Hours -> Seconds
327//----------------------------------------------------------------------------//
328
329# ifndef TIME_SHIELD_CPP17
335 template<class T>
336 constexpr ts_t hour_to_sec_impl(T t, std::true_type tag) noexcept {
337 return static_cast<ts_t>(std::round(t * static_cast<T>(SEC_PER_HOUR)));
338 }
339
345 template<class T>
346 constexpr ts_t hour_to_sec_impl(T t, std::false_type tag) noexcept {
347 return static_cast<ts_t>(t) * static_cast<ts_t>(SEC_PER_HOUR);
348 }
349# endif // TIME_SHIELD_CPP17
350
356 template<class T1 = ts_t, class T2>
357 constexpr T1 hour_to_sec(T2 ts) noexcept {
358# ifdef TIME_SHIELD_CPP17
359 if constexpr (std::is_floating_point_v<T2>) {
360 return static_cast<T1>(std::round(ts * static_cast<T2>(SEC_PER_HOUR)));
361 } else {
362 return static_cast<T1>(ts) * static_cast<T1>(SEC_PER_HOUR);
363 }
364# else
365 return hour_to_sec_impl(ts, typename std::conditional<
366 (std::is_same<T2, double>::value || std::is_same<T2, float>::value),
367 std::true_type,
368 std::false_type
369 >::type{});
370# endif
371 }
372
378 template<class T1 = int, class T2 = ts_t>
379 constexpr T1 sec_to_hour(T2 ts) noexcept {
380 return static_cast<T1>(ts) / static_cast<T1>(SEC_PER_HOUR);
381 }
382
387 template<class T = int>
388 constexpr fts_t hour_to_fsec(T hr) noexcept {
389 return static_cast<fts_t>(hr) * static_cast<fts_t>(SEC_PER_HOUR);
390 }
391
396 template<class T = ts_t>
397 constexpr double sec_to_fhour(T ts) noexcept {
398 return static_cast<double>(ts) / static_cast<double>(SEC_PER_HOUR);
399 }
400
401//------------------------------------------------------------------------------
402
407 template<class T = year_t>
408 constexpr T get_unix_year(ts_t ts) noexcept {
409 // 9223372029693630000 - значение на момент 292277024400 от 2000 года
410 // Такое значение приводит к неправильному вычислению умножения n_400_years * SEC_PER_400_YEARS
411 // Поэтому пришлось снизить до 9223371890843040000
412 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
413 constexpr int64_t BIAS_2000 = 946684800LL;
414
415 int64_t y = MAX_YEAR;
416 int64_t secs = -((ts - BIAS_2000) - BIAS_292277022000);
417
418 const int64_t n_400_years = secs / SEC_PER_400_YEARS;
419 secs -= n_400_years * SEC_PER_400_YEARS;
420 y -= n_400_years * 400;
421
422 const int64_t n_100_years = secs / SEC_PER_100_YEARS;
423 secs -= n_100_years * SEC_PER_100_YEARS;
424 y -= n_100_years * 100;
425
426 const int64_t n_4_years = secs / SEC_PER_4_YEARS;
427 secs -= n_4_years * SEC_PER_4_YEARS;
428 y -= n_4_years * 4;
429
430 const int64_t n_1_years = secs / SEC_PER_YEAR;
431 secs -= n_1_years * SEC_PER_YEAR;
432 y -= n_1_years;
433
434 y = secs == 0 ? y : y - 1;
435 return y - UNIX_EPOCH;
436 }
437
438//------------------------------------------------------------------------------
439
444 template<class T = int>
445 TIME_SHIELD_CONSTEXPR inline T hour24_to_12(T hour) noexcept {
446 if (hour == 0 || hour > 12) return 12;
447 return hour;
448 }
449
450//------------------------------------------------------------------------------
451
462 template<class T1 = DateTimeStruct, class T2 = ts_t>
464 // 9223372029693630000 - значение на момент 292277024400 от 2000 года
465 // Такое значение приводит к неправильному вычислению умножения n_400_years * SEC_PER_400_YEARS
466 // Поэтому пришлось снизить до 9223371890843040000
467 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
468 constexpr int64_t BIAS_2000 = 946684800LL;
469
470 int64_t y = MAX_YEAR;
471 uint64_t secs = -((ts - BIAS_2000) - BIAS_292277022000);
472
473 const uint64_t n_400_years = secs / SEC_PER_400_YEARS;
474 secs -= n_400_years * SEC_PER_400_YEARS;
475 y -= n_400_years * 400;
476
477 const uint64_t n_100_years = secs / SEC_PER_100_YEARS;
478 secs -= n_100_years * SEC_PER_100_YEARS;
479 y -= n_100_years * 100;
480
481 const uint64_t n_4_years = secs / SEC_PER_4_YEARS;
482 secs -= n_4_years * SEC_PER_4_YEARS;
483 y -= n_4_years * 4;
484
485 const uint64_t n_1_years = secs / SEC_PER_YEAR;
486 secs -= n_1_years * SEC_PER_YEAR;
487 y -= n_1_years;
488
489 T1 date_time;
490
491 if (secs == 0) {
492 date_time.year = y;
493 date_time.mon = 1;
494 date_time.day = 1;
495 return date_time;
496 }
497
498 date_time.year = y - 1;
499 const bool is_leap_year = is_leap_year_date(date_time.year);
500 secs = is_leap_year ? SEC_PER_LEAP_YEAR - secs : SEC_PER_YEAR - secs;
501 const int days = static_cast<int>(secs / SEC_PER_DAY);
502
503 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60 - 1;
504 constexpr int TABLE_MONTH_OF_YEAR[] = {
505 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 январь
506 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 февраль
507 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 март
508 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 апрель
509 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,
510 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,
511 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,
512 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,
513 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,
514 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,
515 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,
516 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,
517 };
518 constexpr int TABLE_DAY_OF_YEAR[] = {
519 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 январь
520 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 февраль
521 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 март
522 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 апрель
523 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,
524 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,
525 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,
526 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,
527 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,
528 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,
529 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,
530 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,
531 };
532
533 if (is_leap_year) {
534 const int prev_days = days - 1;
535 date_time.day = days == JAN_AND_FEB_DAY_LEAP_YEAR ? (TABLE_DAY_OF_YEAR[prev_days] + 1) :
536 (days > JAN_AND_FEB_DAY_LEAP_YEAR ? TABLE_DAY_OF_YEAR[prev_days] : TABLE_DAY_OF_YEAR[days]);
537 date_time.mon = days >= JAN_AND_FEB_DAY_LEAP_YEAR ? TABLE_MONTH_OF_YEAR[prev_days] : TABLE_MONTH_OF_YEAR[days];
538 } else {
539 date_time.day = TABLE_DAY_OF_YEAR[days];
540 date_time.mon = TABLE_MONTH_OF_YEAR[days];
541 }
542
543 ts_t day_secs = static_cast<ts_t>(secs % SEC_PER_DAY);
544 date_time.hour = static_cast<decltype(date_time.hour)>(day_secs / SEC_PER_HOUR);
545 ts_t min_secs = static_cast<ts_t>(day_secs - date_time.hour * SEC_PER_HOUR);
546 date_time.min = static_cast<decltype(date_time.min)>(min_secs / SEC_PER_MIN);
547 date_time.sec = static_cast<decltype(date_time.sec)>(min_secs - date_time.min * SEC_PER_MIN);
548# ifdef TIME_SHIELD_CPP17
549 if TIME_SHIELD_IF_CONSTEXPR (std::is_floating_point<T2>::value) {
550 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
551 } else date_time.ms = 0;
552# else
553 if (std::is_floating_point<T2>::value) {
554 date_time.ms = static_cast<int>(std::round(std::fmod(static_cast<double>(ts), static_cast<double>(MS_PER_SEC))));
555 } else date_time.ms = 0;
556# endif
557 return date_time;
558 }
559
560//------------------------------------------------------------------------------
561
567 template<class T>
570 date_time.ms = ms_of_ts(ts); // Extract and set the ms component
571 return date_time;
572 }
573
574//------------------------------------------------------------------------------
575
606 template<class T1 = year_t, class T2 = int>
607 TIME_SHIELD_CONSTEXPR inline ts_t to_timestamp(
608 T1 year,
609 T2 month,
610 T2 day,
611 T2 hour = 0,
612 T2 min = 0,
613 T2 sec = 0) {
614
615 if (day >= UNIX_EPOCH && year <= 31) {
616 return to_timestamp((T1)day, month, (T2)year, hour, min, sec);
617 }
618 if (!is_valid_date_time(year, month, day, hour, min, sec)) {
619 throw std::invalid_argument("Invalid date-time combination");
620 }
621
622 int64_t secs = 0;
623 uint64_t years = (static_cast<int64_t>(MAX_YEAR) - year);
624
625 const int64_t n_400_years = years / 400;
626 secs += n_400_years * SEC_PER_400_YEARS;
627 years -= n_400_years * 400;
628
629 const int64_t n_100_years = years / 100;
630 secs += n_100_years * SEC_PER_100_YEARS;
631 years -= n_100_years * 100;
632
633 const int64_t n_4_years = years / 4;
634 secs += n_4_years * SEC_PER_4_YEARS;
635 years -= n_4_years * 4;
636
637 secs += years * SEC_PER_YEAR;
638
639 // 9223372029693630000 - значение на момент 292277024400 от 2000 года
640 // Такое значение приводит к неправильному вычислению умножения n_400_years * SEC_PER_400_YEARS
641 // Поэтому пришлось снизить до 9223371890843040000
642 constexpr int64_t BIAS_292277022000 = 9223371890843040000LL;
643 constexpr int64_t BIAS_2000 = 946684800LL;
644
645 secs = BIAS_292277022000 - secs;
646 secs += BIAS_2000;
647
648 if (month == 1 && day == 1 &&
649 hour == 0 && min == 0 &&
650 sec == 0) {
651 return secs;
652 }
653
654 constexpr int lmos[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
655 constexpr int mos[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
656
657 secs += (is_leap_year_date(year) ? (lmos[month - 1] + day - 1) : (mos[month - 1] + day - 1)) * SEC_PER_DAY;
658 secs += SEC_PER_HOUR * hour + SEC_PER_MIN * min + sec;
659 return secs;
660 }
661
662//------------------------------------------------------------------------------
663
674 template<class T>
675 TIME_SHIELD_CONSTEXPR inline ts_t dt_to_timestamp(
676 const T& date_time) {
677 return to_timestamp(
678 date_time.year,
679 date_time.mon,
680 date_time.day,
681 date_time.hour,
682 date_time.min,
683 date_time.sec);
684 }
685
686//------------------------------------------------------------------------------
687
696 TIME_SHIELD_CONSTEXPR inline ts_t tm_to_timestamp(
697 const std::tm *timeinfo) {
698 return to_timestamp(
699 timeinfo->tm_year + 1900,
700 timeinfo->tm_mon + 1,
701 timeinfo->tm_mday,
702 timeinfo->tm_hour,
703 timeinfo->tm_min,
704 timeinfo->tm_sec);
705 }
706
707//------------------------------------------------------------------------------
708
725 template<class T1 = year_t, class T2 = int>
726 TIME_SHIELD_CONSTEXPR inline ts_ms_t to_timestamp_ms(
727 T1 year,
728 T2 month,
729 T2 day,
730 T2 hour = 0,
731 T2 min = 0,
732 T2 sec = 0,
733 T2 ms = 0) {
734 return sec_to_ms(to_timestamp<T1, T2>(year, month, day, hour, min, sec)) + ms;
735 }
736
737//------------------------------------------------------------------------------
738
749 template<class T>
750 TIME_SHIELD_CONSTEXPR inline ts_t dt_to_timestamp_ms(
751 const T& date_time) {
752 return sec_to_ms(dt_to_timestamp(date_time)) + date_time.ms;
753 }
754
755//------------------------------------------------------------------------------
756
765 TIME_SHIELD_CONSTEXPR inline ts_t tm_to_timestamp_ms(
766 const std::tm *timeinfo) {
767 return sec_to_ms(tm_to_timestamp(timeinfo));
768 }
769
770//------------------------------------------------------------------------------
771
790 template<class T1 = year_t, class T2 = int, class T3 = int>
791 TIME_SHIELD_CONSTEXPR inline fts_t to_ftimestamp(
792 T1 year,
793 T2 month,
794 T2 day,
795 T2 hour = 0,
796 T2 min = 0,
797 T2 sec = 0,
798 T3 ms = 0) {
799 return static_cast<fts_t>(to_timestamp(year, month, day, hour, min, sec)) +
800 static_cast<fts_t>(ms)/static_cast<fts_t>(MS_PER_SEC);
801 }
802
803//------------------------------------------------------------------------------
804
816 template<class T>
817 TIME_SHIELD_CONSTEXPR inline fts_t dt_to_ftimestamp(
818 const T& date_time) {
819 return static_cast<fts_t>(to_timestamp(date_time)) +
820 static_cast<fts_t>(date_time.ms)/static_cast<fts_t>(MS_PER_SEC);
821 }
822
823//------------------------------------------------------------------------------
824
834 TIME_SHIELD_CONSTEXPR inline fts_t tm_to_ftimestamp(
835 const std::tm* timeinfo) {
836 return static_cast<fts_t>(tm_to_timestamp(timeinfo));
837 }
838
839//------------------------------------------------------------------------------
840
853 template<class Year, class Month, class Day>
854 TIME_SHIELD_CONSTEXPR inline uday_t date_to_unix_day(
855 Year year,
856 Month month,
857 Day day) noexcept {
858 const int64_t y = static_cast<int64_t>(year) - (static_cast<int64_t>(month) <= 2 ? 1 : 0);
859 const int64_t m = static_cast<int64_t>(month) <= 2
860 ? static_cast<int64_t>(month) + 9
861 : static_cast<int64_t>(month) - 3;
862 const int64_t era = (y >= 0 ? y : y - 399) / 400;
863 const int64_t yoe = y - era * 400;
864 const int64_t doy = (153 * m + 2) / 5 + static_cast<int64_t>(day) - 1;
865 const int64_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
866 return static_cast<uday_t>(era * 146097 + doe - 719468);
867 }
868
876 template<class T = uday_t>
877 constexpr T get_unix_day(ts_t ts = time_shield::ts()) noexcept {
878 return ts / SEC_PER_DAY;
879 }
880
881//------------------------------------------------------------------------------
882
891 template<class T = int>
892 constexpr T get_days_difference(ts_t start, ts_t stop) noexcept {
893 return (stop - start) / SEC_PER_DAY;
894 }
895
896//------------------------------------------------------------------------------
897
905 template<class T = uday_t>
906 constexpr T get_unix_day_ms(ts_ms_t t_ms = time_shield::ts_ms()) noexcept {
907 return get_unix_day(ms_to_sec(t_ms));
908 }
909
910//------------------------------------------------------------------------------
911
920 template<class T = ts_t>
921 constexpr T unix_day_to_timestamp(uday_t unix_day) noexcept {
922 return unix_day * SEC_PER_DAY;
923 }
924
925//------------------------------------------------------------------------------
926
935 template<class T = ts_t>
937 return unix_day * MS_PER_DAY;
938 }
939
940//------------------------------------------------------------------------------
941
950 template<class T = ts_t>
952 return unix_day * SEC_PER_DAY + SEC_PER_DAY - 1;
953 }
954
963 template<class T = ts_ms_t>
965 return unix_day * MS_PER_DAY + MS_PER_DAY - 1;
966 }
967
976 template<class T = ts_ms_t>
979 }
980
989 template<class T = ts_ms_t>
993
994//------------------------------------------------------------------------------
995
1003 template<class T = int64_t>
1005 return ts / SEC_PER_MIN;
1006 }
1007
1008//------------------------------------------------------------------------------
1009
1017 template<class T = int>
1018 constexpr T sec_of_day(ts_t ts = time_shield::ts()) noexcept {
1019 return ts % SEC_PER_DAY;
1020 }
1021
1029 template<class T = int>
1030 constexpr T sec_of_day_ms(ts_ms_t ts_ms) noexcept {
1031 return sec_of_day(ms_to_sec(ts_ms));
1032 }
1033
1044 template<class T1 = int, class T2 = int>
1045 constexpr T1 sec_of_day(
1046 T2 hour,
1047 T2 min,
1048 T2 sec) noexcept {
1049 return hour * SEC_PER_HOUR + min * SEC_PER_MIN + sec;
1050 }
1051
1059 template<class T = int>
1061 return (ts % SEC_PER_MIN);
1062 }
1063
1071 template<class T = int>
1073 return (ts % SEC_PER_HOUR);
1074 }
1075
1076//------------------------------------------------------------------------------
1077
1085 template<class T = year_t>
1086 TIME_SHIELD_CONSTEXPR inline T get_year(ts_t ts = time_shield::ts()) {
1087 return get_unix_year(ts) + UNIX_EPOCH;
1088 }
1089
1090//------------------------------------------------------------------------------
1091
1099 template<class T = year_t>
1100 TIME_SHIELD_CONSTEXPR inline T get_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) {
1101 return get_year(ms_to_sec(ts_ms));
1102 }
1103
1104//------------------------------------------------------------------------------
1105
1113 TIME_SHIELD_CONSTEXPR inline ts_t start_of_year(ts_t ts) noexcept {
1114 constexpr ts_t BIAS_2100 = 4102444800;
1115 if (ts < BIAS_2100) {
1116 constexpr ts_t SEC_PER_YEAR_X2 = SEC_PER_YEAR * 2;
1117 ts_t year_start_ts = ts % SEC_PER_4_YEARS;
1118 if (year_start_ts < SEC_PER_YEAR) {
1119 return ts - year_start_ts;
1120 } else
1121 if (year_start_ts < SEC_PER_YEAR_X2) {
1122 return ts + SEC_PER_YEAR - year_start_ts;
1123 } else
1124 if (year_start_ts < (SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR)) {
1125 return ts + SEC_PER_YEAR_X2 - year_start_ts;
1126 }
1127 return ts + (SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR) - year_start_ts;
1128 }
1129
1130 constexpr ts_t BIAS_2000 = 946684800;
1131 ts_t secs = ts - BIAS_2000;
1132
1133 ts_t offset_y400 = secs % SEC_PER_400_YEARS;
1134 ts_t start_ts = secs - offset_y400 + BIAS_2000;
1135 secs = offset_y400;
1136
1137 if (secs >= SEC_PER_FIRST_100_YEARS) {
1139 start_ts += SEC_PER_FIRST_100_YEARS;
1140 while (secs >= SEC_PER_100_YEARS) {
1141 secs -= SEC_PER_100_YEARS;
1142 start_ts += SEC_PER_100_YEARS;
1143 }
1144
1145 constexpr ts_t SEC_PER_4_YEARS_V2 = 4 * SEC_PER_YEAR;
1146 if (secs >= SEC_PER_4_YEARS_V2) {
1147 secs -= SEC_PER_4_YEARS_V2;
1148 start_ts += SEC_PER_4_YEARS_V2;
1149 } else {
1150 start_ts += secs - secs % SEC_PER_YEAR;
1151 return start_ts;
1152 }
1153 }
1154
1155 ts_t offset_4y = secs % SEC_PER_4_YEARS;
1156 start_ts += secs - offset_4y;
1157 secs = offset_4y;
1158
1159 if (secs >= SEC_PER_LEAP_YEAR) {
1160 secs -= SEC_PER_LEAP_YEAR;
1161 start_ts += SEC_PER_LEAP_YEAR;
1162 start_ts += secs - secs % SEC_PER_YEAR;
1163 }
1164 return start_ts;
1165 }
1166
1167//------------------------------------------------------------------------------
1168
1176 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) noexcept {
1178 }
1179
1180//------------------------------------------------------------------------------
1181
1189 template<class T = year_t>
1190 TIME_SHIELD_CONSTEXPR inline ts_t start_of_year_date(T year) {
1191 if (year < 2100) {
1192 const ts_t year_diff = year >= UNIX_EPOCH ? year - UNIX_EPOCH : UNIX_EPOCH - year;
1193 const ts_t year_start_ts = (year_diff / 4) * SEC_PER_4_YEARS;
1194 const ts_t year_remainder = year_diff % 4;
1195 constexpr ts_t SEC_PER_YEAR_X2 = 2 * SEC_PER_YEAR;
1196 constexpr ts_t SEC_PER_YEAR_V2 = SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR;
1197 switch (year_remainder) {
1198 case 0: return year_start_ts;
1199 case 1: return year_start_ts + SEC_PER_YEAR;
1200 case 2: return year_start_ts + SEC_PER_YEAR_X2;
1201 default: break;
1202 };
1203 return year_start_ts + SEC_PER_YEAR_V2;
1204 }
1205 return to_timestamp(year, 1, 1);
1206 }
1207
1208//------------------------------------------------------------------------------
1209
1217 template<class T = year_t>
1218 TIME_SHIELD_CONSTEXPR inline ts_ms_t start_of_year_date_ms(T year) {
1220 }
1221
1222//------------------------------------------------------------------------------
1223
1230 TIME_SHIELD_CONSTEXPR inline ts_t end_of_year(ts_t ts = time_shield::ts()) {
1231 constexpr ts_t BIAS_2100 = 4102444800;
1232 if (ts < BIAS_2100) {
1233 constexpr ts_t SEC_PER_YEAR_X2 = SEC_PER_YEAR * 2;
1234 constexpr ts_t SEC_PER_YEAR_X3 = SEC_PER_YEAR * 3;
1235 constexpr ts_t SEC_PER_YEAR_X3_V2 = SEC_PER_YEAR_X2 + SEC_PER_LEAP_YEAR;
1236 ts_t year_end_ts = ts % SEC_PER_4_YEARS;
1237 if (year_end_ts < SEC_PER_YEAR) {
1238 return ts + SEC_PER_YEAR - year_end_ts - 1;
1239 } else
1240 if (year_end_ts < SEC_PER_YEAR_X2) {
1241 return ts + SEC_PER_YEAR_X2 - year_end_ts - 1;
1242 } else
1243 if (year_end_ts < SEC_PER_YEAR_X3_V2) {
1244 return ts + SEC_PER_YEAR_X3_V2 - year_end_ts - 1;
1245 }
1246 return ts + (SEC_PER_YEAR_X3 + SEC_PER_LEAP_YEAR) - year_end_ts - 1;
1247 }
1248
1249 constexpr ts_t BIAS_2000 = 946684800;
1250 ts_t secs = ts - BIAS_2000;
1251
1252 ts_t offset_y400 = secs % SEC_PER_400_YEARS;
1253 ts_t end_ts = secs - offset_y400 + BIAS_2000;
1254 secs = offset_y400;
1255
1256 if (secs >= SEC_PER_FIRST_100_YEARS) {
1258 end_ts += SEC_PER_FIRST_100_YEARS;
1259 while (secs >= SEC_PER_100_YEARS) {
1260 secs -= SEC_PER_100_YEARS;
1261 end_ts += SEC_PER_100_YEARS;
1262 }
1263
1264 constexpr ts_t SEC_PER_4_YEARS_V2 = 4 * SEC_PER_YEAR;
1265 if (secs >= SEC_PER_4_YEARS_V2) {
1266 secs -= SEC_PER_4_YEARS_V2;
1267 end_ts += SEC_PER_4_YEARS_V2;
1268 } else {
1269 end_ts += secs - secs % SEC_PER_YEAR;
1270 return end_ts + SEC_PER_YEAR - 1;
1271 }
1272 }
1273
1274 ts_t offset_4y = secs % SEC_PER_4_YEARS;
1275 end_ts += secs - offset_4y;
1276 secs = offset_4y;
1277
1278 if (secs >= SEC_PER_LEAP_YEAR) {
1279 secs -= SEC_PER_LEAP_YEAR;
1280 end_ts += SEC_PER_LEAP_YEAR;
1281 end_ts += secs - secs % SEC_PER_YEAR;
1282 end_ts += SEC_PER_YEAR;
1283 } else {
1284 end_ts += SEC_PER_LEAP_YEAR;
1285 }
1286 return end_ts - 1;
1287 }
1288
1289//------------------------------------------------------------------------------
1290
1297 template<class T = year_t>
1298 TIME_SHIELD_CONSTEXPR inline ts_ms_t end_of_year_ms(ts_ms_t ts_ms = time_shield::ts_ms()) {
1300 }
1301
1302//------------------------------------------------------------------------------
1303
1310 template<class T = int>
1312 return static_cast<T>(((ts - start_of_year(ts)) / SEC_PER_DAY) + 1);
1313 }
1314
1315//------------------------------------------------------------------------------
1316
1323 template<class T = Month>
1324 TIME_SHIELD_CONSTEXPR inline T month_of_year(ts_t ts) noexcept {
1325 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60;
1326 constexpr int TABLE_MONTH_OF_YEAR[] = {
1327 0,
1328 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 январь
1329 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 февраль
1330 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 март
1331 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 апрель
1332 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,
1333 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,
1334 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,
1335 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,
1336 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,
1337 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,
1338 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,
1339 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,
1340 };
1341 const size_t dy = day_of_year(ts);
1342 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]);
1343 }
1344
1345//------------------------------------------------------------------------------
1346
1353 template<class T = int>
1354 TIME_SHIELD_CONSTEXPR inline T day_of_month(ts_t ts = time_shield::ts()) {
1355 constexpr int JAN_AND_FEB_DAY_LEAP_YEAR = 60;
1356 // таблица для обычного года, не високосного
1357 constexpr int TABLE_DAY_OF_YEAR[] = {
1358 0,
1359 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 январь
1360 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 февраль
1361 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 март
1362 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 апрель
1363 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,
1364 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,
1365 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,
1366 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,
1367 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,
1368 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,
1369 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,
1370 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,
1371 };
1372 const size_t dy = day_of_year(ts);
1373 if(is_leap_year(ts)) {
1374 if(dy == JAN_AND_FEB_DAY_LEAP_YEAR) return TABLE_DAY_OF_YEAR[dy - 1] + 1;
1375 if(dy > JAN_AND_FEB_DAY_LEAP_YEAR) return TABLE_DAY_OF_YEAR[dy - 1];
1376 }
1377 return TABLE_DAY_OF_YEAR[dy];
1378 }
1379
1380//------------------------------------------------------------------------------
1381
1389 template<class T1 = int, class T2 = year_t, class T3 = int>
1390 constexpr T1 num_days_in_month(T2 year, T3 month) noexcept {
1391 if (month > MONTHS_PER_YEAR || month < 0) return 0;
1392 constexpr T1 num_days[13] = {0,31,30,31,30,31,30,31,31,30,31,30,31};
1393 if (month == FEB) {
1394 if (is_leap_year_date(year)) return 29;
1395 return 28;
1396 }
1397 return num_days[month];
1398 }
1399
1400//------------------------------------------------------------------------------
1401
1408 template<class T1 = int>
1409 TIME_SHIELD_CONSTEXPR T1 num_days_in_month_ts(ts_t ts = time_shield::ts()) noexcept {
1410 constexpr T1 num_days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
1411 const int month = month_of_year(ts);
1412 if (month == FEB) {
1413 return is_leap_year(ts) ? 29 : 28;
1414 }
1415 return num_days[month];
1416 }
1417
1418//------------------------------------------------------------------------------
1419
1424 TIME_SHIELD_CONSTEXPR inline int first_workday_day(year_t year, int month) noexcept {
1425 const int days = num_days_in_month(year, month);
1426 if (days <= 0) {
1427 return 0;
1428 }
1429 for (int day = 1; day <= days; ++day) {
1430 if (is_workday(year, month, day)) {
1431 return day;
1432 }
1433 }
1434 return 0;
1435 }
1436
1441 TIME_SHIELD_CONSTEXPR inline int last_workday_day(year_t year, int month) noexcept {
1442 const int days = num_days_in_month(year, month);
1443 if (days <= 0) {
1444 return 0;
1445 }
1446 for (int day = days; day >= 1; --day) {
1447 if (is_workday(year, month, day)) {
1448 return day;
1449 }
1450 }
1451 return 0;
1452 }
1453
1458 TIME_SHIELD_CONSTEXPR inline int count_workdays_in_month(year_t year, int month) noexcept {
1459 const int days = num_days_in_month(year, month);
1460 if (days <= 0) {
1461 return 0;
1462 }
1463 int total = 0;
1464 for (int day = 1; day <= days; ++day) {
1465 if (is_workday(year, month, day)) {
1466 ++total;
1467 }
1468 }
1469 return total;
1470 }
1471
1477 TIME_SHIELD_CONSTEXPR inline int workday_index_in_month(year_t year, int month, int day) noexcept {
1478 if (!is_workday(year, month, day)) {
1479 return 0;
1480 }
1481 const int days = num_days_in_month(year, month);
1482 if (days <= 0) {
1483 return 0;
1484 }
1485 int index = 0;
1486 for (int current = 1; current <= days; ++current) {
1487 if (is_workday(year, month, current)) {
1488 ++index;
1489 if (current == day) {
1490 return index;
1491 }
1492 }
1493 }
1494 return 0;
1495 }
1496
1497//------------------------------------------------------------------------------
1498
1504 TIME_SHIELD_CONSTEXPR inline bool is_first_workday_of_month(year_t year, int month, int day) noexcept {
1505 return is_workday(year, month, day) && first_workday_day(year, month) == day;
1506 }
1507
1508//------------------------------------------------------------------------------
1509
1516 TIME_SHIELD_CONSTEXPR inline bool is_within_first_workdays_of_month(year_t year, int month, int day, int count) noexcept {
1517 if (count <= 0) {
1518 return false;
1519 }
1520 const int total = count_workdays_in_month(year, month);
1521 if (count > total) {
1522 return false;
1523 }
1524 const int index = workday_index_in_month(year, month, day);
1525 return index > 0 && index <= count;
1526 }
1527
1528//------------------------------------------------------------------------------
1529
1535 TIME_SHIELD_CONSTEXPR inline bool is_last_workday_of_month(year_t year, int month, int day) noexcept {
1536 return is_workday(year, month, day) && last_workday_day(year, month) == day;
1537 }
1538
1539//------------------------------------------------------------------------------
1540
1547 TIME_SHIELD_CONSTEXPR inline bool is_within_last_workdays_of_month(year_t year, int month, int day, int count) noexcept {
1548 if (count <= 0) {
1549 return false;
1550 }
1551 const int total = count_workdays_in_month(year, month);
1552 if (count > total) {
1553 return false;
1554 }
1555 const int index = workday_index_in_month(year, month, day);
1556 return index > 0 && index >= (total - count + 1);
1557 }
1558
1559//------------------------------------------------------------------------------
1560
1564 TIME_SHIELD_CONSTEXPR inline bool is_first_workday_of_month(ts_t ts) noexcept {
1565 const year_t year = get_year(ts);
1566 const int month = month_of_year(ts);
1567 const int day = day_of_month(ts);
1568 return is_first_workday_of_month(year, month, day);
1569 }
1570
1571//------------------------------------------------------------------------------
1572
1577 TIME_SHIELD_CONSTEXPR inline bool is_within_first_workdays_of_month(ts_t ts, int count) noexcept {
1578 const year_t year = get_year(ts);
1579 const int month = month_of_year(ts);
1580 const int day = day_of_month(ts);
1581 return is_within_first_workdays_of_month(year, month, day, count);
1582 }
1583
1584//------------------------------------------------------------------------------
1585
1589 TIME_SHIELD_CONSTEXPR inline bool is_last_workday_of_month(ts_t ts) noexcept {
1590 const year_t year = get_year(ts);
1591 const int month = month_of_year(ts);
1592 const int day = day_of_month(ts);
1593 return is_last_workday_of_month(year, month, day);
1594 }
1595
1596//------------------------------------------------------------------------------
1597
1602 TIME_SHIELD_CONSTEXPR inline bool is_within_last_workdays_of_month(ts_t ts, int count) noexcept {
1603 const year_t year = get_year(ts);
1604 const int month = month_of_year(ts);
1605 const int day = day_of_month(ts);
1606 return is_within_last_workdays_of_month(year, month, day, count);
1607 }
1608
1609//------------------------------------------------------------------------------
1610
1614 TIME_SHIELD_CONSTEXPR inline bool is_first_workday_of_month_ms(ts_ms_t ts_ms) noexcept {
1616 }
1617
1618//------------------------------------------------------------------------------
1619
1624 TIME_SHIELD_CONSTEXPR inline bool is_within_first_workdays_of_month_ms(ts_ms_t ts_ms, int count) noexcept {
1626 }
1627
1628//------------------------------------------------------------------------------
1629
1633 TIME_SHIELD_CONSTEXPR inline bool is_last_workday_of_month_ms(ts_ms_t ts_ms) noexcept {
1635 }
1636
1637//------------------------------------------------------------------------------
1638
1643 TIME_SHIELD_CONSTEXPR inline bool is_within_last_workdays_of_month_ms(ts_ms_t ts_ms, int count) noexcept {
1645 }
1646
1647//------------------------------------------------------------------------------
1648
1655 template<class T1 = int, class T2 = year_t>
1656 constexpr T1 num_days_in_year(T2 year) noexcept {
1658 return DAYS_PER_YEAR;
1659 }
1660
1661//------------------------------------------------------------------------------
1662
1669 template<class T = int>
1672 return DAYS_PER_YEAR;
1673 }
1674
1675//------------------------------------------------------------------------------
1676
1684 constexpr ts_t start_of_day(ts_t ts = time_shield::ts()) noexcept {
1685 return ts - (ts % SEC_PER_DAY);
1686 }
1687
1688//------------------------------------------------------------------------------
1689
1697 template<class T = int>
1698 constexpr ts_t start_of_prev_day(ts_t ts = time_shield::ts(), T days = 1) noexcept {
1699 return ts - (ts % SEC_PER_DAY) - SEC_PER_DAY * days;
1700 }
1701
1702//------------------------------------------------------------------------------
1703
1712 return start_of_day(ms_to_sec(ts_ms));
1713 }
1714
1715//------------------------------------------------------------------------------
1716
1725 return ts_ms - (ts_ms % MS_PER_DAY);
1726 }
1727
1728//------------------------------------------------------------------------------
1729
1738 template<class T = int>
1739 constexpr ts_t start_of_next_day(ts_t ts, T days = 1) noexcept {
1740 return start_of_day(ts) + days * SEC_PER_DAY;
1741 }
1742
1743//------------------------------------------------------------------------------
1744
1753 template<class T = int>
1754 constexpr ts_ms_t start_of_next_day_ms(ts_ms_t ts_ms, T days = 1) noexcept {
1756 }
1757
1758//------------------------------------------------------------------------------
1759
1767 template<class T = int>
1768 constexpr ts_t next_day(ts_t ts, T days = 1) noexcept {
1769 return ts + days * SEC_PER_DAY;
1770 }
1771
1779 template<class T = int>
1780 constexpr ts_ms_t next_day_ms(ts_ms_t ts_ms, T days = 1) noexcept {
1781 return ts_ms + days * MS_PER_DAY;
1782 }
1783
1784//------------------------------------------------------------------------------
1785
1792 constexpr ts_t end_of_day(ts_t ts = time_shield::ts()) noexcept {
1793 return ts - (ts % SEC_PER_DAY) + SEC_PER_DAY - 1;
1794 }
1795
1796//------------------------------------------------------------------------------
1797
1805 return end_of_day(ms_to_sec(ts_ms));
1806 }
1807
1808//------------------------------------------------------------------------------
1809
1817 return ts_ms - (ts_ms % MS_PER_DAY) + MS_PER_DAY - 1;
1818 }
1819
1820//------------------------------------------------------------------------------
1821
1831 template<class T1 = Weekday, class T2 = year_t, class T3 = int, class T4 = int>
1832 constexpr T1 day_of_week_date(T2 year, T3 month, T4 day) {
1833 year_t a, y, m, R;
1834 a = (14 - month) / MONTHS_PER_YEAR;
1835 y = year - a;
1836 m = month + MONTHS_PER_YEAR * a - 2;
1837 R = 7000 + ( day + y + (y / 4) - (y / 100) + (y / 400) + (31 * m) / MONTHS_PER_YEAR);
1838 return static_cast<T1>(R % DAYS_PER_WEEK);
1839 }
1840
1841//------------------------------------------------------------------------------
1842
1851 template<class T1 = Weekday, class T2>
1852 constexpr T1 get_weekday_from_date(const T2& date) {
1853 return day_of_week_date(date.year, date.mon, date.day);
1854 }
1855
1856//------------------------------------------------------------------------------
1857
1861 template<class T = Weekday>
1862 constexpr T get_weekday_from_ts(ts_t ts) noexcept {
1863 return static_cast<T>((ts / SEC_PER_DAY + THU) % DAYS_PER_WEEK);
1864 }
1865
1866//------------------------------------------------------------------------------
1867
1871 template<class T = Weekday>
1875
1876//------------------------------------------------------------------------------
1877
1885 TIME_SHIELD_CONSTEXPR inline ts_t start_of_month(ts_t ts = time_shield::ts()) {
1886 return start_of_day(ts) - (day_of_month(ts) - 1) * SEC_PER_DAY;
1887 }
1888
1889//------------------------------------------------------------------------------
1890
1898 TIME_SHIELD_CONSTEXPR inline ts_t end_of_month(ts_t ts = time_shield::ts()) {
1900 }
1901
1902//------------------------------------------------------------------------------
1903
1911 TIME_SHIELD_CONSTEXPR inline ts_t last_sunday_of_month(ts_t ts = time_shield::ts()) {
1913 }
1914
1915//------------------------------------------------------------------------------
1916
1924 template<class T1 = int, class T2 = year_t, class T3 = int>
1925 TIME_SHIELD_CONSTEXPR inline T1 last_sunday_month_day(T2 year, T3 month) {
1926 const T1 days = num_days_in_month(year, month);
1927 return days - day_of_week_date(year, month, days);
1928 }
1929
1930//------------------------------------------------------------------------------
1931
1938 constexpr ts_t start_of_hour(ts_t ts = time_shield::ts()) noexcept {
1939 return ts - (ts % SEC_PER_HOUR);
1940 }
1941
1942//------------------------------------------------------------------------------
1943
1951 return start_of_hour(ms_to_sec(ts_ms));
1952 }
1953
1954//------------------------------------------------------------------------------
1955
1961 return ts_ms - (ts_ms % MS_PER_HOUR);
1962 }
1963
1964//------------------------------------------------------------------------------
1965
1970 constexpr ts_t end_of_hour(ts_t ts = time_shield::ts()) noexcept {
1971 return ts - (ts % SEC_PER_HOUR) + SEC_PER_HOUR - 1;
1972 }
1973
1974//------------------------------------------------------------------------------
1975
1983 return end_of_hour(ms_to_sec(ts_ms));
1984 }
1985
1986//------------------------------------------------------------------------------
1987
1995 return ts_ms - (ts_ms % MS_PER_HOUR) + MS_PER_HOUR - 1;
1996 }
1997
1998//------------------------------------------------------------------------------
1999
2006 template<class T = int>
2007 constexpr T hour_of_day(ts_t ts = time_shield::ts()) noexcept {
2008 return ((ts / SEC_PER_HOUR) % HOURS_PER_DAY);
2009 }
2010
2011//------------------------------------------------------------------------------
2012
2023
2024//------------------------------------------------------------------------------
2025
2036
2037//------------------------------------------------------------------------------
2038
2049
2050//------------------------------------------------------------------------------
2051
2055 constexpr ts_t start_of_min(ts_t ts = time_shield::ts()) noexcept {
2056 return ts - (ts % SEC_PER_MIN);
2057 }
2058
2059//------------------------------------------------------------------------------
2060
2064 constexpr ts_t end_of_min(ts_t ts = time_shield::ts()) noexcept {
2065 return ts - (ts % SEC_PER_MIN) + SEC_PER_MIN - 1;
2066 }
2067
2068//------------------------------------------------------------------------------
2069
2074 template<class T = int>
2075 constexpr T min_of_day(ts_t ts = time_shield::ts()) noexcept {
2076 return ((ts / SEC_PER_MIN) % MIN_PER_DAY);
2077 }
2078
2079//------------------------------------------------------------------------------
2080
2085 template<class T = int>
2086 constexpr T min_of_hour(ts_t ts = time_shield::ts()) noexcept {
2087 return ((ts / SEC_PER_MIN) % MIN_PER_HOUR);
2088 }
2089
2090//------------------------------------------------------------------------------
2091
2096 template<class T = int>
2098 return ts - (ts % p);
2099 }
2100
2101//------------------------------------------------------------------------------
2102
2107 template<class T = int>
2109 return ts - (ts % p) + p - 1;
2110 }
2111
2112//------------------------------------------------------------------------------
2113
2119 template<class T = TimeZoneStruct>
2120 inline T to_time_zone(tz_t offset) {
2121 T tz;
2122 int abs_val = std::abs(offset);
2123 tz.hour = abs_val / SEC_PER_HOUR;
2124 tz.min = (abs_val % SEC_PER_HOUR) / SEC_PER_MIN;
2125 tz.is_positive = (offset >= 0);
2126 return tz;
2127 }
2128
2130
2131}; // namespace time_shield
2132
2134
2135#endif // _TIME_SHIELD_TIME_CONVERSIONS_HPP_INCLUDED
Header for date and time structure and related functions.
Header file with enumerations for weekdays, months, and other time-related categories.
constexpr int64_t MIN_PER_HOUR
Minutes per hour.
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 DAYS_PER_YEAR
Days 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 MS_PER_MIN
Milliseconds per minute.
Definition constants.hpp:83
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 DAYS_PER_LEAP_YEAR
Days per leap year.
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 NS_PER_SEC
Nanoseconds per second.
Definition constants.hpp:73
constexpr int64_t MS_PER_HOUR
Milliseconds per hour.
Definition constants.hpp:90
constexpr int64_t US_PER_SEC
Microseconds per second.
Definition constants.hpp:76
constexpr int64_t SEC_PER_4_YEARS
Seconds per 4 years.
TIME_SHIELD_CONSTEXPR ts_t tm_to_timestamp(const std::tm *timeinfo)
Converts a std::tm structure to a timestamp.
constexpr T sec_of_hour(ts_t ts=time_shield::ts())
Get the second of the hour.
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. This function sets the minute and second to 59.
constexpr T unix_day(ts_t ts=time_shield::ts()) noexcept
Alias for get_unix_day function.
constexpr T end_of_day_from_unix_day_ms(uday_t unix_day) noexcept
Converts a UNIX day to a timestamp representing the end of the day in milliseconds.
TIME_SHIELD_CONSTEXPR fts_t dt_to_ftimestamp(const T &date_time)
Converts a date-time structure to a floating-point timestamp.
constexpr T sec_of_min(ts_t ts=time_shield::ts())
Get the second of the minute.
TIME_SHIELD_CONSTEXPR fts_t tm_to_ftimestamp(const std::tm *timeinfo)
Converts a std::tm structure to a floating-point timestamp.
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 T get_year(ts_t ts=time_shield::ts())
Get the year from the timestamp.
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 bool is_first_workday_of_month_ms(ts_ms_t ts_ms) noexcept
Check whether a timestamp in milliseconds falls on the first workday of its month.
constexpr T get_unix_day(ts_t ts=time_shield::ts()) noexcept
Get UNIX day.
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 bool is_within_last_workdays_of_month_ms(ts_ms_t ts_ms, int count) noexcept
Check whether a timestamp in milliseconds falls within the last N workdays of its month.
constexpr T get_days_difference(ts_t start, ts_t stop) noexcept
Get the number of days between two timestamps.
constexpr T1 min_to_sec(T2 ts) noexcept
Converts a timestamp from minutes to seconds.
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 bool is_within_first_workdays_of_month(year_t year, int month, int day, int count) noexcept
Check whether a date is within the first N workdays of its month.
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.
constexpr T start_of_next_day_from_unix_day(uday_t unix_day) noexcept
Converts a UNIX day to a timestamp representing the start of the next day in seconds.
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 int last_workday_day(year_t year, int month) noexcept
Compute the calendar day number of the last workday in a month.
constexpr T sec_of_day(ts_t ts=time_shield::ts()) noexcept
Get the second of the day.
constexpr T1 hour_to_ms(T2 ts) noexcept
Converts a timestamp from hours to milliseconds.
TIME_SHIELD_CONSTEXPR uday_t date_to_unix_day(Year year, Month month, Day day) noexcept
Convert a calendar date to UNIX day count.
TIME_SHIELD_CONSTEXPR bool is_within_first_workdays_of_month_ms(ts_ms_t ts_ms, int count) noexcept
Check whether a timestamp in milliseconds falls within the first N workdays of its month.
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
Get the millisecond part of the timestamp.
TIME_SHIELD_CONSTEXPR ts_t end_of_year(ts_t ts=time_shield::ts())
Get the end-of-year timestamp.
constexpr T get_unix_day_ms(ts_ms_t t_ms=time_shield::ts_ms()) noexcept
Get UNIX day from milliseconds timestamp.
TIME_SHIELD_CONSTEXPR bool is_last_workday_of_month(year_t year, int month, int day) noexcept
Check whether a date is the last workday of its month.
constexpr double sec_to_fhour(T ts) noexcept
Converts a timestamp from seconds to floating-point hours.
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 int count_workdays_in_month(year_t year, int month) noexcept
Count the number of workdays contained within a month.
constexpr ts_ms_t sec_to_ms_impl(T t, std::true_type tag) noexcept
Helper function for converting seconds to milliseconds (floating-point version).
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 T hour24_to_12(T hour) noexcept
Converts a 24-hour format hour to a 12-hour format.
constexpr T1 ms_to_hour(T2 ts) noexcept
Converts a timestamp from milliseconds to hours.
constexpr ts_t start_of_hour(ts_t ts=time_shield::ts()) noexcept
Get the timestamp at the start of the hour.
T to_time_zone(tz_t offset)
Converts an integer to a time zone structure.
TIME_SHIELD_CONSTEXPR bool is_first_workday_of_month(year_t year, int month, int day) noexcept
Check whether a date is the first workday of its month.
constexpr T hour_of_day(ts_t ts=time_shield::ts()) noexcept
Get the hour of the day.
constexpr T get_unix_min(ts_t ts=time_shield::ts())
Get UNIX minute.
constexpr T unix_day_to_timestamp(uday_t unix_day) noexcept
Converts a UNIX day to a timestamp in seconds.
constexpr T1 hour_to_sec(T2 ts) noexcept
Converts a timestamp from hours to seconds.
TIME_SHIELD_CONSTEXPR ts_t start_of_year(ts_t ts) noexcept
Get the start of the year timestamp.
TIME_SHIELD_CONSTEXPR T get_year_ms(ts_ms_t ts_ms=time_shield::ts_ms())
Get the year from the timestamp in milliseconds.
TIME_SHIELD_CONSTEXPR bool is_last_workday_of_month_ms(ts_ms_t ts_ms) noexcept
Check whether a timestamp in milliseconds falls on the last workday of its month.
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.
constexpr ts_t min_to_sec_impl(T t, std::true_type tag) noexcept
Helper function for converting minutes to seconds (floating-point version).
TIME_SHIELD_CONSTEXPR ts_t tm_to_timestamp_ms(const std::tm *timeinfo)
Converts a std::tm structure to a timestamp in milliseconds.
constexpr T sec_of_day_ms(ts_ms_t ts_ms) noexcept
Get the second of the day from milliseconds timestamp.
constexpr double sec_to_fmin(T ts) noexcept
Converts a timestamp from seconds to floating-point minutes.
TIME_SHIELD_CONSTEXPR int first_workday_day(year_t year, int month) noexcept
Compute the calendar day number of the first workday in a month.
constexpr ts_t hour_to_sec_impl(T t, std::true_type tag) noexcept
Helper function for converting hours to seconds (floating-point version).
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 bool is_within_last_workdays_of_month(year_t year, int month, int day, int count) noexcept
Check whether a date is within the last N workdays of its month.
TIME_SHIELD_CONSTEXPR int workday_index_in_month(year_t year, int month, int day) noexcept
Determine the 1-based index of a workday within its month.
constexpr T get_weekday_from_ts_ms(ts_ms_t ts_ms)
Get the weekday from a timestamp in milliseconds.
TIME_SHIELD_CONSTEXPR ts_t dt_to_timestamp(const T &date_time)
Converts a date-time structure to a timestamp.
constexpr fts_t hour_to_fsec(T hr) noexcept
Converts a timestamp from hours to floating-point seconds.
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.
constexpr T1 num_days_in_month(ts_t ts=time_shield::ts()) noexcept
Alias for num_days_in_month_ts function.
constexpr fts_t min_to_fsec(T min) noexcept
Converts a timestamp from minutes to floating-point seconds.
constexpr T1 ms_to_sec(T2 ts_ms) noexcept
Converts a timestamp from milliseconds to seconds.
constexpr fts_t to_ftimestamp(const T &date_time)
Alias for dt_to_ftimestamp.
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.
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.
TIME_SHIELD_CONSTEXPR ts_t to_timestamp(const T &date_time)
Alias for dt_to_timestamp function.
constexpr ts_ms_t ts_ms(year_t year, int month, int day)
Alias for to_timestamp_ms.
constexpr T num_days_in_year_ts(ts_t ts=time_shield::ts())
Get the number of days in the current year.
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.
constexpr T1 min_to_ms(T2 ts) noexcept
Converts a timestamp from minutes to milliseconds.
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 T get_unix_year(ts_t ts) noexcept
Converts a UNIX timestamp to a 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.
constexpr T1 ms_to_min(T2 ts) noexcept
Converts a timestamp from milliseconds to minutes.
constexpr ts_t next_day(ts_t ts, T days=1) noexcept
Calculate the timestamp for a specified number of days in the future.
constexpr T unix_day_to_timestamp_ms(uday_t unix_day) noexcept
Converts a UNIX day to a timestamp in milliseconds.
T1 to_date_time(T2 ts)
Converts a timestamp to a date-time structure.
constexpr T1 sec_to_min(T2 ts) noexcept
Converts a timestamp from seconds to minutes.
TIME_SHIELD_CONSTEXPR ts_t dt_to_timestamp_ms(const T &date_time)
Converts a date-time structure to a timestamp in milliseconds.
constexpr T days(ts_t start, ts_t stop) noexcept
Alias for get_days_difference function.
constexpr T1 sec_to_hour(T2 ts) noexcept
Converts a timestamp from seconds to hours.
constexpr T1 day_of_week_date(T2 year, T3 month, T4 day)
Get the day of the week.
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 end_of_day_from_unix_day(uday_t unix_day) noexcept
Converts a UNIX day to a timestamp representing the end of the day in seconds.
constexpr T1 sec_to_ms(T2 ts) noexcept
Converts a timestamp from seconds to milliseconds.
constexpr ts_ms_t hour_to_ms_impl(T t, std::true_type tag) noexcept
Helper function for converting hours to milliseconds (floating-point version).
constexpr ts_ms_t min_to_ms_impl(T t, std::true_type tag) noexcept
Helper function for converting minutes to milliseconds (floating-point version).
constexpr T start_of_next_day_from_unix_day_ms(uday_t unix_day) noexcept
Converts a UNIX day to a timestamp representing the start of the next day in milliseconds.
constexpr T1 get_weekday_from_date(const T2 &date)
Get the day of the week from a date structure.
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 T year(ts_t ts=time_shield::ts())
Alias for get_year function.
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
Get the weekday from a timestamp.
constexpr fts_t ms_to_fsec(T ts_ms) noexcept
Converts a timestamp from milliseconds to floating-point seconds.
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_year_date_ms(T year)
Get the timestamp in milliseconds of the start of the year.
ts_ms_t fsec_to_ms(fts_t ts) noexcept
Converts a floating-point timestamp from seconds to milliseconds.
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_t to_timestamp_ms(const T &date_time)
Alias for dt_to_timestamp_ms function.
constexpr T1 num_days_in_year(T2 year) noexcept
Get the number of days in a given year.
TIME_SHIELD_CONSTEXPR ts_ms_t start_of_year_ms(ts_ms_t ts_ms=time_shield::ts_ms()) noexcept
Get the start of the year timestamp in milliseconds.
@ FEB
February.
Definition enums.hpp:95
@ SAT
Saturday.
Definition enums.hpp:34
@ THU
Thursday.
Definition enums.hpp:32
bool is_workday(const std::string &str)
Parse an ISO8601 string and check if it falls on a workday using second precision.
int64_t ts_t
Unix timestamp in seconds since 1970‑01‑01T00:00:00Z.
Definition types.hpp:46
int32_t tz_t
Time zone offset in minutes from UTC (e.g., +180 = UTC+3).
Definition types.hpp:58
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:47
int64_t uday_t
Unix day count since 1970‑01‑01 (days since epoch).
Definition types.hpp:42
double fts_t
Floating-point timestamp (fractional seconds since epoch).
Definition types.hpp:49
int64_t year_t
Year as an integer (e.g., 2024).
Definition types.hpp:41
T ns_of_sec() noexcept
Get the nanosecond part of the current second.
T ms_of_sec() noexcept
Get the millisecond part of the current second.
T us_of_sec() noexcept
Get the microsecond part of the current second.
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 bool is_leap_year_ts(ts_t ts)
Checks if the given year is a leap year.
Main namespace for the Time Shield library.
Doxygen-only stubs for alias functions defined via macros.
Header file with time-related utility functions.
Header for time zone structure and related functions.
Header file with time-related validation functions.