Add `TickType` and integer overloads to chrono utilities

This commit is contained in:
Martchus 2022-02-15 23:00:18 +01:00
parent a8fddad804
commit 77c353fb6c
6 changed files with 171 additions and 66 deletions

View File

@ -114,7 +114,7 @@ set(META_APP_AUTHOR "Martchus")
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "Useful C++ classes and routines such as argument parser, IO and conversion utilities")
set(META_VERSION_MAJOR 5)
set(META_VERSION_MINOR 12)
set(META_VERSION_MINOR 13)
set(META_VERSION_PATCH 0)
# find required 3rd party libraries

View File

@ -385,7 +385,7 @@ DateTime DateTime::exactGmtNow()
/*!
* \brief Converts the given date expressed in \a year, \a month and \a day to ticks.
*/
std::uint64_t DateTime::dateToTicks(int year, int month, int day)
DateTime::TickType DateTime::dateToTicks(int year, int month, int day)
{
if (!inRangeInclMax(year, 1, 9999)) {
throw ConversionException("year is out of range");
@ -408,7 +408,7 @@ std::uint64_t DateTime::dateToTicks(int year, int month, int day)
/*!
* \brief Converts the given time expressed in \a hour, \a minute, \a second and \a millisecond to ticks.
*/
std::uint64_t DateTime::timeToTicks(int hour, int minute, int second, double millisecond)
DateTime::TickType DateTime::timeToTicks(int hour, int minute, int second, double millisecond)
{
if (!inRangeExclMax(hour, 0, 24)) {
throw ConversionException("hour is out of range");

View File

@ -52,8 +52,10 @@ enum class DatePart {
class CPP_UTILITIES_EXPORT DateTime {
public:
using TickType = std::uint64_t;
explicit constexpr DateTime();
explicit constexpr DateTime(std::uint64_t ticks);
explicit constexpr DateTime(TickType ticks);
static DateTime fromDate(int year = 1, int month = 1, int day = 1);
static DateTime fromTime(int hour = 0, int minute = 0, int second = 0, double millisecond = 0.0);
static DateTime fromDateAndTime(int year = 1, int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, double millisecond = 0.0);
@ -67,8 +69,8 @@ public:
template <typename TimePoint> static DateTime fromChronoTimePoint(TimePoint timePoint);
template <typename TimePoint> constexpr static DateTime fromChronoTimePointGmt(TimePoint timePoint);
constexpr std::uint64_t &ticks();
constexpr std::uint64_t totalTicks() const;
constexpr TickType &ticks();
constexpr TickType totalTicks() const;
int year() const;
int month() const;
int day() const;
@ -117,11 +119,11 @@ public:
DateTime &operator-=(const TimeSpan &timeSpan);
private:
static std::uint64_t dateToTicks(int year, int month, int day);
static std::uint64_t timeToTicks(int hour, int minute, int second, double millisecond);
static TickType dateToTicks(int year, int month, int day);
static TickType timeToTicks(int hour, int minute, int second, double millisecond);
int getDatePart(DatePart part) const;
std::uint64_t m_ticks;
TickType m_ticks;
static const int m_daysPerYear;
static const int m_daysPer4Years;
static const int m_daysPer100Years;
@ -146,7 +148,7 @@ constexpr inline DateTime::DateTime()
/*!
* \brief Constructs a DateTime with the specified number of \a ticks.
*/
constexpr inline DateTime::DateTime(std::uint64_t ticks)
constexpr inline DateTime::DateTime(TickType ticks)
: m_ticks(ticks)
{
}
@ -247,7 +249,7 @@ template <typename TimePoint> constexpr DateTime DateTime::fromChronoTimePointGm
/*!
* \brief Returns a mutable reference to the total ticks.
*/
constexpr inline std::uint64_t &DateTime::ticks()
constexpr inline DateTime::TickType &DateTime::ticks()
{
return m_ticks;
}
@ -255,7 +257,7 @@ constexpr inline std::uint64_t &DateTime::ticks()
/*!
* \brief Returns the number of ticks which represent the value of the current instance.
*/
constexpr inline std::uint64_t DateTime::totalTicks() const
constexpr inline DateTime::TickType DateTime::totalTicks() const
{
return m_ticks;
}
@ -365,7 +367,7 @@ constexpr inline bool DateTime::isNull() const
*/
constexpr inline TimeSpan DateTime::timeOfDay() const
{
return TimeSpan(static_cast<std::int64_t>(m_ticks % TimeSpan::ticksPerDay));
return TimeSpan(static_cast<TimeSpan::TickType>(m_ticks % TimeSpan::ticksPerDay));
}
/*!
@ -381,7 +383,7 @@ inline bool DateTime::isLeapYear() const
*/
constexpr inline bool DateTime::isEternity() const
{
return m_ticks == std::numeric_limits<decltype(m_ticks)>::max();
return m_ticks == std::numeric_limits<TickType>::max();
}
/*!
@ -433,7 +435,7 @@ constexpr std::time_t DateTime::toTimeStamp() const
*/
constexpr inline DateTime DateTime::eternity()
{
return DateTime(std::numeric_limits<decltype(m_ticks)>::max());
return DateTime(std::numeric_limits<TickType>::max());
}
/*!
@ -516,7 +518,7 @@ constexpr inline bool DateTime::operator>=(const DateTime &other) const
*/
constexpr inline DateTime DateTime::operator+(const TimeSpan &timeSpan) const
{
return DateTime(m_ticks + static_cast<std::uint64_t>(timeSpan.m_ticks));
return DateTime(m_ticks + static_cast<TickType>(timeSpan.m_ticks));
}
/*!
@ -525,7 +527,7 @@ constexpr inline DateTime DateTime::operator+(const TimeSpan &timeSpan) const
*/
constexpr inline DateTime DateTime::operator-(const TimeSpan &timeSpan) const
{
return DateTime(m_ticks - static_cast<std::uint64_t>(timeSpan.m_ticks));
return DateTime(m_ticks - static_cast<TickType>(timeSpan.m_ticks));
}
/*!
@ -534,7 +536,7 @@ constexpr inline DateTime DateTime::operator-(const TimeSpan &timeSpan) const
*/
constexpr inline TimeSpan DateTime::operator+(const DateTime &other) const
{
return TimeSpan(static_cast<std::int64_t>(m_ticks + other.m_ticks));
return TimeSpan(static_cast<TimeSpan::TickType>(m_ticks + other.m_ticks));
}
/*!
@ -545,7 +547,7 @@ constexpr inline TimeSpan DateTime::operator+(const DateTime &other) const
*/
constexpr inline TimeSpan DateTime::operator-(const DateTime &other) const
{
return TimeSpan(static_cast<std::int64_t>(m_ticks - other.m_ticks));
return TimeSpan(static_cast<TimeSpan::TickType>(m_ticks - other.m_ticks));
}
/*!
@ -553,7 +555,7 @@ constexpr inline TimeSpan DateTime::operator-(const DateTime &other) const
*/
inline DateTime &DateTime::operator+=(const TimeSpan &timeSpan)
{
m_ticks += static_cast<std::uint64_t>(timeSpan.m_ticks);
m_ticks += static_cast<TickType>(timeSpan.m_ticks);
return *this;
}
@ -562,7 +564,7 @@ inline DateTime &DateTime::operator+=(const TimeSpan &timeSpan)
*/
inline DateTime &DateTime::operator-=(const TimeSpan &timeSpan)
{
m_ticks += static_cast<std::uint64_t>(timeSpan.m_ticks);
m_ticks += static_cast<TickType>(timeSpan.m_ticks);
return *this;
}
} // namespace CppUtilities
@ -572,7 +574,7 @@ namespace std {
template <> struct hash<CppUtilities::DateTime> {
inline size_t operator()(const CppUtilities::DateTime &dateTime) const
{
return hash<decltype(dateTime.totalTicks())>()(dateTime.totalTicks());
return hash<CppUtilities::DateTime::TickType>()(dateTime.totalTicks());
}
};
} // namespace std

View File

@ -1,3 +1,5 @@
#define CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
#include "./timespan.h"
#include "../conversion/stringconversion.h"

View File

@ -26,21 +26,30 @@ class CPP_UTILITIES_EXPORT TimeSpan {
friend class DateTime;
public:
using TickType = std::int64_t;
explicit constexpr TimeSpan();
explicit constexpr TimeSpan(std::int64_t ticks);
explicit constexpr TimeSpan(TickType ticks);
static constexpr TimeSpan fromMilliseconds(double milliseconds);
static constexpr TimeSpan fromSeconds(double seconds);
static constexpr TimeSpan fromMinutes(double minutes);
static constexpr TimeSpan fromHours(double hours);
static constexpr TimeSpan fromDays(double days);
#ifdef CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
static constexpr TimeSpan fromMilliseconds(TickType milliseconds);
static constexpr TimeSpan fromSeconds(TickType seconds);
static constexpr TimeSpan fromMinutes(TickType minutes);
static constexpr TimeSpan fromHours(TickType hours);
static constexpr TimeSpan fromDays(TickType days);
#endif
static TimeSpan fromString(const std::string &str, char separator = ':');
static TimeSpan fromString(const char *str, char separator);
static constexpr TimeSpan negativeInfinity();
static constexpr TimeSpan infinity();
std::int64_t &ticks();
constexpr std::int64_t totalTicks() const;
TickType &ticks();
constexpr TickType totalTicks() const;
constexpr double totalMicroseconds() const;
constexpr double totalMilliseconds() const;
constexpr double totalSeconds() const;
@ -66,11 +75,19 @@ public:
constexpr TimeSpan operator-(const TimeSpan &other) const;
constexpr TimeSpan operator*(double factor) const;
constexpr TimeSpan operator/(double factor) const;
#ifdef CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
constexpr TimeSpan operator*(TickType factor) const;
constexpr TimeSpan operator/(TickType factor) const;
#endif
constexpr double operator/(TimeSpan other) const;
TimeSpan &operator+=(const TimeSpan &other);
TimeSpan &operator-=(const TimeSpan &other);
TimeSpan &operator*=(double factor);
TimeSpan &operator/=(double factor);
#ifdef CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
TimeSpan &operator*=(TickType factor);
TimeSpan &operator/=(TickType factor);
#endif
std::string toString(TimeSpanOutputFormat format = TimeSpanOutputFormat::Normal, bool fullSeconds = false) const;
void toString(std::string &result, TimeSpanOutputFormat format = TimeSpanOutputFormat::Normal, bool fullSeconds = false) const;
@ -79,16 +96,16 @@ public:
constexpr bool isNegativeInfinity() const;
constexpr bool isInfinity() const;
static constexpr std::int64_t nanosecondsPerTick = 100uL;
static constexpr std::int64_t ticksPerMicrosecond = 10uL;
static constexpr std::int64_t ticksPerMillisecond = 10000uL;
static constexpr std::int64_t ticksPerSecond = 10000000uL;
static constexpr std::int64_t ticksPerMinute = 600000000uL;
static constexpr std::int64_t ticksPerHour = 36000000000uL;
static constexpr std::int64_t ticksPerDay = 864000000000uL;
static constexpr TickType nanosecondsPerTick = 100L;
static constexpr TickType ticksPerMicrosecond = 10L;
static constexpr TickType ticksPerMillisecond = 10000L;
static constexpr TickType ticksPerSecond = 10000000L;
static constexpr TickType ticksPerMinute = 600000000L;
static constexpr TickType ticksPerHour = 36000000000L;
static constexpr TickType ticksPerDay = 864000000000L;
private:
std::int64_t m_ticks;
TickType m_ticks;
};
/*!
@ -102,7 +119,7 @@ constexpr inline TimeSpan::TimeSpan()
/*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of ticks.
*/
constexpr inline TimeSpan::TimeSpan(std::int64_t ticks)
constexpr inline TimeSpan::TimeSpan(TickType ticks)
: m_ticks(ticks)
{
}
@ -112,7 +129,7 @@ constexpr inline TimeSpan::TimeSpan(std::int64_t ticks)
*/
constexpr inline TimeSpan TimeSpan::fromMilliseconds(double milliseconds)
{
return TimeSpan(static_cast<std::int64_t>(milliseconds * static_cast<double>(ticksPerMillisecond)));
return TimeSpan(static_cast<TickType>(milliseconds * static_cast<double>(ticksPerMillisecond)));
}
/*!
@ -120,7 +137,7 @@ constexpr inline TimeSpan TimeSpan::fromMilliseconds(double milliseconds)
*/
constexpr inline TimeSpan TimeSpan::fromSeconds(double seconds)
{
return TimeSpan(static_cast<std::int64_t>(seconds * static_cast<double>(ticksPerSecond)));
return TimeSpan(static_cast<TickType>(seconds * static_cast<double>(ticksPerSecond)));
}
/*!
@ -128,7 +145,7 @@ constexpr inline TimeSpan TimeSpan::fromSeconds(double seconds)
*/
constexpr inline TimeSpan TimeSpan::fromMinutes(double minutes)
{
return TimeSpan(static_cast<std::int64_t>(minutes * static_cast<double>(ticksPerMinute)));
return TimeSpan(static_cast<TickType>(minutes * static_cast<double>(ticksPerMinute)));
}
/*!
@ -136,7 +153,7 @@ constexpr inline TimeSpan TimeSpan::fromMinutes(double minutes)
*/
constexpr inline TimeSpan TimeSpan::fromHours(double hours)
{
return TimeSpan(static_cast<std::int64_t>(hours * static_cast<double>(ticksPerHour)));
return TimeSpan(static_cast<TickType>(hours * static_cast<double>(ticksPerHour)));
}
/*!
@ -144,9 +161,51 @@ constexpr inline TimeSpan TimeSpan::fromHours(double hours)
*/
constexpr inline TimeSpan TimeSpan::fromDays(double days)
{
return TimeSpan(static_cast<std::int64_t>(days * static_cast<double>(ticksPerDay)));
return TimeSpan(static_cast<TickType>(days * static_cast<double>(ticksPerDay)));
}
#ifdef CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
/*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of milliseconds.
*/
constexpr inline TimeSpan TimeSpan::fromMilliseconds(TickType milliseconds)
{
return TimeSpan(milliseconds * ticksPerMillisecond);
}
/*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of seconds.
*/
constexpr inline TimeSpan TimeSpan::fromSeconds(TickType seconds)
{
return TimeSpan(seconds * ticksPerSecond);
}
/*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of minutes.
*/
constexpr inline TimeSpan TimeSpan::fromMinutes(TickType minutes)
{
return TimeSpan(minutes * ticksPerMinute);
}
/*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of hours.
*/
constexpr inline TimeSpan TimeSpan::fromHours(TickType hours)
{
return TimeSpan(hours * ticksPerHour);
}
/*!
* \brief Constructs a new instance of the TimeSpan class with the specified number of days.
*/
constexpr inline TimeSpan TimeSpan::fromDays(TickType days)
{
return TimeSpan(days * ticksPerDay);
}
#endif
/*!
* \brief Parses the given std::string as TimeSpan.
* \throws Throws a ConversionException if the specified \a str does not match the expected format.
@ -165,7 +224,7 @@ inline TimeSpan TimeSpan::fromString(const std::string &str, char separator)
*/
constexpr inline TimeSpan TimeSpan::negativeInfinity()
{
return TimeSpan(std::numeric_limits<decltype(m_ticks)>::min());
return TimeSpan(std::numeric_limits<TickType>::min());
}
/*!
@ -173,13 +232,13 @@ constexpr inline TimeSpan TimeSpan::negativeInfinity()
*/
constexpr inline TimeSpan TimeSpan::infinity()
{
return TimeSpan(std::numeric_limits<decltype(m_ticks)>::max());
return TimeSpan(std::numeric_limits<TickType>::max());
}
/*!
* \brief Returns a mutable reference to the total ticks.
*/
inline std::int64_t &TimeSpan::ticks()
inline TimeSpan::TickType &TimeSpan::ticks()
{
return m_ticks;
}
@ -187,7 +246,7 @@ inline std::int64_t &TimeSpan::ticks()
/*!
* \brief Returns the number of ticks that represent the value of the current TimeSpan class.
*/
constexpr inline std::int64_t TimeSpan::totalTicks() const
constexpr inline TimeSpan::TickType TimeSpan::totalTicks() const
{
return m_ticks;
}
@ -378,6 +437,24 @@ constexpr inline TimeSpan TimeSpan::operator/(double factor) const
return TimeSpan(static_cast<std::int64_t>(static_cast<double>(m_ticks) / factor));
}
#ifdef CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
/*!
* \brief Multiplies a TimeSpan by the specified \a factor.
*/
constexpr inline TimeSpan TimeSpan::operator*(std::int64_t factor) const
{
return TimeSpan(m_ticks * factor);
}
/*!
* \brief Divides a TimeSpan by the specified \a factor.
*/
constexpr inline TimeSpan TimeSpan::operator/(std::int64_t factor) const
{
return TimeSpan(m_ticks / factor);
}
#endif
/*!
* \brief Computes the ratio between two TimeSpan instances.
*/
@ -422,6 +499,26 @@ inline TimeSpan &TimeSpan::operator/=(double factor)
return *this;
}
#ifdef CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
/*!
* \brief Multiplies the current instance by the specified \a factor.
*/
inline TimeSpan &TimeSpan::operator*=(std::int64_t factor)
{
m_ticks *= factor;
return *this;
}
/*!
* \brief Divides the current instance by the specified \a factor.
*/
inline TimeSpan &TimeSpan::operator/=(std::int64_t factor)
{
m_ticks /= factor;
return *this;
}
#endif
/*!
* \brief Converts the value of the current TimeSpan object to its equivalent std::string representation
* according the given \a format.

View File

@ -1,3 +1,5 @@
#define CHRONO_UTILITIES_TIMESPAN_INTEGER_SCALE_OVERLOADS
#include "../chrono/datetime.h"
#include "../chrono/format.h"
#include "../chrono/period.h"
@ -27,7 +29,7 @@ static_assert(DateTime(2) < DateTime(3), "operator <");
static_assert(DateTime(3) > DateTime(2), "operator >");
static_assert(DateTime::eternity().isEternity() && !DateTime().isEternity(), "isEternity()");
static constexpr auto dateFromUnixEpoch(
DateTime::unixEpochStart() + TimeSpan::fromHours(1) + TimeSpan::fromMinutes(2) + TimeSpan::fromSeconds(3.1256789));
DateTime::unixEpochStart() + TimeSpan::fromHours(1.0) + TimeSpan::fromMinutes(2.0) + TimeSpan::fromSeconds(3.1256789));
static_assert(dateFromUnixEpoch.dayOfWeek() == DayOfWeek::Thursday, "dayOfWeek()");
static_assert(dateFromUnixEpoch.hour() == 1, "hour()");
static_assert(dateFromUnixEpoch.minute() == 2, "minute()");
@ -36,7 +38,7 @@ static_assert(dateFromUnixEpoch.millisecond() == 125, "millisecond()");
static_assert(dateFromUnixEpoch.microsecond() == 678, "microsecond()");
static_assert(dateFromUnixEpoch.nanosecond() == 900, "nanosecond()");
static_assert(dateFromUnixEpoch.isSameDay(DateTime::unixEpochStart()), "isSameDay()");
static_assert(!dateFromUnixEpoch.isSameDay(DateTime::unixEpochStart() + TimeSpan::fromHours(24)), "!isSameDay()");
static_assert(!dateFromUnixEpoch.isSameDay(DateTime::unixEpochStart() + TimeSpan::fromHours(24.0)), "!isSameDay()");
// compile-time checks for TimeSpan class
static_assert(TimeSpan().isNull(), "isNull()");
@ -47,10 +49,10 @@ static_assert(TimeSpan::negativeInfinity().isNegativeInfinity() && !TimeSpan().i
static_assert(TimeSpan::fromMilliseconds(1.0125).nanoseconds() == 500, "fromMilliseconds()/nanoseconds()");
static_assert(TimeSpan::fromMilliseconds(1.0125).microseconds() == 12, "fromMilliseconds()/microseconds()");
static_assert(TimeSpan::fromMilliseconds(1.0125).milliseconds() == 1, "fromMilliseconds()/milliseconds()");
static_assert(TimeSpan::fromSeconds(61).seconds() == 1, "fromSeconds()/seconds()");
static_assert(TimeSpan::fromSeconds(61).minutes() == 1, "fromSeconds()/minutes()");
static_assert(TimeSpan::fromMinutes(61).minutes() == 1, "fromMinutes()/minutes()");
static_assert(TimeSpan::fromHours(25).hours() == 1, "fromMinutes()/hours()");
static_assert(TimeSpan::fromSeconds(TimeSpan::TickType(61)).seconds() == 1, "fromSeconds()/seconds()");
static_assert(TimeSpan::fromSeconds(TimeSpan::TickType(61)).minutes() == 1, "fromSeconds()/minutes()");
static_assert(TimeSpan::fromMinutes(TimeSpan::TickType(61)).minutes() == 1, "fromMinutes()/minutes()");
static_assert(TimeSpan::fromHours(TimeSpan::TickType(25)).hours() == 1, "fromMinutes()/hours()");
static_assert(TimeSpan::fromDays(20.5).days() == 20, "fromDays()/days()");
static_assert(TimeSpan::fromMinutes(1.5).totalMicroseconds() == 90e6, "totalMicroseconds()");
static_assert(TimeSpan::fromMinutes(1.5).totalMilliseconds() == 90e3, "totalMilliseconds()");
@ -111,8 +113,8 @@ void ChronoTests::testDateTime()
CPPUNIT_ASSERT_EQUAL(DayOfWeek::Wednesday, test1.dayOfWeek());
CPPUNIT_ASSERT_EQUAL((31 + 29), test1.dayOfYear());
CPPUNIT_ASSERT(test1.isLeapYear());
CPPUNIT_ASSERT(test1.isSameDay(test1 + TimeSpan::fromHours(8)));
CPPUNIT_ASSERT(!test1.isSameDay(test1 + TimeSpan::fromHours(9)));
CPPUNIT_ASSERT(test1.isSameDay(test1 + TimeSpan::fromHours(8.0)));
CPPUNIT_ASSERT(!test1.isSameDay(test1 + TimeSpan::fromHours(9.0)));
CPPUNIT_ASSERT_EQUAL("Wed 2012-02-29 15:34:20.033"s, test1.toString(DateTimeOutputFormat::DateTimeAndShortWeekday));
const auto test2 = DateTime::fromDateAndTime(1, 1, 1, 15, 34, 20, 33.0);
CPPUNIT_ASSERT_EQUAL(1, test2.year());
@ -175,7 +177,7 @@ void ChronoTests::testDateTime()
CPPUNIT_ASSERT_EQUAL_MESSAGE("only year and month", DateTime::fromDate(2008, 12), DateTime::fromIsoStringGmt("2008-12"));
CPPUNIT_ASSERT_EQUAL_MESSAGE("only date", DateTime::fromDate(2008, 12, 5), DateTime::fromIsoStringGmt("2008-12-05"));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Zulu time", TimeSpan(), DateTime::fromIsoString("2017-08-23T19:40:15.985077682Z").second);
CPPUNIT_ASSERT_EQUAL_MESSAGE("no minutes", TimeSpan::fromHours(3), DateTime::fromIsoString("2017-08-23T19:40:15.985077682+03").second);
CPPUNIT_ASSERT_EQUAL_MESSAGE("no minutes", TimeSpan::fromHours(3.0), DateTime::fromIsoString("2017-08-23T19:40:15.985077682+03").second);
const auto test6 = DateTime::fromIsoString("1970-01-01T01:02:03+01:00");
CPPUNIT_ASSERT_EQUAL_MESSAGE("no seconds fraction (positive timezone offset, 1)", DateTime::fromDateAndTime(1970, 1, 1, 1, 2, 3), test6.first);
CPPUNIT_ASSERT_EQUAL_MESSAGE("no seconds fraction (positive timezone offset, 2)", TimeSpan::fromHours(1.0), test6.second);
@ -217,7 +219,7 @@ void ChronoTests::testDateTime()
// test now() and exactNow() (or at least whether both behave the same)
#if defined(PLATFORM_UNIX)
const auto delta = DateTime::gmtNow() - DateTime::exactGmtNow();
CPPUNIT_ASSERT(delta < TimeSpan::fromSeconds(2) && delta > TimeSpan::fromSeconds(-2));
CPPUNIT_ASSERT(delta < TimeSpan::fromSeconds(2.0) && delta > TimeSpan::fromSeconds(-2.0));
#endif
}
@ -230,7 +232,7 @@ void ChronoTests::testTimeSpan()
CPPUNIT_ASSERT_EQUAL(TimeSpan(), TimeSpan::fromString(string()));
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(5.0), TimeSpan::fromString("5.0"));
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromMinutes(5.5), TimeSpan::fromString("5:30"));
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(7) + TimeSpan::fromMinutes(5.5), TimeSpan::fromString("7:5:30"));
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(7.0) + TimeSpan::fromMinutes(5.5), TimeSpan::fromString("7:5:30"));
const auto test1 = TimeSpan::fromString("2:34:53:2.5");
// test days(), hours(), ...
CPPUNIT_ASSERT_EQUAL(3, test1.days());
@ -243,7 +245,7 @@ void ChronoTests::testTimeSpan()
CPPUNIT_ASSERT(test1.totalMinutes() > (2 * 24 * 60 + 34 * 60 + 53) && test1.totalHours() < (2 * 24 * 60 + 34 * 60 + 54));
// test toString(...)
CPPUNIT_ASSERT_EQUAL("3 d 10 h 53 min 2 s 500 ms"s, test1.toString(TimeSpanOutputFormat::WithMeasures, false));
CPPUNIT_ASSERT_EQUAL("07:05:30"s, (TimeSpan::fromHours(7) + TimeSpan::fromMinutes(5.5)).toString());
CPPUNIT_ASSERT_EQUAL("07:05:30"s, (TimeSpan::fromHours(7.0) + TimeSpan::fromMinutes(5.5)).toString());
CPPUNIT_ASSERT_EQUAL("-5 s"s, TimeSpan::fromSeconds(-5.0).toString(TimeSpanOutputFormat::WithMeasures, false));
CPPUNIT_ASSERT_EQUAL("0 s"s, TimeSpan().toString(TimeSpanOutputFormat::WithMeasures, false));
CPPUNIT_ASSERT_EQUAL("5e+02 µs"s, TimeSpan::fromMilliseconds(0.5).toString(TimeSpanOutputFormat::WithMeasures, false));
@ -268,16 +270,18 @@ void ChronoTests::testTimeSpan()
void ChronoTests::testOperators()
{
auto dateTime = DateTime::fromDateAndTime(1999, 1, 5, 4, 16);
CPPUNIT_ASSERT_EQUAL(7, (dateTime + TimeSpan::fromDays(2)).day());
CPPUNIT_ASSERT_EQUAL(6, (dateTime + TimeSpan::fromHours(24)).day());
CPPUNIT_ASSERT_EQUAL(3, (dateTime + TimeSpan::fromHours(24) + TimeSpan::fromHours(-1)).hour());
CPPUNIT_ASSERT_EQUAL(17, (dateTime + TimeSpan::fromHours(24) - TimeSpan::fromMinutes(-1)).minute());
dateTime += TimeSpan::fromDays(365);
CPPUNIT_ASSERT_EQUAL(7, (dateTime + TimeSpan::fromDays(2.0)).day());
CPPUNIT_ASSERT_EQUAL(6, (dateTime + TimeSpan::fromHours(24.0)).day());
CPPUNIT_ASSERT_EQUAL(3, (dateTime + TimeSpan::fromHours(24.0) + TimeSpan::fromHours(-1.0)).hour());
CPPUNIT_ASSERT_EQUAL(17, (dateTime + TimeSpan::fromHours(24.0) - TimeSpan::fromMinutes(-1.0)).minute());
dateTime += TimeSpan::fromDays(365.0);
CPPUNIT_ASSERT_EQUAL(2000, dateTime.year());
CPPUNIT_ASSERT_EQUAL(5, dateTime.day());
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromDays(1), TimeSpan::fromHours(12) * 2);
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(12), TimeSpan::fromDays(1) / 2);
CPPUNIT_ASSERT_EQUAL(2.0, TimeSpan::fromDays(1) / TimeSpan::fromHours(12));
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromDays(1.0), TimeSpan::fromHours(12.0) * 2.0);
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(12.0), TimeSpan::fromDays(1.0) / 2.0);
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromDays(1.0), TimeSpan::fromHours(12.0) * TimeSpan::TickType(2));
CPPUNIT_ASSERT_EQUAL(TimeSpan::fromHours(12.0), TimeSpan::fromDays(1.0) / TimeSpan::TickType(2));
CPPUNIT_ASSERT_EQUAL(2.0, TimeSpan::fromDays(1.0) / TimeSpan::fromHours(12.0));
}
/*!
@ -312,8 +316,8 @@ void ChronoTests::testHashing()
CPPUNIT_ASSERT_EQUAL(2_st, dateTimes.size());
set<TimeSpan> timeSpans;
timeSpans.emplace(TimeSpan::fromDays(5));
timeSpans.emplace(TimeSpan::fromDays(10));
timeSpans.emplace(TimeSpan::fromDays(5));
timeSpans.emplace(TimeSpan::fromDays(5.0));
timeSpans.emplace(TimeSpan::fromDays(10.0));
timeSpans.emplace(TimeSpan::fromDays(5.0));
CPPUNIT_ASSERT_EQUAL(2_st, timeSpans.size());
}