ORIGINAL
Loading...
Searching...
No Matches
zeit.h
Go to the documentation of this file.
1#ifndef ORIGINAL_ZEIT_H
2#define ORIGINAL_ZEIT_H
3
4#include "config.h"
5
6#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
7#include <ctime>
8#elif ORIGINAL_COMPILER_MSVC
9#ifndef WIN32_LEAN_AND_MEAN
10#define WIN32_LEAN_AND_MEAN
11#endif
12#include <Windows.h>
13#include <sysinfoapi.h>
14#endif
15
16#include <cmath>
17#include "comparable.h"
18#include "hash.h"
19#include "printable.h"
20#include "error.h"
21#include <iomanip>
22
42namespace original {
49 class time final {
50 public:
53
54 private:
56 static constexpr time_val_type UNIT_FACTOR_BASE = 1;
57
59 static constexpr time_val_type UNIT_FACTOR[] {
60 UNIT_FACTOR_BASE,
61 UNIT_FACTOR_BASE * 1000,
62 UNIT_FACTOR_BASE * 1000 * 1000,
63 UNIT_FACTOR_BASE * 1000 * 1000 * 1000,
64 UNIT_FACTOR_BASE * 1000 * 1000 * 1000 * 60,
65 UNIT_FACTOR_BASE * 1000 * 1000 * 1000 * 60 * 60,
66 UNIT_FACTOR_BASE * 1000 * 1000 * 1000 * 60 * 60 * 24,
67 };
68
69 public:
74 enum class unit {
78 SECOND,
79 MINUTE,
80 HOUR,
81 DAY,
82 };
83
85 static constexpr auto NANOSECOND = unit::NANOSECOND;
87 static constexpr auto MICROSECOND = unit::MICROSECOND;
89 static constexpr auto MILLISECOND = unit::MILLISECOND;
91 static constexpr auto SECOND = unit::SECOND;
93 static constexpr auto MINUTE = unit::MINUTE;
95 static constexpr auto HOUR = unit::HOUR;
97 static constexpr auto DAY = unit::DAY;
98
100 static constexpr time_val_type FACTOR_NANOSECOND = UNIT_FACTOR[static_cast<ul_integer>(NANOSECOND)];
102 static constexpr time_val_type FACTOR_MICROSECOND = UNIT_FACTOR[static_cast<ul_integer>(MICROSECOND)];
104 static constexpr time_val_type FACTOR_MILLISECOND = UNIT_FACTOR[static_cast<ul_integer>(MILLISECOND)];
106 static constexpr time_val_type FACTOR_SECOND = UNIT_FACTOR[static_cast<ul_integer>(SECOND)];
108 static constexpr time_val_type FACTOR_MINUTE = UNIT_FACTOR[static_cast<ul_integer>(MINUTE)];
110 static constexpr time_val_type FACTOR_HOUR = UNIT_FACTOR[static_cast<ul_integer>(HOUR)];
112 static constexpr time_val_type FACTOR_DAY = UNIT_FACTOR[static_cast<ul_integer>(DAY)];
113
115 static constexpr integer DAYS_LEAP_YEAR = 366;
117 static constexpr integer DAYS_COMMON_YEAR = 365;
118
120 static constexpr integer EPOCH_YEAR = 1970;
122 static constexpr integer EPOCH_MONTH = 1;
124 static constexpr integer EPOCH_DAY = 1;
125
127 class point;
129 class UTCTime;
130
141 : public comparable<duration>,
142 public hashable<duration>,
143 public printable {
144 time_val_type nano_seconds_;
145
146 public:
147 friend class point;
148
150 static const duration ZERO;
151
158
159#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
167 explicit duration(const timespec& ts);
168#elif ORIGINAL_COMPILER_MSVC
169 explicit duration(DWORD milliseconds);
170#endif
171
173 duration(const duration& other) = default;
174
176 duration& operator=(const duration& other) = default;
177
182 duration(duration&& other) noexcept;
183
189 duration& operator=(duration&& other) noexcept;
190
197
203 [[nodiscard]] integer compareTo(const duration& other) const override;
204
210
215 std::string className() const override;
216
222 std::string toString(bool enter) const override;
223
224#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
230 explicit operator timespec() const;
231
232 timespec toTimespec() const;
233#elif ORIGINAL_COMPILER_MSVC
234 explicit operator DWORD() const;
235
236 DWORD toDWMilliseconds() const;
237#endif
238
244
251
257
264
271
278
285
292
299
307
313 [[nodiscard]] floating div(const duration& other) const;
314
320 friend duration operator-(const duration& d);
321
328 friend duration operator+(const duration& lhs, const duration& rhs);
329
336 friend duration operator-(const duration& lhs, const duration& rhs);
337
345
353
361
368 friend duration operator/(const duration& lhs, const duration& rhs);
369
375 friend duration abs(const duration& d);
376 };
377
387 : public comparable<point>,
388 public hashable<point>,
389 public printable {
390 duration nano_since_epoch_;
391
392 public:
393 friend class UTCTime;
394
399 static point now();
400
406 explicit point(time_val_type val = 0, unit unit = MILLISECOND);
407
412 explicit point(duration d);
413
414#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
420 explicit point(const timespec& ts);
421#elif ORIGINAL_COMPILER_MSVC
422 explicit point(DWORD milliseconds);
423#endif
424
430 [[nodiscard]] time_val_type value(unit unit = MILLISECOND) const noexcept;
431
437 [[nodiscard]] integer compareTo(const point& other) const override;
438
443 u_integer toHash() const noexcept override;
444
449 std::string className() const override;
450
456 std::string toString(bool enter) const override;
457
458#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
464 explicit operator timespec() const;
465
466 timespec toTimespec() const;
467#elif ORIGINAL_COMPILER_MSVC
468 explicit operator DWORD() const;
469
470 DWORD toDWMilliseconds() const;
471#endif
472
477 point& operator++();
478
485
490 point& operator--();
491
498
504 point& operator+=(const duration& d);
505
511 point& operator-=(const duration& d);
512
519 friend point operator+(const point& p, const duration& d);
520
521 friend point operator+(const duration& d, const point& p);
522
529 friend point operator-(const point& p, const duration& d);
530
537 friend duration operator-(const point& lhs, const point& rhs);
538 };
539
553 : public comparable<UTCTime>,
554 public hashable<UTCTime>,
555 public printable {
556
557 integer year_{};
558 integer month_{};
559 integer day_{};
560 integer hour_{};
561 integer minute_{};
562 integer second_{};
563
568 enum class calendar : integer {
569 YEAR,
570 MONTH,
571 };
572
577 enum class weekdays : integer {
578 SATURDAY,
579 SUNDAY,
580 MONDAY,
581 TUESDAY,
582 WEDNESDAY,
583 THURSDAY,
584 FRIDAY,
585 };
586
588 static constexpr integer DAYS_OF_MONTH[] {
589 31, 28, 31, 30, 31, 30,
590 31, 31, 30, 31, 30, 31
591 };
592
598 static constexpr bool isValidYear(integer year);
599
605 static constexpr bool isValidMonth(integer month);
606
612 static constexpr bool isValidDay(integer day);
613
625
626 public:
627 friend time;
628
630 static constexpr auto SATURDAY = weekdays::SATURDAY;
632 static constexpr auto SUNDAY = weekdays::SUNDAY;
634 static constexpr auto MONDAY = weekdays::MONDAY;
636 static constexpr auto TUESDAY = weekdays::TUESDAY;
638 static constexpr auto WEDNESDAY = weekdays::WEDNESDAY;
640 static constexpr auto THURSDAY = weekdays::THURSDAY;
642 static constexpr auto FRIDAY = weekdays::FRIDAY;
643
645 static constexpr integer DAYS_WEEK = 7;
647 static constexpr integer MONTHS_YEAR = std::size(DAYS_OF_MONTH);
649 static constexpr integer YEARS_CENTURY = 100;
650
652 static const UTCTime EPOCH;
653
658 static UTCTime now();
659
665 static integer localZonedOffset();
666
672 static UTCTime localNow();
673
679 static constexpr bool isLeapYear(integer year);
680
688 static constexpr integer daysOfMonth(integer year, integer month);
689
698 static constexpr weekdays weekday(integer year, integer month, integer day);
699
707 static constexpr bool isValidYMD(integer year, integer month, integer day);
708
716 static constexpr bool isValidHMS(integer hour, integer minute, integer second);
717
728 static constexpr bool isValid(integer year, integer month, integer day,
730
735 [[nodiscard]] bool isLeapYear() const;
736
741 [[nodiscard]] weekdays weekday() const;
742
751 explicit UTCTime();
752
765
782
793 explicit UTCTime(const point& p);
794
796 UTCTime(const UTCTime& other) = default;
797
799 UTCTime& operator=(const UTCTime& other) = default;
800
805 UTCTime(UTCTime&& other) noexcept;
806
812 UTCTime& operator=(UTCTime&& other) noexcept;
813
824 UTCTime date() const;
825
831 integer value(unit unit) const;
832
838 integer value(calendar calendar) const;
839
846 explicit operator original::time::point() const;
847
848 point toPoint() const;
849
855 integer compareTo(const UTCTime& other) const override;
856
862
867 std::string className() const override;
868
874 std::string toString(bool enter) const override;
875
883
891
899
907 };
908
910 static constexpr auto MONTH = UTCTime::calendar::MONTH;
912 static constexpr auto YEAR = UTCTime::calendar::YEAR;
913 };
914
917
918 time::duration nanoseconds(time::time_val_type val = 1);
919
920 time::duration microseconds(time::time_val_type val = 1);
921
922 time::duration milliseconds(time::time_val_type val = 1);
923
925
927
929
931
933
935
937
939
941
943
945
947
949
951
953
955
958
959 time::UTCTime operator+(const time::UTCTime& t, const time::duration& d);
960
961 time::UTCTime operator+(const time::duration& d, const time::UTCTime& t);
962
963 time::UTCTime operator-(const time::UTCTime& t, const time::duration& d);
964
965 time::duration operator-(const time::UTCTime& lhs, const time::UTCTime& rhs);
966
971 namespace literals {
977 inline time::duration operator""_ns(const unsigned long long val) {
978 return time::duration(static_cast<time::time_val_type>(val), time::NANOSECOND);
979 }
980
986 inline time::duration operator""_us(const unsigned long long val) {
987 return time::duration(static_cast<time::time_val_type>(val), time::MICROSECOND);
988 }
989
995 inline time::duration operator""_ms(const unsigned long long val) {
996 return time::duration(static_cast<time::time_val_type>(val), time::MILLISECOND);
997 }
998
1004 inline time::duration operator""_s(const unsigned long long val) {
1005 return time::duration(static_cast<time::time_val_type>(val), time::SECOND);
1006 }
1007
1013 inline time::duration operator""_min(const unsigned long long val) {
1014 return time::duration(static_cast<time::time_val_type>(val), time::MINUTE);
1015 }
1016
1022 inline time::duration operator""_h(const unsigned long long val) {
1023 return time::duration(static_cast<time::time_val_type>(val), time::HOUR);
1024 }
1025
1031 inline time::duration operator""_d(const unsigned long long val) {
1032 return time::duration(static_cast<time::time_val_type>(val), time::DAY);
1033 }
1034
1040 inline time::duration operator""_ns(const long double val) {
1041 return time::duration(std::llround(val * time::FACTOR_NANOSECOND), time::NANOSECOND);
1042 }
1043
1049 inline time::duration operator""_us(const long double val) {
1050 return time::duration(std::llround(val * time::FACTOR_MICROSECOND), time::NANOSECOND);
1051 }
1052
1058 inline time::duration operator""_ms(const long double val) {
1059 return time::duration(std::llround(val * time::FACTOR_MILLISECOND), time::NANOSECOND);
1060 }
1061
1067 inline time::duration operator""_s(const long double val) {
1068 return time::duration(std::llround(val * time::FACTOR_SECOND), time::NANOSECOND);
1069 }
1070
1076 inline time::duration operator""_min(const long double val) {
1077 return time::duration(std::llround(val * time::FACTOR_MINUTE), time::NANOSECOND);
1078 }
1079
1085 inline time::duration operator""_h(const long double val) {
1086 return time::duration(std::llround(val * time::FACTOR_HOUR), time::NANOSECOND);
1087 }
1088
1094 inline time::duration operator""_d(const long double val) {
1095 return time::duration(std::llround(val * time::FACTOR_DAY), time::NANOSECOND);
1096 }
1097 }
1098}
1099
1101 switch (unit) {
1102 case unit::DAY:
1103 this->nano_seconds_ = FACTOR_DAY * val;
1104 break;
1105 case unit::HOUR:
1106 this->nano_seconds_ = FACTOR_HOUR * val;
1107 break;
1108 case unit::MINUTE:
1109 this->nano_seconds_ = FACTOR_MINUTE * val;
1110 break;
1111 case unit::SECOND:
1112 this->nano_seconds_ = FACTOR_SECOND * val;
1113 break;
1114 case unit::MILLISECOND:
1115 this->nano_seconds_ = FACTOR_MILLISECOND * val;
1116 break;
1117 case unit::MICROSECOND:
1118 this->nano_seconds_ = FACTOR_MICROSECOND * val;
1119 break;
1120 case unit::NANOSECOND:
1121 this->nano_seconds_ = FACTOR_NANOSECOND * val;
1122 break;
1123 default:
1124 throw valueError("Invalid time unit specified for duration construction");
1125 }
1126}
1127
1128#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
1130 : nano_seconds_(ts.tv_sec * FACTOR_SECOND + ts.tv_nsec) {}
1131#elif ORIGINAL_COMPILER_MSVC
1132inline original::time::duration::duration(const DWORD milliseconds)
1133 : nano_seconds_(static_cast<time_val_type>(milliseconds) * FACTOR_MILLISECOND) {}
1134#endif
1135
1137 this->operator=(std::move(other));
1138}
1139
1142 if (this == &other)
1143 return *this;
1144
1145 this->nano_seconds_ = other.nano_seconds_;
1146 other.nano_seconds_ = 0;
1147 return *this;
1148}
1149
1152 time_val_type val = this->nano_seconds_;
1153 switch (unit) {
1154 case unit::DAY:
1155 val /= FACTOR_DAY;
1156 break;
1157 case unit::HOUR:
1158 val /= FACTOR_HOUR;
1159 break;
1160 case unit::MINUTE:
1161 val /= FACTOR_MINUTE;
1162 break;
1163 case unit::SECOND:
1164 val /= FACTOR_SECOND;
1165 break;
1166 case unit::MILLISECOND:
1168 break;
1169 case unit::MICROSECOND:
1171 break;
1172 case unit::NANOSECOND:
1174 break;
1175 default:
1176 throw valueError("Invalid time unit specified for duration value conversion");
1177 }
1178 return val;
1179}
1180
1181inline original::integer
1183 if (this->nano_seconds_ == other.nano_seconds_)
1184 return 0;
1185 return this->nano_seconds_ > other.nano_seconds_ ? 1 : -1;
1186}
1187
1192
1193inline std::string original::time::duration::className() const {
1194 return "time::duration";
1195}
1196
1197inline std::string original::time::duration::toString(const bool enter) const {
1198 std::stringstream ss;
1199 ss << "(" << this->className() << " " << this->nano_seconds_ << "ns)";
1200 if (enter)
1201 ss << "\n";
1202 return ss.str();
1203}
1204
1205#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
1206inline original::time::duration::operator timespec() const
1207{
1208 auto nanoseconds = this->value(NANOSECOND);
1209 const auto seconds = nanoseconds / FACTOR_SECOND;
1210 nanoseconds %= FACTOR_SECOND;
1211 return timespec{seconds, static_cast<long>(nanoseconds)}; //NOLINT: The remaining nanosecond value is within the range of type long.
1212}
1213
1214inline timespec original::time::duration::toTimespec() const
1215{
1216 return static_cast<timespec>(*this);
1217}
1218#elif ORIGINAL_COMPILER_MSVC
1219inline original::time::duration::operator DWORD() const
1220{
1221 return static_cast<DWORD>(this->value());
1222}
1223
1224inline DWORD original::time::duration::toDWMilliseconds() const
1225{
1226 return static_cast<DWORD>(*this);
1227}
1228#endif
1229
1232 this->nano_seconds_ += 1;
1233 return *this;
1234}
1235
1238 duration res{*this};
1239 this->nano_seconds_ += 1;
1240 return res;
1241}
1242
1245 this->nano_seconds_ -= 1;
1246 return *this;
1247}
1248
1251 duration res{*this};
1252 this->nano_seconds_ -= 1;
1253 return res;
1254}
1255
1258 this->nano_seconds_ += other.nano_seconds_;
1259 return *this;
1260}
1261
1264 this->nano_seconds_ -= other.nano_seconds_;
1265 return *this;
1266}
1267
1270 this->nano_seconds_ *= factor;
1271 return *this;
1272}
1273
1276 this->nano_seconds_ /= factor;
1277 return *this;
1278}
1279
1282 this->nano_seconds_ /= other.nano_seconds_;
1283 return *this;
1284}
1285
1286inline original::floating
1288 return this->div(duration{factor, unit});
1289}
1290
1291inline original::floating
1293 return static_cast<floating>(this->nano_seconds_) / static_cast<floating>(other.nano_seconds_);
1294}
1295
1297original::nanoseconds(const time::time_val_type val) {
1299}
1300
1302original::microseconds(const time::time_val_type val) {
1303 return time::duration{val, time::MICROSECOND};
1304}
1305
1307original::milliseconds(const time::time_val_type val) {
1308 return time::duration{val, time::MILLISECOND};
1309}
1310
1312original::seconds(const time::time_val_type val) {
1313 return time::duration{val, time::SECOND};
1314}
1315
1317original::minutes(const time::time_val_type val) {
1318 return time::duration{val, time::MINUTE};
1319}
1320
1322original::hours(const time::time_val_type val) {
1323 return time::duration{val, time::HOUR};
1324}
1325
1327original::days(const time::time_val_type val) {
1328 return time::duration{val, time::DAY};
1329}
1330
1334 res.nano_seconds_ = -res.nano_seconds_;
1335 return res;
1336}
1337
1341 d += rhs;
1342 return d;
1343}
1344
1348 d -= rhs;
1349 return d;
1350}
1351
1355 res *= factor;
1356 return res;
1357}
1358
1363
1367 res /= factor;
1368 return res;
1369}
1370
1374 d /= rhs;
1375 return d;
1376}
1377
1380 time::time_val_type val = d.nano_seconds_;
1381 val = val < 0 ? -val : val;
1383}
1384
1387#if ORIGINAL_COMPILER_GCC || (ORIGINAL_COMPILER_CLANG && ORIGINAL_PLATFORM_LINUX)
1388 timespec ts{};
1390 return point{ts};
1391#elif ORIGINAL_PLATFORM_APPLE
1392 struct timeval tv;
1393 gettimeofday(&tv, nullptr);
1394 time_val_type ns = tv.tv_sec * FACTOR_SECOND + tv.tv_usec * FACTOR_MICROSECOND;
1395 return point(ns, NANOSECOND);
1396#elif ORIGINAL_COMPILER_MSVC
1399
1401 uli.LowPart = file_time.dwLowDateTime;
1402 uli.HighPart = file_time.dwHighDateTime;
1403
1404 constexpr time_val_type WINDOWS_TO_UNIX_EPOCH = 11644473600LL * FACTOR_SECOND;
1405
1406 const time_val_type nanoseconds = uli.QuadPart * 100 - WINDOWS_TO_UNIX_EPOCH;
1407
1408 return point{nanoseconds, NANOSECOND};
1409#endif
1410 return point{};
1411}
1412
1414 : nano_since_epoch_(val, unit) {}
1415
1417 : nano_since_epoch_(std::move(d)) {}
1418
1419#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
1421 : nano_since_epoch_(ts) {}
1422#elif ORIGINAL_COMPILER_MSVC
1423inline original::time::point::point(const DWORD milliseconds)
1424 : nano_since_epoch_(milliseconds) {}
1425#endif
1426
1429 return this->nano_since_epoch_.value(unit);
1430}
1431
1432inline original::integer
1434 return this->nano_since_epoch_.compareTo(other.nano_since_epoch_);
1435}
1436
1439 return this->nano_since_epoch_.toHash();
1440}
1441
1442inline std::string original::time::point::className() const {
1443 return "time::point";
1444}
1445
1446inline std::string
1448 std::stringstream ss;
1449 ss << "(" << this->className() << " " << this->nano_since_epoch_.nano_seconds_ << ")";
1450 if (enter)
1451 ss << "\n";
1452 return ss.str();
1453}
1454
1455#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
1456inline original::time::point::operator timespec() const
1457{
1458 return static_cast<timespec>(this->nano_since_epoch_);
1459}
1460
1461inline timespec original::time::point::toTimespec() const
1462{
1463 return static_cast<timespec>(*this);
1464}
1465#elif ORIGINAL_COMPILER_MSVC
1466inline original::time::point::operator DWORD() const
1467{
1468 return static_cast<DWORD>(this->nano_since_epoch_);
1469}
1470
1471inline DWORD original::time::point::toDWMilliseconds() const
1472{
1473 return static_cast<DWORD>(*this);
1474}
1475#endif
1476
1479 ++this->nano_since_epoch_;
1480 return *this;
1481}
1482
1485 point res{*this};
1486 ++this->nano_since_epoch_;
1487 return res;
1488}
1489
1492 --this->nano_since_epoch_;
1493 return *this;
1494}
1495
1498 point res{*this};
1499 --this->nano_since_epoch_;
1500 return res;
1501}
1502
1505 this->nano_since_epoch_ += d;
1506 return *this;
1507}
1508
1511 this->nano_since_epoch_ -= d;
1512 return *this;
1513}
1514
1517 time::point res{p};
1518 res -= d;
1519 return res;
1520}
1521
1524 return lhs.nano_since_epoch_ - rhs.nano_since_epoch_;
1525}
1526
1529 time::point res{p};
1530 res += d;
1531 return res;
1532}
1533
1535original::operator+(const time::duration &d, const time::point &p) {
1536 return p + d;
1537}
1538
1539constexpr bool
1540original::time::UTCTime::isValidYear(const integer year) {
1541 return 0 <= year;
1542}
1543
1544constexpr bool
1545original::time::UTCTime::isValidMonth(const integer month) {
1546 return 1 <= month && month <= 12;
1547}
1548
1549constexpr bool
1550original::time::UTCTime::isValidDay(const integer day) {
1551 return 1 <= day && day <= 31;
1552}
1553
1554inline void original::time::UTCTime::set(const integer year, const integer month, const integer day,
1555 const integer hour, const integer minute, const integer second) {
1556 this->year_ = year;
1557 this->month_ = month;
1558 this->day_ = day;
1559 this->hour_ = hour;
1560 this->minute_ = minute;
1561 this->second_ = second;
1562}
1563
1568
1569inline original::integer
1572#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
1573 integer t = std::time(nullptr);
1574 tm local_tm{};
1575#if ORIGINAL_PLATFORM_WINDOWS
1577#else
1579#endif
1580
1581 tm utc_tm{};
1582#if ORIGINAL_PLATFORM_WINDOWS
1583 gmtime_s(&utc_tm, &t);
1584#else
1585 gmtime_r(&t, &utc_tm);
1586#endif
1587
1589#else
1592 if (result != TIME_ZONE_ID_INVALID) {
1594 if (result == TIME_ZONE_ID_DAYLIGHT) {
1595 offset_seconds -= tz_info.DaylightBias * (FACTOR_MINUTE / FACTOR_SECOND);
1596 }
1597 }
1598#endif
1600}
1601
1604 return now() + duration{localZonedOffset(), HOUR};
1605}
1606
1607constexpr bool
1609 if (!isValidYear(year))
1610 return false;
1611 return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
1612}
1613
1614constexpr original::integer
1616 if (!isValidYear(year) || !isValidMonth(month))
1617 throw valueError();
1618
1619 if (month == 2 && isLeapYear(year)){
1620 return DAYS_OF_MONTH[month - 1] + 1;
1621 }
1622 return DAYS_OF_MONTH[month - 1];
1623}
1624
1625constexpr original::time::UTCTime::weekdays
1627 if (!isValidYMD(year, month, day))
1628 throw valueError("Invalid date for weekday calculation: " +
1629 formatString(year) + "-" + formatString(month) + "-" + formatString(day));
1630
1632 if (month == 1 || month == 2){
1633 corrected_year = year - 1;
1634 corrected_month = MONTHS_YEAR + month;
1635 } else {
1638 }
1639 const integer century = corrected_year / YEARS_CENTURY;
1640 const integer years_in_century = corrected_year % YEARS_CENTURY;
1641
1642 return static_cast<weekdays>((
1643 day +
1644 13 * (corrected_month + 1) / 5 +
1646 years_in_century / 4 +
1647 century / 4 +
1648 5 * century
1649 ) % DAYS_WEEK);
1650}
1651
1652constexpr bool
1654 if (!isValidYear(year) || !isValidMonth(month) || !isValidDay(day))
1655 return false;
1656
1657 return day <= daysOfMonth(year, month);
1658}
1659
1660constexpr bool
1662 return 0 <= hour && hour <= 23 &&
1663 0 <= minute && minute <= 59 &&
1664 0 <= second && second <= 59;
1665}
1666
1667constexpr bool
1669 const integer hour, const integer minute, const integer second) {
1670 return isValidYMD(year, month, day) && isValidHMS(hour, minute, second);
1671}
1672
1674 return isLeapYear(this->year_);
1675}
1676
1677inline original::time::UTCTime::weekdays
1679 return weekday(this->year_, this->month_, this->day_);
1680}
1681
1684
1686 : UTCTime(year, month, day, 0, 0, 0) {}
1687
1689 const integer hour, const integer minute, const integer second) {
1690 if (!isValid(year, month, day, hour, minute, second))
1691 throw valueError("Invalid UTC time parameters: " +
1692 formatString(year) + "-" + formatString(month) + "-" + formatString(day) + " " +
1693 formatString(hour) + ":" + formatString(minute) + ":" + formatString(second));
1694
1695 this->set(year, month, day, hour, minute, second);
1696}
1697
1699 const auto nano_seconds = p.value(NANOSECOND);
1700
1702
1704 second %= (FACTOR_MINUTE / FACTOR_SECOND);
1705
1708
1711
1713 while (true){
1715 if (day < days_in_year){
1716 break;
1717 }
1718
1719 day -= days_in_year;
1720 year += 1;
1721 }
1722
1723 integer month = 1;
1724 while (true){
1725 const integer dim = daysOfMonth(year, month);
1726 if (day < dim){
1727 break;
1728 }
1729
1730 day -= dim;
1731 month += 1;
1732 }
1733
1734 day += 1;
1735
1736 this->set(year, month, day, hour, minute, second);
1737}
1738
1740 this->operator=(std::move(other));
1741}
1742
1745 if (this == &other)
1746 return *this;
1747
1748 this->set(other.year_, other.month_, other.day_,
1749 other.hour_, other.minute_, other.second_);
1750 other.set(EPOCH_YEAR, EPOCH_MONTH, EPOCH_DAY, 0, 0, 0);
1751 return *this;
1752}
1753
1755{
1756 return UTCTime{this->year_, this->month_, this->day_};
1757}
1758
1759inline original::integer
1761 switch (unit) {
1762 case SECOND:
1763 return this->second_;
1764 case MINUTE:
1765 return this->minute_;
1766 case HOUR:
1767 return this->hour_;
1768 case DAY:
1769 return this->day_;
1770 default:
1771 throw valueError("Invalid time unit for UTCTime value access");
1772 }
1773}
1774
1775inline original::integer
1776original::time::UTCTime::value(const calendar calendar) const {
1777 switch (calendar) {
1778 case MONTH:
1779 return this->month_;
1780 case YEAR:
1781 return this->year_;
1782 default:
1783 throw valueError("Invalid calendar component for UTCTime value access");
1784 }
1785}
1786
1787inline original::time::UTCTime::operator original::time::point() const {
1789
1790 for (integer year = EPOCH_YEAR; year < this->year_; ++year) {
1792 }
1793
1794 for (integer month = 1; month < this->month_; ++month) {
1795 total_days += daysOfMonth(this->year_, month);
1796 }
1797
1798 total_days += this->day_ - 1;
1799
1801 total_seconds += this->hour_ * (FACTOR_HOUR / FACTOR_SECOND);
1802 total_seconds += this->minute_ * (FACTOR_MINUTE / FACTOR_SECOND);
1803 total_seconds += this->second_;
1804
1805 return point{total_seconds, SECOND};
1806}
1807
1808inline original::time::point original::time::UTCTime::toPoint() const
1809{
1810 return static_cast<point>(*this);
1811}
1812
1813inline original::integer
1815 if (this->year_ != other.year_)
1816 return this->year_ > other.year_ ? 1 : -1;
1817 if (this->month_ != other.month_)
1818 return this->month_ > other.month_ ? 1 : -1;
1819 if (this->day_ != other.day_)
1820 return this->day_ > other.day_ ? 1 : -1;
1821 if (this->hour_ != other.hour_)
1822 return this->hour_ > other.hour_ ? 1 : -1;
1823 if (this->minute_ != other.minute_)
1824 return this->minute_ > other.minute_ ? 1 : -1;
1825 if (this->second_ != other.second_)
1826 return this->second_ > other.second_ ? 1 : -1;
1827 return 0;
1828}
1829
1832 u_integer seed = 0;
1833 hash<UTCTime>::hashCombine(seed, this->year_, this->month_, this->day_,
1834 this-> hour_, this->minute_, this->second_);
1835 return seed;
1836}
1837
1838inline std::string original::time::UTCTime::className() const {
1839 return "time::UTCTime";
1840}
1841
1842inline std::string original::time::UTCTime::toString(const bool enter) const {
1843 std::stringstream ss;
1844 ss << "(" << this->className() << " "
1845 << this->year_ << "-"
1846 << std::setw(2) << std::setfill('0') << this->month_ << "-"
1847 << std::setw(2) << std::setfill('0') << this->day_ << " "
1848 << std::setw(2) << std::setfill('0') << this->hour_ << ":"
1849 << std::setw(2) << std::setfill('0') << this->minute_ << ":"
1850 << std::setw(2) << std::setfill('0') << this->second_ << ")";
1851 if (enter)
1852 ss << "\n";
1853 return ss.str();
1854}
1855
1858 return time::UTCTime{static_cast<time::point>(t) - d};
1859}
1860
1863 return static_cast<time::point>(lhs) - static_cast<time::point>(rhs);
1864}
1865
1868 return time::UTCTime{static_cast<time::point>(t) + d};
1869}
1870
1873 return t + d;
1874}
1875
1876#endif //ORIGINAL_ZEIT_H
integer compareTo(const autoPtr &other) const override
Compare reference counters.
Definition autoPtr.h:714
u_integer toHash() const noexcept override
Compute hash value for the pointer.
Definition autoPtr.h:735
Base class for comparable objects.
Definition comparable.h:35
static u_integer hashFunc(const T &t) noexcept
Default hash function fallback.
static void hashCombine(u_integer &seed, const T &value) noexcept
Combines a hash value with another value's hash.
Definition hash.h:275
Forward declaration of hashable interface template.
Definition hash.h:220
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Base class providing polymorphic string conversion capabilities.
Definition printable.h:39
Abstract base class for unique element containers.
Definition set.h:44
Represents a UTC calendar date and time.
Definition zeit.h:555
static UTCTime localNow()
Returns the current local time as UTCTime.
Definition zeit.h:1603
static constexpr bool isValidYMD(integer year, integer month, integer day)
Checks if year-month-day is valid.
Definition zeit.h:1653
static integer localZonedOffset()
Returns the system's local timezone offset in hours from UTC.
Definition zeit.h:1570
std::string toString(bool enter) const override
Converts UTCTime to string representation (YYYY-MM-DD HH:MM:SS)
Definition zeit.h:1842
static constexpr auto FRIDAY
Constant for Friday.
Definition zeit.h:642
static constexpr bool isValidHMS(integer hour, integer minute, integer second)
Checks if hour-minute-second is valid.
Definition zeit.h:1661
static constexpr auto SATURDAY
Constant for Saturday.
Definition zeit.h:630
static constexpr integer YEARS_CENTURY
Years in a century.
Definition zeit.h:649
static constexpr integer MONTHS_YEAR
Months in a year.
Definition zeit.h:647
friend UTCTime operator+(const UTCTime &t, const duration &d)
Adds duration to UTCTime.
bool isLeapYear() const
Checks if this year is a leap year.
Definition zeit.h:1673
static constexpr integer daysOfMonth(integer year, integer month)
Gets days in specified month.
Definition zeit.h:1615
static constexpr auto MONDAY
Constant for Monday.
Definition zeit.h:634
integer compareTo(const UTCTime &other) const override
Compares this UTCTime to another.
Definition zeit.h:1814
static constexpr auto TUESDAY
Constant for Tuesday.
Definition zeit.h:636
static constexpr integer DAYS_WEEK
Days in a week.
Definition zeit.h:645
static constexpr auto WEDNESDAY
Constant for Wednesday.
Definition zeit.h:638
UTCTime & operator=(const UTCTime &other)=default
Default copy assignment.
static const UTCTime EPOCH
Epoch time constant (1970-01-01 00:00:00)
Definition zeit.h:652
weekdays weekday() const
Gets weekday for this date.
Definition zeit.h:1678
UTCTime(const UTCTime &other)=default
Default copy constructor.
UTCTime date() const
Returns a new UTCTime object containing only the calendar date.
Definition zeit.h:1754
std::string className() const override
Gets the class name.
Definition zeit.h:1838
u_integer toHash() const noexcept override
Computes hash value for this UTCTime.
Definition zeit.h:1831
static constexpr auto THURSDAY
Constant for Thursday.
Definition zeit.h:640
friend UTCTime operator-(const UTCTime &t, const duration &d)
Subtracts duration from UTCTime.
integer value(unit unit) const
Gets time component value.
Definition zeit.h:1760
static constexpr bool isValid(integer year, integer month, integer day, integer hour, integer minute, integer second)
Checks if full date-time is valid.
Definition zeit.h:1668
UTCTime()
Constructs a UTCTime object representing the epoch (1970-01-01 00:00:00 UTC)
Definition zeit.h:1682
static constexpr auto SUNDAY
Constant for Sunday.
Definition zeit.h:632
static UTCTime now()
Gets current UTC time.
Definition zeit.h:1565
Represents a time duration with nanosecond precision.
Definition zeit.h:143
duration & operator*=(time_val_type factor)
Multiplies duration by a factor.
Definition zeit.h:1269
duration(const duration &other)=default
Default copy constructor.
duration & operator+=(const duration &other)
Adds another duration to this one.
Definition zeit.h:1257
u_integer toHash() const noexcept override
Computes hash value for this duration.
Definition zeit.h:1189
friend duration operator/(const duration &lhs, const duration &rhs)
Division operator (duration / duration)
time_val_type value(unit unit=MILLISECOND) const
Gets the duration value in specified units.
Definition zeit.h:1151
std::string className() const override
Gets the class name.
Definition zeit.h:1193
duration(time_val_type val=0, unit unit=MILLISECOND)
Constructs a duration with given value and unit.
Definition zeit.h:1100
floating div(time_val_type factor, unit unit=MILLISECOND) const
Floating-point division by a factor.
Definition zeit.h:1287
duration & operator++()
Prefix increment (adds 1 nanosecond)
Definition zeit.h:1231
std::string toString(bool enter) const override
Converts duration to string representation.
Definition zeit.h:1197
friend duration operator-(const duration &d)
Negation operator.
friend duration operator*(const duration &d, time_val_type factor)
Multiplication operator (duration * factor)
integer compareTo(const duration &other) const override
Compares this duration to another.
Definition zeit.h:1182
static const duration ZERO
Zero duration constant.
Definition zeit.h:150
friend duration operator*(time_val_type factor, const duration &d)
Multiplication operator (factor * duration)
friend duration operator+(const duration &lhs, const duration &rhs)
Addition operator.
friend duration operator/(const duration &d, time_val_type factor)
Division operator (duration / factor)
friend duration abs(const duration &d)
Absolute value of duration.
duration & operator/=(time_val_type factor)
Divides duration by a factor.
Definition zeit.h:1275
duration & operator-=(const duration &other)
Subtracts another duration from this one.
Definition zeit.h:1263
duration & operator--()
Prefix decrement (subtracts 1 nanosecond)
Definition zeit.h:1244
duration & operator=(const duration &other)=default
Default copy assignment.
friend duration operator-(const duration &lhs, const duration &rhs)
Subtraction operator.
Represents a point in time with nanosecond precision.
Definition zeit.h:389
static point now()
Gets current time point.
Definition zeit.h:1386
time_val_type value(unit unit=MILLISECOND) const noexcept
Gets time value in specified units.
Definition zeit.h:1428
std::string className() const override
Gets the class name.
Definition zeit.h:1442
friend point operator-(const point &p, const duration &d)
Subtracts duration from time point.
point & operator--()
Prefix decrement (subtracts 1 nanosecond)
Definition zeit.h:1491
point & operator++()
Prefix increment (adds 1 nanosecond)
Definition zeit.h:1478
point(time_val_type val=0, unit unit=MILLISECOND)
Constructs time point from value and unit.
Definition zeit.h:1413
point & operator-=(const duration &d)
Subtracts duration from time point.
Definition zeit.h:1510
std::string toString(bool enter) const override
Converts time point to string representation.
Definition zeit.h:1447
friend point operator+(const point &p, const duration &d)
Adds duration to time point.
point & operator+=(const duration &d)
Adds duration to time point.
Definition zeit.h:1504
u_integer toHash() const noexcept override
Computes hash value for this time point.
Definition zeit.h:1438
integer compareTo(const point &other) const override
Compares this time point to another.
Definition zeit.h:1433
friend duration operator-(const point &lhs, const point &rhs)
Computes duration between two time points.
Namespace-like class containing time-related utilities.
Definition zeit.h:49
static constexpr time_val_type FACTOR_MILLISECOND
Conversion factor for milliseconds.
Definition zeit.h:104
static constexpr auto NANOSECOND
Constant for nanosecond unit.
Definition zeit.h:85
static constexpr integer EPOCH_DAY
Epoch day (Unix epoch)
Definition zeit.h:124
static constexpr auto DAY
Constant for day unit.
Definition zeit.h:97
static constexpr auto HOUR
Constant for hour unit.
Definition zeit.h:95
static constexpr auto YEAR
Constant for year calendar component.
Definition zeit.h:912
static constexpr integer EPOCH_MONTH
Epoch month (Unix epoch)
Definition zeit.h:122
static constexpr auto MILLISECOND
Constant for millisecond unit.
Definition zeit.h:89
static constexpr auto MINUTE
Constant for minute unit.
Definition zeit.h:93
static constexpr time_val_type FACTOR_NANOSECOND
Conversion factor for nanoseconds.
Definition zeit.h:100
unit
Time units supported by the library.
Definition zeit.h:74
@ MILLISECOND
Milliseconds (1e-3 seconds)
@ MINUTE
Minutes (60 seconds)
@ MICROSECOND
Microseconds (1e-6 seconds)
@ DAY
Days (86400 seconds)
@ HOUR
Hours (3600 seconds)
@ NANOSECOND
Nanoseconds (1e-9 seconds)
static constexpr auto SECOND
Constant for second unit.
Definition zeit.h:91
static constexpr time_val_type FACTOR_DAY
Conversion factor for days.
Definition zeit.h:112
static constexpr integer DAYS_COMMON_YEAR
Days in a common year.
Definition zeit.h:117
static constexpr auto MICROSECOND
Constant for microsecond unit.
Definition zeit.h:87
static constexpr time_val_type FACTOR_MINUTE
Conversion factor for minutes.
Definition zeit.h:108
integer time_val_type
Type used for storing time values.
Definition zeit.h:52
static constexpr integer DAYS_LEAP_YEAR
Days in a leap year.
Definition zeit.h:115
static constexpr time_val_type FACTOR_SECOND
Conversion factor for seconds.
Definition zeit.h:106
static constexpr time_val_type FACTOR_HOUR
Conversion factor for hours.
Definition zeit.h:110
static constexpr integer EPOCH_YEAR
Epoch year (Unix epoch)
Definition zeit.h:120
static constexpr time_val_type FACTOR_MICROSECOND
Conversion factor for microseconds.
Definition zeit.h:102
static constexpr auto MONTH
Constant for month calendar component.
Definition zeit.h:910
Exception for invalid parameter values.
Definition error.h:219
Interface for objects that can be compared.
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
Provides a generic hashing utility and interface for hashable types.
User-defined literals for time durations.
Main namespace for the project Original.
Definition algorithms.h:21
auto operator+(const iterator< T > &it, integer steps) -> iterator< T > *
Adds a number of steps to the iterator's current position and returns a new iterator.
auto operator-(const iterator< T > &it, integer steps) -> iterator< T > *
Subtracts a number of steps from the iterator's current position and returns a new iterator.
TYPE abs(TYPE a)
Returns the absolute value of a given number.
time::duration operator*(const time::duration &d, time::time_val_type factor)
Definition zeit.h:1353
time::duration operator/(const time::duration &d, time::time_val_type factor)
Definition zeit.h:1365
Standard namespace extensions for original::alternative.
Definition allocator.h:351
Interface for polymorphic string formatting and output.