1 #include "../chrono/datetime.h"
2 #include "../chrono/format.h"
3 #include "../chrono/period.h"
4 #include "../chrono/timespan.h"
5 #include "../conversion/conversionexception.h"
6 #include "../tests/testutils.h"
8 #include <cppunit/TestFixture.h>
9 #include <cppunit/extensions/HelperMacros.h>
19 using namespace CPPUNIT_NS;
22 static_assert(
DateTime().isNull(),
"isNull()");
23 static_assert(
DateTime(1).totalTicks() == 1,
"construction with ticks");
28 static_assert(DateTime::eternity().isEternity() && !
DateTime().isEternity(),
"isEternity()");
29 static constexpr
auto dateFromUnixEpoch(
30 DateTime::unixEpochStart() + TimeSpan::fromHours(1) + TimeSpan::fromMinutes(2) + TimeSpan::fromSeconds(3.1256789));
31 static_assert(dateFromUnixEpoch.dayOfWeek() == DayOfWeek::Thursday,
"dayOfWeek()");
32 static_assert(dateFromUnixEpoch.hour() == 1,
"hour()");
33 static_assert(dateFromUnixEpoch.minute() == 2,
"minute()");
34 static_assert(dateFromUnixEpoch.second() == 3,
"second()");
35 static_assert(dateFromUnixEpoch.millisecond() == 125,
"millisecond()");
36 static_assert(dateFromUnixEpoch.microsecond() == 678,
"microsecond()");
37 static_assert(dateFromUnixEpoch.nanosecond() == 900,
"nanosecond()");
38 static_assert(dateFromUnixEpoch.isSameDay(DateTime::unixEpochStart()),
"isSameDay()");
39 static_assert(!dateFromUnixEpoch.isSameDay(DateTime::unixEpochStart() + TimeSpan::fromHours(24)),
"!isSameDay()");
42 static_assert(
TimeSpan().isNull(),
"isNull()");
43 static_assert(
TimeSpan(1).totalTicks() == 1,
"construction with ticks");
44 static_assert(
TimeSpan(-1).isNegative() && !
TimeSpan(1).isNegative(),
"isNegative()");
45 static_assert(TimeSpan::infinity().isInfinity() && !
TimeSpan().isInfinity(),
"isInfinity()");
46 static_assert(TimeSpan::negativeInfinity().isNegativeInfinity() && !
TimeSpan().isNegativeInfinity(),
"isNegativeInfinity()");
47 static_assert(TimeSpan::fromMilliseconds(1.0125).nanoseconds() == 500,
"fromMilliseconds()/nanoseconds()");
48 static_assert(TimeSpan::fromMilliseconds(1.0125).microseconds() == 12,
"fromMilliseconds()/microseconds()");
49 static_assert(TimeSpan::fromMilliseconds(1.0125).milliseconds() == 1,
"fromMilliseconds()/milliseconds()");
50 static_assert(TimeSpan::fromSeconds(61).seconds() == 1,
"fromSeconds()/seconds()");
51 static_assert(TimeSpan::fromSeconds(61).minutes() == 1,
"fromSeconds()/minutes()");
52 static_assert(TimeSpan::fromMinutes(61).minutes() == 1,
"fromMinutes()/minutes()");
53 static_assert(TimeSpan::fromHours(25).hours() == 1,
"fromMinutes()/hours()");
54 static_assert(TimeSpan::fromDays(20.5).days() == 20,
"fromDays()/days()");
55 static_assert(TimeSpan::fromMinutes(1.5).totalMicroseconds() == 90e6,
"totalMicroseconds()");
56 static_assert(TimeSpan::fromMinutes(1.5).totalMilliseconds() == 90e3,
"totalMilliseconds()");
57 static_assert(TimeSpan::fromMinutes(1.5).totalSeconds() == 90.0,
"totalSeconds()");
58 static_assert(TimeSpan::fromHours(1.5).totalMinutes() == 90.0,
"totalMinutes()");
59 static_assert(TimeSpan::fromDays(1.5).totalHours() == 36.0,
"totalHours()");
60 static_assert(TimeSpan::fromDays(20.5).totalDays() == 20.5,
"totalDays()");
70 CPPUNIT_TEST(testDateTime);
71 CPPUNIT_TEST(testTimeSpan);
72 CPPUNIT_TEST(testOperators);
73 CPPUNIT_TEST(testPeriod);
74 CPPUNIT_TEST(testHashing);
75 CPPUNIT_TEST_SUITE_END();
100 CPPUNIT_ASSERT_EQUAL(DateTime::daysInMonth(2000, 2), 29);
101 CPPUNIT_ASSERT_EQUAL(DateTime::daysInMonth(2001, 2), 28);
102 CPPUNIT_ASSERT_EQUAL(DateTime::daysInMonth(2100, 2), 28);
103 const auto test1 = DateTime::fromDateAndTime(2012, 2, 29, 15, 34, 20, 33.0);
104 CPPUNIT_ASSERT_EQUAL(2012, test1.year());
105 CPPUNIT_ASSERT_EQUAL(2, test1.month());
106 CPPUNIT_ASSERT_EQUAL(29, test1.day());
107 CPPUNIT_ASSERT_EQUAL(15, test1.hour());
108 CPPUNIT_ASSERT_EQUAL(34, test1.minute());
109 CPPUNIT_ASSERT_EQUAL(20, test1.second());
110 CPPUNIT_ASSERT_EQUAL(33, test1.millisecond());
111 CPPUNIT_ASSERT_EQUAL(DayOfWeek::Wednesday, test1.dayOfWeek());
112 CPPUNIT_ASSERT_EQUAL((31 + 29), test1.dayOfYear());
113 CPPUNIT_ASSERT(test1.isLeapYear());
114 CPPUNIT_ASSERT(test1.isSameDay(test1 + TimeSpan::fromHours(8)));
115 CPPUNIT_ASSERT(!test1.isSameDay(test1 + TimeSpan::fromHours(9)));
116 CPPUNIT_ASSERT_EQUAL(
"Wed 2012-02-29 15:34:20.033"s, test1.toString(DateTimeOutputFormat::DateTimeAndShortWeekday));
117 const auto test2 = DateTime::fromDateAndTime(1, 1, 1, 15, 34, 20, 33.0);
118 CPPUNIT_ASSERT_EQUAL(1, test2.year());
119 CPPUNIT_ASSERT_EQUAL(1, test2.month());
120 CPPUNIT_ASSERT_EQUAL(1, test2.day());
121 CPPUNIT_ASSERT_EQUAL(15, test2.hour());
122 CPPUNIT_ASSERT_EQUAL(34, test2.minute());
123 CPPUNIT_ASSERT_EQUAL(20, test2.second());
124 CPPUNIT_ASSERT_EQUAL(33, test2.millisecond());
127 const auto timeStamp =
static_cast<time_t
>(1453840331);
128 const auto fromTimeStampGmt = DateTime::fromTimeStampGmt(timeStamp), fromTimeStamp = DateTime::fromTimeStamp(timeStamp);
129 CPPUNIT_ASSERT_EQUAL(
"Tue 2016-01-26 20:32:11"s, fromTimeStampGmt.toString(DateTimeOutputFormat::DateTimeAndShortWeekday));
130 CPPUNIT_ASSERT(fabs((fromTimeStamp - fromTimeStampGmt).totalDays()) <= 1.0);
131 CPPUNIT_ASSERT_EQUAL(
DateTime(), DateTime::fromTimeStamp(0));
132 CPPUNIT_ASSERT_EQUAL(timeStamp, fromTimeStampGmt.toTimeStamp());
135 const auto fromChronoTimePointGmt = DateTime::fromChronoTimePointGmt(chrono::system_clock::from_time_t(timeStamp));
136 CPPUNIT_ASSERT_EQUAL(
"Tue 2016-01-26 20:32:11"s, fromChronoTimePointGmt.toString(DateTimeOutputFormat::DateTimeAndShortWeekday));
141 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(0, 2, 29, 15, 34, 20, 33),
ConversionException);
142 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2013, 2, 29, 15, 34, 20, 33),
ConversionException);
143 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 2, 29, 15, 61, 20, 33),
ConversionException);
144 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 4, 31, 15, 0, 20, 33),
ConversionException);
145 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 3, 31, 15, 0, 61, 33),
ConversionException);
146 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 1, 1, 61, 2, 1),
ConversionException);
147 CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 1, 1, 15, 2, 1, 2000.0),
ConversionException);
150 CPPUNIT_ASSERT_EQUAL(test1, DateTime::fromString(
"2012-02-29 15:34:20.033"));
151 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"surplus parts ignored", test1, DateTime::fromString(
"2012-02-29 15:34:20.033:12"));
152 CPPUNIT_ASSERT_EQUAL(
"2012-02-29 15:34:20.033"s, test1.toString(DateTimeOutputFormat::DateAndTime,
false));
153 CPPUNIT_ASSERT_THROW(TimeSpan::fromString(
"2012-02-29 15:34:34:20.033"),
ConversionException);
154 const auto test3 = DateTime::fromIsoString(
"2016-08-29T21:32:31.125+02:00");
155 CPPUNIT_ASSERT_EQUAL(
"2016-08-29T21:32:31.125+02:00"s, test3.first.toIsoString(test3.second));
158 const auto test4 = DateTime::fromIsoString(
"2017-08-23T19:40:15.985077682+02:30");
159 CPPUNIT_ASSERT_EQUAL(2.5, test4.second.totalHours());
160 CPPUNIT_ASSERT_EQUAL(15, test4.first.second());
161 CPPUNIT_ASSERT_EQUAL(985, test4.first.millisecond());
162 CPPUNIT_ASSERT_EQUAL(77, test4.first.microsecond());
163 CPPUNIT_ASSERT_EQUAL(600, test4.first.nanosecond());
164 CPPUNIT_ASSERT_EQUAL(
"2017-08-23T19:40:15.9850776+02:30"s, test4.first.toIsoString(test4.second));
166 const auto test5 = DateTime::fromIsoString(
"2017-08-23T19:40:15.985077682-02:30");
167 CPPUNIT_ASSERT_EQUAL(-2.5, test5.second.totalHours());
168 CPPUNIT_ASSERT_EQUAL(15, test5.first.second());
169 CPPUNIT_ASSERT_EQUAL(985, test5.first.millisecond());
170 CPPUNIT_ASSERT_EQUAL(77, test5.first.microsecond());
171 CPPUNIT_ASSERT_EQUAL(600, test5.first.nanosecond());
172 CPPUNIT_ASSERT_EQUAL(
"2017-08-23T19:40:15.9850776-02:30"s, test5.first.toIsoString(test5.second));
174 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"only year", DateTime::fromDate(2008), DateTime::fromIsoStringGmt(
"2008"));
175 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"only year and month", DateTime::fromDate(2008, 12), DateTime::fromIsoStringGmt(
"2008-12"));
176 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"only date", DateTime::fromDate(2008, 12, 5), DateTime::fromIsoStringGmt(
"2008-12-05"));
177 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"Zulu time",
TimeSpan(), DateTime::fromIsoString(
"2017-08-23T19:40:15.985077682Z").second);
178 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"no minutes", TimeSpan::fromHours(3), DateTime::fromIsoString(
"2017-08-23T19:40:15.985077682+03").second);
179 const auto test6 = DateTime::fromIsoString(
"1970-01-01T01:02:03+01:00");
180 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"no seconds fraction", DateTime::fromDateAndTime(1970, 1, 1, 1, 2, 3), test6.first);
181 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"no seconds fraction", TimeSpan::fromHours(1.0), test6.second);
183 CPPUNIT_ASSERT_THROW_MESSAGE(
"digits after Z", DateTime::fromIsoString(
"2017-O8-23T19:40:15.985077682Z02:00"),
ConversionException);
184 CPPUNIT_ASSERT_THROW_MESSAGE(
"invalid letter", DateTime::fromIsoString(
"2017-O8-23T19:40:15.985077682:+02:00"),
ConversionException);
185 CPPUNIT_ASSERT_THROW_MESSAGE(
"invalid T", DateTime::fromIsoString(
"2017-08-23T19:T40:15.985077682+02:00"),
ConversionException);
186 CPPUNIT_ASSERT_THROW_MESSAGE(
"invalid -", DateTime::fromIsoString(
"2017-08-23T19:40-15.985077682+02:00"),
ConversionException);
187 CPPUNIT_ASSERT_THROW_MESSAGE(
"invalid .", DateTime::fromIsoString(
"2017-08.5-23T19:40:15.985077682+02:00"),
ConversionException);
188 CPPUNIT_ASSERT_THROW_MESSAGE(
"invalid :", DateTime::fromIsoString(
"2017:08-23T19:40:15.985077682+02:00"),
ConversionException);
189 CPPUNIT_ASSERT_THROW_MESSAGE(
"invalid :", DateTime::fromIsoString(
"2017-08-23T19:40:15:985077682+02:00"),
ConversionException);
191 CPPUNIT_ASSERT_EQUAL(
"1234-05-06T07:08:09.0105005"s, DateTime::fromDateAndTime(1234, 5, 6, 7, 8, 9, 10.5005).toString(DateTimeOutputFormat::Iso));
192 CPPUNIT_ASSERT_EQUAL(
"1234-05-06T07:08:09.0105005"s,
193 DateTime::fromDateAndTime(1234, 5, 6, 7, 8, 9, 10.5005).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
194 CPPUNIT_ASSERT_EQUAL(
"1234-05-06T07:08:09.010500"s,
195 DateTime::fromDateAndTime(1234, 5, 6, 7, 8, 9, 10.500).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
196 CPPUNIT_ASSERT_EQUAL(
197 "1234-05-06T07:08:09.010"s, DateTime::fromDateAndTime(1234, 5, 6, 7, 8, 9, 10).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
198 CPPUNIT_ASSERT_EQUAL(
199 "1234-05-06T07:08:09"s, DateTime::fromDateAndTime(1234, 5, 6, 7, 8, 9).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
200 CPPUNIT_ASSERT_EQUAL(
201 "1234-05-06T07:08"s, DateTime::fromDateAndTime(1234, 5, 6, 7, 8).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
202 CPPUNIT_ASSERT_EQUAL(
"1234-05-06T07"s, DateTime::fromDateAndTime(1234, 5, 6, 7).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
203 CPPUNIT_ASSERT_EQUAL(
"1234-05-06"s, DateTime::fromDateAndTime(1234, 5, 6).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
204 CPPUNIT_ASSERT_EQUAL(
"1234-05"s, DateTime::fromDateAndTime(1234, 5).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
205 CPPUNIT_ASSERT_EQUAL(
"1234"s, DateTime::fromDateAndTime(1234).toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
206 CPPUNIT_ASSERT_EQUAL(
"0001"s,
DateTime().toString(DateTimeOutputFormat::IsoOmittingDefaultComponents));
209 #if defined(PLATFORM_UNIX)
210 const auto delta = DateTime::gmtNow() - DateTime::exactGmtNow();
211 CPPUNIT_ASSERT(delta < TimeSpan::fromSeconds(2) && delta > TimeSpan::fromSeconds(-2));
221 CPPUNIT_ASSERT_EQUAL(
TimeSpan(), TimeSpan::fromString(
string()));
222 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(5.0), TimeSpan::fromString(
"5.0"));
223 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromMinutes(5.5), TimeSpan::fromString(
"5:30"));
224 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(7) + TimeSpan::fromMinutes(5.5), TimeSpan::fromString(
"7:5:30"));
225 const auto test1 = TimeSpan::fromString(
"2:34:53:2.5");
227 CPPUNIT_ASSERT_EQUAL(3, test1.days());
228 CPPUNIT_ASSERT_EQUAL(10, test1.hours());
229 CPPUNIT_ASSERT_EQUAL(53, test1.minutes());
230 CPPUNIT_ASSERT_EQUAL(2, test1.seconds());
231 CPPUNIT_ASSERT_EQUAL(500, test1.milliseconds());
232 CPPUNIT_ASSERT(test1.totalDays() > 3.0 && test1.totalDays() < 4.0);
233 CPPUNIT_ASSERT(test1.totalHours() > (2 * 24 + 34) && test1.totalHours() < (2 * 24 + 35));
234 CPPUNIT_ASSERT(test1.totalMinutes() > (2 * 24 * 60 + 34 * 60 + 53) && test1.totalHours() < (2 * 24 * 60 + 34 * 60 + 54));
236 CPPUNIT_ASSERT_EQUAL(
"3 d 10 h 53 min 2 s 500 ms"s, test1.toString(TimeSpanOutputFormat::WithMeasures,
false));
237 CPPUNIT_ASSERT_EQUAL(
"07:05:30"s, (TimeSpan::fromHours(7) + TimeSpan::fromMinutes(5.5)).toString());
238 CPPUNIT_ASSERT_EQUAL(
"-5 s"s, TimeSpan::fromSeconds(-5.0).toString(TimeSpanOutputFormat::WithMeasures,
false));
239 CPPUNIT_ASSERT_EQUAL(
"0 s"s,
TimeSpan().toString(TimeSpanOutputFormat::WithMeasures,
false));
240 CPPUNIT_ASSERT_EQUAL(
"5e+02 µs"s, TimeSpan::fromMilliseconds(0.5).toString(TimeSpanOutputFormat::WithMeasures,
false));
242 const auto test2 = TimeSpan::fromString(
"15.985077682");
243 CPPUNIT_ASSERT_EQUAL(15.9850776, test2.totalSeconds());
244 CPPUNIT_ASSERT_EQUAL(15, test2.seconds());
245 CPPUNIT_ASSERT_EQUAL(985, test2.milliseconds());
246 CPPUNIT_ASSERT_EQUAL(77, test2.microseconds());
247 CPPUNIT_ASSERT_EQUAL(600, test2.nanoseconds());
248 CPPUNIT_ASSERT_EQUAL(
"00:00:15.9850776"s, test2.toString());
249 CPPUNIT_ASSERT_EQUAL(
"15 s 985 ms 77 µs 600 ns"s, test2.toString(TimeSpanOutputFormat::WithMeasures));
250 CPPUNIT_ASSERT_EQUAL(
"15.9850776"s, test2.toString(TimeSpanOutputFormat::TotalSeconds));
261 auto dateTime = DateTime::fromDateAndTime(1999, 1, 5, 4, 16);
262 CPPUNIT_ASSERT_EQUAL(7, (dateTime + TimeSpan::fromDays(2)).day());
263 CPPUNIT_ASSERT_EQUAL(6, (dateTime + TimeSpan::fromHours(24)).day());
264 CPPUNIT_ASSERT_EQUAL(3, (dateTime + TimeSpan::fromHours(24) + TimeSpan::fromHours(-1)).hour());
265 CPPUNIT_ASSERT_EQUAL(17, (dateTime + TimeSpan::fromHours(24) - TimeSpan::fromMinutes(-1)).minute());
266 dateTime += TimeSpan::fromDays(365);
267 CPPUNIT_ASSERT_EQUAL(2000, dateTime.year());
268 CPPUNIT_ASSERT_EQUAL(5, dateTime.day());
269 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromDays(1), TimeSpan::fromHours(12) * 2);
270 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(12), TimeSpan::fromDays(1) / 2);
271 CPPUNIT_ASSERT_EQUAL(2.0, TimeSpan::fromDays(1) / TimeSpan::fromHours(12));
279 const auto begin(DateTime::fromDateAndTime(1994, 7, 18, 15, 30, 21)), end(DateTime::fromDateAndTime(2017, 12, 2, 15, 30, 21));
280 const Period period(begin, end);
281 CPPUNIT_ASSERT_EQUAL(23, period.
years());
282 CPPUNIT_ASSERT_EQUAL(4, period.
months());
283 CPPUNIT_ASSERT_EQUAL(14, period.
days());
284 CPPUNIT_ASSERT_EQUAL(end.toString(), (begin + period).toString());
286 const auto end2(DateTime::fromDateAndTime(2018, 1, 2, 15, 30, 21));
287 const Period period2(begin, end2);
288 CPPUNIT_ASSERT_EQUAL(23, period2.
years());
289 CPPUNIT_ASSERT_EQUAL(5, period2.
months());
290 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"one more day, because December has 31 days", 15, period2.
days());
291 CPPUNIT_ASSERT_EQUAL(end2.toString(), (begin + period2).toString());
299 set<DateTime> dateTimes;
300 dateTimes.emplace(DateTime::fromDate(2500, 2, 1));
301 dateTimes.emplace(DateTime::fromDate(2500, 2, 2));
302 dateTimes.emplace(DateTime::fromDate(2500, 2, 1));
303 CPPUNIT_ASSERT_EQUAL(2_st, dateTimes.size());
305 set<TimeSpan> timeSpans;
306 timeSpans.emplace(TimeSpan::fromDays(5));
307 timeSpans.emplace(TimeSpan::fromDays(10));
308 timeSpans.emplace(TimeSpan::fromDays(5));
309 CPPUNIT_ASSERT_EQUAL(2_st, timeSpans.size());
CPPUNIT_TEST_SUITE_REGISTRATION(ChronoTests)
The ChronoTests class tests classes and functions provided by the files inside the chrono directory.
void testTimeSpan()
Tests most important TimeSpan features.
void testHashing()
Tests hashing DateTime / TimeSpan by using in a set.
void testOperators()
Tests operators of DateTime / TimeSpan.
void testDateTime()
Tests most important DateTime features.
void testPeriod()
Tests Period.
The ConversionException class is thrown by the various conversion functions of this library when a co...
Represents an instant in time, typically expressed as a date and time of day.
Represents a period of time.
constexpr int days() const
Returns the days component of the period represented by the current instance.
constexpr int years() const
Returns the years component of the period represented by the current instance.
constexpr int months() const
Returns the months component of the period represented by the current instance.
Represents a time interval.
Contains literals to ease asserting with CPPUNIT_ASSERT_EQUAL.
Contains all utilities provides by the c++utilities library.