12#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
13#include <doctest/doctest.h>
17TEST_SUITE_BEGIN(
"Time");
18TEST_CASE(
"TimePoint parsing and formating")
21 std::stringstream is(
"2022-06-07T14:16:01Z");
29 REQUIRE(is.str() == os.str());
33 std::string rightNow =
"2022-06-10T09:33:21Z";
35 REQUIRE(tq.format() == rightNow);
38TEST_CASE(
"Julian-Gregorian shifts")
57 const int days = 24 * 60 * 60;
59 const char* iso = TimePoint::ymdhmsFormat.c_str();
61 std::stringstream ss(
"1970-01-01T00:00:00");
63 ss >> std::get_time(&epoch_tm, iso);
65 std::time_t epoch_time =
mkgmtime(&epoch_tm);
67 REQUIRE(epoch_time == 0);
69 std::stringstream ss1(
"1971-01-01T00:00:00");
72 ss1 >> std::get_time(&tm, iso);
73 REQUIRE(
mkgmtime(&tm) == 365 * days);
76 std::stringstream stow(
"2022-06-07T15:37:45");
77 stow >> std::get_time(&tow_tm, iso);
78 std::time_t timeOfWriting =
mkgmtime(&tow_tm);
80 REQUIRE(timeOfWriting == 1654616265);
83 std::stringstream(
"1980-02-28T00:00:00") >> std::get_time(&tm, iso);
86 std::stringstream(
"1980-03-01T00:00:00") >> std::get_time(&tm, iso);
89 REQUIRE((after - before) == 2 * days);
90 std::stringstream(
"1980-02-13T00:00:00") >> std::get_time(&tm, iso);
94 std::stringstream(
"2100-02-28T00:00:00") >> std::get_time(&tm, iso);
97 std::stringstream(
"2100-03-01T00:00:00") >> std::get_time(&tm, iso);
100 REQUIRE((after - before) == 1 * days);
102 REQUIRE(before == 4107456000);
103 REQUIRE(after == 4107542400);
106 std::stringstream(
"2099-12-31T00:00:00") >> std::get_time(&tm, iso);
107 REQUIRE(
mkgmtime(&tm) == 4102358400);
108 std::stringstream(
"2100-01-01T00:00:00") >> std::get_time(&tm, iso);
109 REQUIRE(
mkgmtime(&tm) == 4102444800);
110 std::stringstream(
"2101-01-01T00:00:00") >> std::get_time(&tm, iso);
111 REQUIRE(
mkgmtime(&tm) == 4133980800);
112 std::stringstream(
"2101-01-01T00:00:00") >> std::get_time(&tm, iso);
114 std::stringstream(
"2100-01-01T00:00:00") >> std::get_time(&tm, iso);
116 REQUIRE(after - before == 365 * days);
119TEST_CASE(
"timeFromISO")
121 const int days = 24 * 60 * 60;
127 REQUIRE(
timeFromISO(
"1970-01-03T12:00:00Z") == 2 * days + (days / 2));
129 REQUIRE(
timeFromISO(
"1970-02-01T06:00:00") == 31 * days + (days / 4));
134 REQUIRE(
timeFromISO(
"1971-003T00:00:00") == 367 * days);
138 bool previousDOY = TimeOptions::useDOY();
139 TimeOptions::useDOY() =
true;
141 TimeOptions::useDOY() = previousDOY;
144TEST_CASE(
"TimePoints")
150 REQUIRE(tp.parse(
"1980-07-30") == tq.parse(
"1980-212"));
151 REQUIRE(tp.parse(
"1980-07-30") > tq.parse(
"1980-07-29"));
152 REQUIRE(tp.parse(
"1980-07-30") >= tq.parse(
"1980-212"));
153 REQUIRE(tp.parse(
"1980-07-30") >= tq.parse(
"1980-07-29"));
154 REQUIRE(tp.parse(
"1980-07-30") < tq.parse(
"1980-07-31"));
155 REQUIRE(tp.parse(
"1980-07-30") <= tq.parse(
"1980-212"));
156 REQUIRE(tp.parse(
"1980-07-30") <= tq.parse(
"1980-07-31"));
157 REQUIRE(tp.parse(
"1980-07-30") != tq.parse(
"1980-07-29"));
160TEST_CASE(
"Durations")
162 const int days = 24 * 60 * 60;
166 REQUIRE_THROWS(dur.parse(
"0-0-0T0:0:1"));
167 REQUIRE(dur.parse(
"P0-1").seconds() == 1 * days);
168 REQUIRE(dur.parse(
"P0-0T0:0:1").seconds() == 1);
169 REQUIRE(dur.parse(
"P-0-0T0:0:1").seconds() == -1);
174 Duration
s(
"P0-0T0:0:1");
176 int daySeconds = 86400;
177 int yearSeconds = 365 * daySeconds;
178 REQUIRE((yr + dy).seconds() == yearSeconds + daySeconds);
179 REQUIRE((dy - yr).seconds() == daySeconds - yearSeconds);
182 REQUIRE(yr.seconds() == yearSeconds + 1);
184 REQUIRE(yr.seconds() == yearSeconds);
186 REQUIRE(yr.seconds() == 2 * yearSeconds);
188 REQUIRE(yr.seconds() == yearSeconds);
191 TimePoint tt(
"2010-01-01T00:00:00Z");
192 TimePoint tt_day(
"2010-01-02T00:00:00Z");
194 REQUIRE(tt + dy == tt_day);
195 REQUIRE(dy + tt == tt_day);
197 TimePoint ttOther(tt);
199 REQUIRE(ttOther == tt_day);
201 Duration maybeADay = tt_day - tt;
202 REQUIRE(maybeADay.seconds() == 1 * days);
204 Duration tenSeconds(10.);
205 REQUIRE(tenSeconds.seconds() == 10);
207 Duration hundredSeconds(
"100.");
208 REQUIRE(hundredSeconds.seconds() == 100);
210 Duration minusThousandSeconds(
"-1000.");
211 REQUIRE(minusThousandSeconds.seconds() == -1000);
213 Duration myriadSeconds(1e4);
214 REQUIRE(myriadSeconds.seconds() == 10000);
216 Duration strMyriadSeconds(
"1e4");
217 REQUIRE(strMyriadSeconds.seconds() == 10000);
219 Duration complexStrSec(
"-1440.42e-2");
220 REQUIRE(complexStrSec.seconds() == -14);
222 Duration aDay(daySeconds);
223 REQUIRE(aDay.seconds() == daySeconds);
226TEST_CASE(
"gmtime and doy")
228 TimePoint janfirst(
"2010-01-01T00:00:00Z");
229 std::tm* timeStruct = janfirst.gmtime();
230 REQUIRE(timeStruct->tm_yday == 0);
233 TimePoint marchfirst(
"2010-03-01T00:00:00Z");
234 REQUIRE(marchfirst.gmtime()->tm_yday == 59);
235 TimePoint bissextile(
"2020-03-01T00:00:00Z");
236 REQUIRE(bissextile.gmtime()->tm_yday == 60);
std::time_t timeFromISO(const std::string &iso)
Returns a std::time_t from a given ISO date string of a specific format.
int julianGregorianShiftDays(int year)
Returns the number of days between the Julian and Gregorian years.
std::time_t mkgmtime(std::tm *time, bool recalculateDoy=true)
converts the std::tm struct to a std::time_t value assuming UTC.
const double s
Salinity of sea ice. [g kg⁻¹].