OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
DateTime.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2//
3// Copyright 2026 Caleb Buahin
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
46
47#ifndef OPENSWMM_ENGINE_DATETIME_HPP
48#define OPENSWMM_ENGINE_DATETIME_HPP
49
50#include <cmath>
51
52namespace openswmm {
53namespace datetime {
54
55// ============================================================================
56// Constants — matching legacy datetime.c exactly
57// ============================================================================
58
59static constexpr int DateDelta = 693594;
60static constexpr double SecsPerDay = 86400.0;
61static constexpr double OneSecond = 1.1574074e-5;
62
63// ============================================================================
64// Date/time type — same as legacy DateTime (double)
65// ============================================================================
66
67using DateTime = double;
68
69// ============================================================================
70// Core functions — numerically identical to legacy datetime.c
71// ============================================================================
72
76inline void divMod(int n, int d, int* result, int* remainder) {
77 if (d == 0) { *result = 0; *remainder = 0; }
78 else { *result = n / d; *remainder = n - d * (*result); }
79}
80
84inline bool isLeapYear(int year) {
85 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
86}
87
92inline DateTime encodeDate(int year, int month, int day) {
93 static constexpr int DaysPerMonth[2][12] = {
94 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
95 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
96 int i = isLeapYear(year) ? 1 : 0;
97 if (year >= 1 && year <= 9999 && month >= 1 && month <= 12
98 && day >= 1 && day <= DaysPerMonth[i][month - 1]) {
99 for (int j = 0; j < month - 1; ++j) day += DaysPerMonth[i][j];
100 int y = year - 1;
101 return y * 365 + y / 4 - y / 100 + y / 400 + day - DateDelta;
102 }
103 return -DateDelta;
104}
105
110inline DateTime encodeTime(int hour, int minute, int second) {
111 if (hour >= 0 && minute >= 0 && second >= 0) {
112 int s = hour * 3600 + minute * 60 + second;
113 return static_cast<double>(s) / SecsPerDay;
114 }
115 return 0.0;
116}
117
122inline void decodeDate(DateTime date, int& year, int& month, int& day) {
123 static constexpr int DaysPerMonth[2][12] = {
124 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
125 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
126 constexpr int D1 = 365, D4 = 1461, D100 = 36524, D400 = 146097;
127
128 int t = static_cast<int>(std::floor(date)) + DateDelta;
129 if (t <= 0) { year = 0; month = 1; day = 1; return; }
130
131 t--;
132 int y = 1, i, d;
133 while (t >= D400) { t -= D400; y += 400; }
134 divMod(t, D100, &i, &d);
135 if (i == 4) { i--; d += D100; }
136 y += i * 100;
137 divMod(d, D4, &i, &d);
138 y += i * 4;
139 divMod(d, D1, &i, &d);
140 if (i == 4) { i--; d += D1; }
141 y += i;
142
143 int k = isLeapYear(y) ? 1 : 0;
144 int m = 1;
145 for (;;) {
146 i = DaysPerMonth[k][m - 1];
147 if (d < i) break;
148 d -= i;
149 m++;
150 }
151 year = y; month = m; day = d + 1;
152}
153
161inline void decodeTime(DateTime time, int& h, int& m, int& s) {
162 double fracDay = (time - std::floor(time)) * SecsPerDay;
163 int secs = static_cast<int>(std::floor(fracDay + 0.5));
164 if (secs >= 86400) secs = 86399;
165 divMod(secs, 60, &m, &s); // mins, secs
166 int mins = m;
167 divMod(mins, 60, &h, &m); // hours, mins
168 if (h > 23) h = 0;
169}
170
179inline DateTime addSeconds(DateTime date, double seconds) {
180 double d = std::floor(date);
181 int h, m, s;
182 decodeTime(date, h, m, s);
183 return d + (3600.0 * h + 60.0 * m + s + seconds) / SecsPerDay;
184}
185
190inline long timeDiff(DateTime date1, DateTime date2) {
191 double d1 = std::floor(date1);
192 double d2 = std::floor(date2);
193 int h, m, s;
194 decodeTime(date1, h, m, s);
195 long s1 = 3600L * h + 60L * m + s;
196 decodeTime(date2, h, m, s);
197 long s2 = 3600L * h + 60L * m + s;
198 long secs = static_cast<long>(std::floor((d1 - d2) * SecsPerDay + 0.5));
199 secs += (s1 - s2);
200 return secs;
201}
202
206inline int monthOfYear(DateTime date) {
207 int y, m, d;
208 decodeDate(date, y, m, d);
209 return m;
210}
211
215inline int dayOfYear(DateTime date) {
216 int y, m, d;
217 decodeDate(date, y, m, d);
218 DateTime startOfYear = encodeDate(y, 1, 1);
219 return static_cast<int>(std::floor(date - startOfYear)) + 1;
220}
221
222} // namespace datetime
223} // namespace openswmm
224
225#endif // OPENSWMM_ENGINE_DATETIME_HPP
Definition DateTime.hpp:53
void decodeDate(DateTime date, int &year, int &month, int &day)
Decode DateTime to year-month-day.
Definition DateTime.hpp:122
DateTime encodeTime(int hour, int minute, int second)
Encode hour:minute:second to fractional day.
Definition DateTime.hpp:110
DateTime addSeconds(DateTime date, double seconds)
Add seconds to a DateTime — numerically identical to legacy.
Definition DateTime.hpp:179
double DateTime
Definition DateTime.hpp:67
int monthOfYear(DateTime date)
Get month of year (1..12) from DateTime.
Definition DateTime.hpp:206
bool isLeapYear(int year)
Check if year is a leap year.
Definition DateTime.hpp:84
void divMod(int n, int d, int *result, int *remainder)
Integer divmod — matching legacy divMod().
Definition DateTime.hpp:76
DateTime encodeDate(int year, int month, int day)
Encode year-month-day to DateTime.
Definition DateTime.hpp:92
long timeDiff(DateTime date1, DateTime date2)
Compute difference in seconds between two DateTimes.
Definition DateTime.hpp:190
void decodeTime(DateTime time, int &h, int &m, int &s)
Decode DateTime to hour:minute:second.
Definition DateTime.hpp:161
int dayOfYear(DateTime date)
Get day of year (1..365/366) from DateTime.
Definition DateTime.hpp:215
Definition NodeCoupling.cpp:16
double * y
Definition odesolve.c:28