Time Shield Library
C++ library for working with time
Loading...
Searching...
No Matches
ole_automation_conversions.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2#pragma once
3#ifndef _TIME_SHIELD_OLE_AUTOMATION_CONVERSIONS_HPP_INCLUDED
4#define _TIME_SHIELD_OLE_AUTOMATION_CONVERSIONS_HPP_INCLUDED
5
20
21#include "config.hpp"
22#include "types.hpp"
23#include "constants.hpp"
25
26#include <cstdint>
27#include <limits>
28
29namespace time_shield {
30
31 namespace detail {
32
33 TIME_SHIELD_CONSTEXPR inline bool oadate_can_cast_to_i64(oadate_t value) noexcept {
34 return value >= static_cast<oadate_t>((std::numeric_limits<int64_t>::min)())
35 && value <= static_cast<oadate_t>((std::numeric_limits<int64_t>::max)());
36 }
37
38 TIME_SHIELD_CONSTEXPR inline oadate_t oadate_abs(oadate_t value) noexcept {
39 return value < 0 ? -value : value;
40 }
41
42 TIME_SHIELD_CONSTEXPR inline oadate_t oadate_trunc_toward_zero(oadate_t value) noexcept {
43 if (!oadate_can_cast_to_i64(value)) {
44 return value;
45 }
46 return static_cast<oadate_t>(static_cast<int64_t>(value));
47 }
48
49 TIME_SHIELD_CONSTEXPR inline oadate_t oadate_floor_value(oadate_t value) noexcept {
50 const oadate_t truncated = oadate_trunc_toward_zero(value);
51 if (truncated == value) {
52 return truncated;
53 }
54 if (value < 0) {
55 return truncated - static_cast<oadate_t>(1.0);
56 }
57 return truncated;
58 }
59
60 TIME_SHIELD_CONSTEXPR inline bool oadate_has_fraction(oadate_t value) noexcept {
61 if (!oadate_can_cast_to_i64(value)) {
62 return false;
63 }
64 return oadate_trunc_toward_zero(value) != value;
65 }
66
67 TIME_SHIELD_CONSTEXPR inline oadate_t linear_days_to_oadate(oadate_t linear_days) noexcept {
68 if (linear_days < 0 && oadate_has_fraction(linear_days)) {
69 const oadate_t whole_days = oadate_floor_value(linear_days);
70 const oadate_t fraction = linear_days - whole_days;
71 return whole_days - fraction;
72 }
73 return linear_days;
74 }
75
76 TIME_SHIELD_CONSTEXPR inline oadate_t oadate_to_linear_days(oadate_t oa) noexcept {
77 if (oa < 0 && oadate_has_fraction(oa)) {
78 const oadate_t whole_days = oadate_trunc_toward_zero(oa);
79 const oadate_t fraction = oadate_abs(oa - whole_days);
80 return whole_days + fraction;
81 }
82 return oa;
83 }
84
85 } // namespace detail
86
90 TIME_SHIELD_CONSTEXPR inline oadate_t ts_to_oadate(ts_t ts) noexcept {
91 const oadate_t linear_days = static_cast<oadate_t>(OLE_EPOCH)
92 + static_cast<oadate_t>(ts) / static_cast<oadate_t>(SEC_PER_DAY);
93 return detail::linear_days_to_oadate(linear_days);
94 }
95
99 TIME_SHIELD_CONSTEXPR inline oadate_t fts_to_oadate(fts_t ts) noexcept {
100 const oadate_t linear_days = static_cast<oadate_t>(OLE_EPOCH)
101 + static_cast<oadate_t>(ts) / static_cast<oadate_t>(SEC_PER_DAY);
102 return detail::linear_days_to_oadate(linear_days);
103 }
104
108 TIME_SHIELD_CONSTEXPR inline oadate_t ts_ms_to_oadate(ts_ms_t ts_ms) noexcept {
109 const oadate_t linear_days = static_cast<oadate_t>(OLE_EPOCH)
110 + static_cast<oadate_t>(ts_ms) / static_cast<oadate_t>(MS_PER_DAY);
111 return detail::linear_days_to_oadate(linear_days);
112 }
113
117 TIME_SHIELD_CONSTEXPR inline ts_t oadate_to_ts(oadate_t oa) noexcept {
118 const oadate_t linear_days = detail::oadate_to_linear_days(oa);
119 const oadate_t seconds = (linear_days - static_cast<oadate_t>(OLE_EPOCH))
120 * static_cast<oadate_t>(SEC_PER_DAY);
121 return static_cast<ts_t>(seconds);
122 }
123
127 TIME_SHIELD_CONSTEXPR inline fts_t oadate_to_fts(oadate_t oa) noexcept {
128 const oadate_t linear_days = detail::oadate_to_linear_days(oa);
129 return static_cast<fts_t>((linear_days - static_cast<oadate_t>(OLE_EPOCH))
130 * static_cast<oadate_t>(SEC_PER_DAY));
131 }
132
136 TIME_SHIELD_CONSTEXPR inline ts_ms_t oadate_to_ts_ms(oadate_t oa) noexcept {
137 const oadate_t linear_days = detail::oadate_to_linear_days(oa);
138 const oadate_t ms = (linear_days - static_cast<oadate_t>(OLE_EPOCH))
139 * static_cast<oadate_t>(MS_PER_DAY);
140 return static_cast<ts_ms_t>(ms);
141 }
142
148 template<class T1, class T2, class T3>
149 TIME_SHIELD_CONSTEXPR inline oadate_t to_oadate(
150 T1 year, T2 month, T2 day,
151 T2 hour = 0, T2 min = 0, T2 sec = 0, T3 ms = 0) noexcept {
152 // Use existing conversion to floating timestamp (seconds).
153 const fts_t fts = to_ftimestamp(year, month, day, hour, min, sec, ms);
154 return fts_to_oadate(fts);
155 }
156
157} // namespace time_shield
158
159#endif // _TIME_SHIELD_OLE_AUTOMATION_CONVERSIONS_HPP_INCLUDED
Configuration macros for the library.
Header file with time-related constants.
Conversions involving DateTimeStruct and day boundary helpers.
constexpr int64_t OLE_EPOCH
OLE automation date since UNIX epoch.
constexpr int64_t MS_PER_DAY
Milliseconds per day.
Definition constants.hpp:97
constexpr int64_t SEC_PER_DAY
Seconds per day.
TIME_SHIELD_CONSTEXPR ts_t ts(year_t year, int month, int day)
Alias for to_timestamp.
TIME_SHIELD_CONSTEXPR ts_ms_t ts_ms(year_t year, int month, int day)
Alias for to_timestamp_ms.
TIME_SHIELD_CONSTEXPR T year(ts_t ts=time_shield::ts())
Alias for year_of function.
TIME_SHIELD_CONSTEXPR fts_t fts(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0)
Alias for to_ftimestamp.
TIME_SHIELD_CONSTEXPR fts_t to_ftimestamp(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0)
Converts a date and time to a floating-point timestamp.
int64_t ts_t
Unix timestamp in seconds since 1970‑01‑01T00:00:00Z.
Definition types.hpp:49
int64_t ts_ms_t
Unix timestamp in milliseconds since epoch.
Definition types.hpp:50
double fts_t
Floating-point timestamp (fractional seconds since epoch).
Definition types.hpp:52
double oadate_t
OLE Automation date (days since 1899‑12‑30, as double).
Definition types.hpp:55
TIME_SHIELD_CONSTEXPR oadate_t oadate_to_linear_days(oadate_t oa) noexcept
TIME_SHIELD_CONSTEXPR oadate_t linear_days_to_oadate(oadate_t linear_days) noexcept
TIME_SHIELD_CONSTEXPR oadate_t oadate_trunc_toward_zero(oadate_t value) noexcept
TIME_SHIELD_CONSTEXPR oadate_t oadate_floor_value(oadate_t value) noexcept
TIME_SHIELD_CONSTEXPR oadate_t oadate_abs(oadate_t value) noexcept
TIME_SHIELD_CONSTEXPR bool oadate_can_cast_to_i64(oadate_t value) noexcept
TIME_SHIELD_CONSTEXPR bool oadate_has_fraction(oadate_t value) noexcept
Main namespace for the Time Shield library.
TIME_SHIELD_CONSTEXPR oadate_t ts_ms_to_oadate(ts_ms_t ts_ms) noexcept
Convert Unix timestamp (milliseconds) to OA date.
TIME_SHIELD_CONSTEXPR oadate_t ts_to_oadate(ts_t ts) noexcept
Convert Unix timestamp (seconds) to OA date.
TIME_SHIELD_CONSTEXPR ts_t oadate_to_ts(oadate_t oa) noexcept
Convert OA date to Unix timestamp (seconds).
TIME_SHIELD_CONSTEXPR oadate_t to_oadate(T1 year, T2 month, T2 day, T2 hour=0, T2 min=0, T2 sec=0, T3 ms=0) noexcept
Build OA date from calendar components (Gregorian).
TIME_SHIELD_CONSTEXPR fts_t oadate_to_fts(oadate_t oa) noexcept
Convert OA date to Unix timestamp (floating seconds).
TIME_SHIELD_CONSTEXPR ts_ms_t oadate_to_ts_ms(oadate_t oa) noexcept
Convert OA date to Unix timestamp (milliseconds).
TIME_SHIELD_CONSTEXPR oadate_t fts_to_oadate(fts_t ts) noexcept
Convert Unix timestamp (floating seconds) to OA date.
Type definitions for time-related units and formats.