Add useful operators to `DateTimeExpression`
* Add serialization back to string, useful for implementing `TagValue::toString()` * Add equality comparition
This commit is contained in:
parent
4911d16129
commit
5acf422f71
|
@ -528,4 +528,78 @@ DateTimeExpression DateTimeExpression::fromString(const char *str)
|
|||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the string representation of the current instance in the ISO format.
|
||||
* \remarks Only present parts will be included.
|
||||
*/
|
||||
std::string DateTimeExpression::toIsoString(char dateDelimiter, char timeDelimiter, char timeZoneDelimiter) const
|
||||
{
|
||||
auto s = std::stringstream(std::stringstream::in | std::stringstream::out);
|
||||
s << setfill('0');
|
||||
if (parts & DateTimeParts::Year) {
|
||||
s << setw(4) << value.year();
|
||||
}
|
||||
if (parts & DateTimeParts::Month) {
|
||||
if (s.tellp()) {
|
||||
s << dateDelimiter;
|
||||
}
|
||||
s << setw(2) << value.month();
|
||||
}
|
||||
if (parts & DateTimeParts::Day) {
|
||||
if (s.tellp()) {
|
||||
s << dateDelimiter;
|
||||
}
|
||||
s << setw(2) << value.day();
|
||||
}
|
||||
if (parts & DateTimeParts::Hour) {
|
||||
if (s.tellp()) {
|
||||
s << 'T';
|
||||
}
|
||||
s << setw(2) << value.hour();
|
||||
}
|
||||
if (parts & DateTimeParts::Minute) {
|
||||
if (s.tellp()) {
|
||||
s << timeDelimiter;
|
||||
}
|
||||
s << setw(2) << value.minute();
|
||||
}
|
||||
if (parts & DateTimeParts::Second) {
|
||||
if (s.tellp()) {
|
||||
s << timeDelimiter;
|
||||
}
|
||||
s << setw(2) << value.second();
|
||||
}
|
||||
if (parts & DateTimeParts::SubSecond) {
|
||||
const auto milli = value.millisecond();
|
||||
const auto micro = value.microsecond();
|
||||
const auto nano = value.nanosecond();
|
||||
s << '.' << setw(3) << milli;
|
||||
if (micro || nano) {
|
||||
s << setw(3) << micro;
|
||||
if (nano) {
|
||||
s << nano / TimeSpan::nanosecondsPerTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts & DateTimeParts::TimeZoneDelta) {
|
||||
auto d = delta;
|
||||
if (d.isNegative()) {
|
||||
s << '-';
|
||||
d = TimeSpan(-d.totalTicks());
|
||||
} else {
|
||||
s << '+';
|
||||
}
|
||||
if (parts & DateTimeParts::DeltaHour) {
|
||||
s << setw(2) << d.hours();
|
||||
}
|
||||
if (parts & DateTimeParts::DeltaMinute) {
|
||||
if (parts & DateTimeParts::DeltaHour) {
|
||||
s << timeZoneDelimiter;
|
||||
}
|
||||
s << setw(2) << d.minutes();
|
||||
}
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
} // namespace CppUtilities
|
||||
|
|
|
@ -166,6 +166,8 @@ struct CPP_UTILITIES_EXPORT DateTimeExpression {
|
|||
DateTimeParts parts = DateTimeParts::None; /**< The parts present in the expression as flag enum. */
|
||||
|
||||
constexpr DateTime gmt() const;
|
||||
constexpr bool operator==(const DateTimeExpression &other) const;
|
||||
std::string toIsoString(char dateDelimiter = '-', char timeDelimiter = ':', char timeZoneDelimiter = ':') const;
|
||||
static DateTimeExpression fromIsoString(const char *str);
|
||||
static DateTimeExpression fromString(const char *str);
|
||||
};
|
||||
|
@ -178,6 +180,14 @@ constexpr DateTime DateTimeExpression::gmt() const
|
|||
return value - delta;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns whether the expressions are equivalent.
|
||||
*/
|
||||
constexpr bool DateTimeExpression::operator==(const DateTimeExpression &other) const
|
||||
{
|
||||
return value == other.value && delta == other.delta && parts == other.parts;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a DateTime.
|
||||
*/
|
||||
|
|
|
@ -230,44 +230,53 @@ void ChronoTests::testDateTime()
|
|||
*/
|
||||
void ChronoTests::testDateTimeExpression()
|
||||
{
|
||||
// check adding ISO timestamp parts one-by-one
|
||||
// check adding ISO timestamp parts one-by-one and serialization back to string
|
||||
auto expr = DateTimeExpression::fromIsoString("1");
|
||||
auto parts = DateTimeParts::Year;
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::Month, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::Day, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1T0");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::Hour, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01T00"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1T0:0");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::Minute, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01T00:00"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1T0:0:0");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::Second, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01T00:00:00"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1T0:0:0.0");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::SubSecond, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01T00:00:00.000"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1T0:0:0.0+0");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::DeltaHour, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01T00:00:00.000+00"s, expr.toIsoString());
|
||||
expr = DateTimeExpression::fromIsoString("1-1-1T0:0:0.0-0:0");
|
||||
CPPUNIT_ASSERT_EQUAL(DateTime(), expr.value);
|
||||
CPPUNIT_ASSERT_EQUAL(TimeSpan(), expr.delta);
|
||||
CPPUNIT_ASSERT_EQUAL(parts |= DateTimeParts::DeltaMinute, expr.parts);
|
||||
CPPUNIT_ASSERT_EQUAL("0001-01-01T00:00:00.000+00:00"s, expr.toIsoString());
|
||||
|
||||
// check that omitting parts in the middle is not possible anyways
|
||||
CPPUNIT_ASSERT_THROW(DateTimeExpression::fromIsoString("1-1T0"), ConversionException);
|
||||
|
|
Loading…
Reference in New Issue