Improve chrono utils
- Support parsing/generating ISO time stamp with time zone delta - Fix minor bugs - Improve tests
This commit is contained in:
parent
d6b08b8ed9
commit
12588c6928
|
@ -10,6 +10,7 @@ set(HEADER_FILES
|
||||||
chrono/datetime.h
|
chrono/datetime.h
|
||||||
chrono/period.h
|
chrono/period.h
|
||||||
chrono/timespan.h
|
chrono/timespan.h
|
||||||
|
chrono/format.h
|
||||||
conversion/binaryconversion.h
|
conversion/binaryconversion.h
|
||||||
conversion/binaryconversionprivate.h
|
conversion/binaryconversionprivate.h
|
||||||
conversion/conversionexception.h
|
conversion/conversionexception.h
|
||||||
|
|
|
@ -76,30 +76,109 @@ DateTime DateTime::fromTimeStampGmt(time_t timeStamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Parses the given std::string \a str as DateTime.
|
* \brief Parses the given C-style string as DateTime.
|
||||||
*/
|
*/
|
||||||
DateTime DateTime::fromString(const string &str)
|
DateTime DateTime::fromString(const char *str)
|
||||||
{
|
{
|
||||||
int values[7] = {0};
|
int values[6] = {0};
|
||||||
int *i = values;
|
int *const dayIndex = values + 2;
|
||||||
for(const auto &c : str) {
|
int *const secondsIndex = values + 5;
|
||||||
if(c >= '1' || c <= '0') {
|
int *valueIndex = values;
|
||||||
*i *= 10;
|
int *const valuesEnd = values + 7;
|
||||||
*i += c - '1';
|
double miliSecondsFact = 100.0, miliSeconds = 0.0;
|
||||||
} else if((c == '-' || c == ':' || c == '/') || (c == '.' && (i == values + 5))) {
|
for(const char *strIndex = str; ; ++strIndex) {
|
||||||
++i;
|
const char c = *strIndex;
|
||||||
|
if(c <= '9' && c >= '0') {
|
||||||
|
if(valueIndex > secondsIndex) {
|
||||||
|
miliSeconds += (c - '0') * miliSecondsFact;
|
||||||
|
miliSecondsFact /= 10;
|
||||||
} else {
|
} else {
|
||||||
throw ConversionException(string("string contains unexpected character ") + c);
|
*valueIndex *= 10;
|
||||||
|
*valueIndex += c - '0';
|
||||||
|
}
|
||||||
|
} else if((c == '-' || c == ':' || c == '/') || (c == '.' && (valueIndex == secondsIndex)) || (c == ' ' && (valueIndex == dayIndex))) {
|
||||||
|
if(++valueIndex == valuesEnd) {
|
||||||
|
break; // just ignore further values for now
|
||||||
|
}
|
||||||
|
} else if(c == '\0') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw ConversionException(string("unexpected ") + c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DateTime::fromDateAndTime(values[0], values[1], values[2], values[3], values[4], values[5], 100.0 * values[6]);
|
return DateTime::fromDateAndTime(values[0], values[1], *dayIndex, values[3], values[4], *secondsIndex, miliSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Converts the value of the current DateTime object to its equivalent std::string representation
|
* \brief Parses the given ISO date time denotation provided as C-style string.
|
||||||
* according the given \a format.
|
* \returns Returns a pair where the first value is the parsed UTC DateTime and the second value
|
||||||
*
|
* a TimeSpan which can be added to the first value to get the local DateTime.
|
||||||
* If \a noMilliseconds is true the date will be rounded to full seconds.
|
* \remarks Not sure whether it is actually ISO conform, but it parses denotations like
|
||||||
|
* "2016-08-29T21:32:31.588539814+02:00".
|
||||||
|
*/
|
||||||
|
std::pair<DateTime, TimeSpan> DateTime::fromIsoString(const char *str)
|
||||||
|
{
|
||||||
|
int values[9] = {0};
|
||||||
|
int *const dayIndex = values + 2;
|
||||||
|
int *const hourIndex = values + 3;
|
||||||
|
int *const secondsIndex = values + 5;
|
||||||
|
int *const miliSecondsIndex = values + 6;
|
||||||
|
int *const deltaHourIndex = values + 7;
|
||||||
|
int *valueIndex = values;
|
||||||
|
bool deltaNegative = false;
|
||||||
|
double miliSecondsFact = 100.0, miliSeconds = 0.0;
|
||||||
|
for(const char *strIndex = str; ; ++strIndex) {
|
||||||
|
const char c = *strIndex;
|
||||||
|
if(c <= '9' && c >= '0') {
|
||||||
|
if(valueIndex == miliSecondsIndex) {
|
||||||
|
miliSeconds += (c - '0') * miliSecondsFact;
|
||||||
|
miliSecondsFact /= 10;
|
||||||
|
} else {
|
||||||
|
*valueIndex *= 10;
|
||||||
|
*valueIndex += c - '0';
|
||||||
|
}
|
||||||
|
} else if(c == 'T') {
|
||||||
|
if(++valueIndex != hourIndex) {
|
||||||
|
throw ConversionException("\"T\" expected before hour");
|
||||||
|
}
|
||||||
|
} else if(c == '-') {
|
||||||
|
if(valueIndex < dayIndex) {
|
||||||
|
++valueIndex;
|
||||||
|
} else {
|
||||||
|
throw ConversionException("unexpected \"-\" after day");
|
||||||
|
}
|
||||||
|
} else if(c == '.') {
|
||||||
|
if(valueIndex != secondsIndex) {
|
||||||
|
throw ConversionException("unexpected \".\"");
|
||||||
|
} else {
|
||||||
|
++valueIndex;
|
||||||
|
}
|
||||||
|
} else if(c == ':') {
|
||||||
|
if(valueIndex < hourIndex) {
|
||||||
|
throw ConversionException("unexpected \":\" before hour");
|
||||||
|
} else if(valueIndex == secondsIndex) {
|
||||||
|
throw ConversionException("unexpected \":\" after second");
|
||||||
|
} else {
|
||||||
|
++valueIndex;
|
||||||
|
}
|
||||||
|
} else if((c == '+') && (++valueIndex == deltaHourIndex)) {
|
||||||
|
deltaNegative = false;
|
||||||
|
} else if((c == '-') && (++valueIndex == deltaHourIndex)) {
|
||||||
|
deltaNegative = true;
|
||||||
|
} else if(c == '\0') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw ConversionException(string("unexpected \"") + c + '\"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deltaNegative && (*deltaHourIndex = -*deltaHourIndex);
|
||||||
|
return make_pair(DateTime::fromDateAndTime(values[0], values[1], *dayIndex, *hourIndex, values[4], *secondsIndex, miliSeconds), TimeSpan::fromMinutes(*deltaHourIndex * 60 + values[8]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the string representation of the current instance using the specified \a format.
|
||||||
|
* \remarks If \a noMilliseconds is true the date will be rounded to full seconds.
|
||||||
|
* \sa toIsoString() for ISO format
|
||||||
*/
|
*/
|
||||||
string DateTime::toString(DateTimeOutputFormat format, bool noMilliseconds) const
|
string DateTime::toString(DateTimeOutputFormat format, bool noMilliseconds) const
|
||||||
{
|
{
|
||||||
|
@ -109,10 +188,9 @@ string DateTime::toString(DateTimeOutputFormat format, bool noMilliseconds) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Converts the value of the current DateTime object to its equivalent std::string representation
|
* \brief Returns the string representation of the current instance using the specified \a format.
|
||||||
* according the given \a format.
|
* \remarks If \a noMilliseconds is true the date will be rounded to full seconds.
|
||||||
*
|
* \sa toIsoString() for ISO format
|
||||||
* If \a noMilliseconds is true the date will be rounded to full seconds.
|
|
||||||
*/
|
*/
|
||||||
void DateTime::toString(string &result, DateTimeOutputFormat format, bool noMilliseconds) const
|
void DateTime::toString(string &result, DateTimeOutputFormat format, bool noMilliseconds) const
|
||||||
{
|
{
|
||||||
|
@ -120,12 +198,12 @@ void DateTime::toString(string &result, DateTimeOutputFormat format, bool noMill
|
||||||
s << setfill('0');
|
s << setfill('0');
|
||||||
if(format == DateTimeOutputFormat::DateTimeAndWeekday
|
if(format == DateTimeOutputFormat::DateTimeAndWeekday
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|
||||||
s << printDayOfWeek(dayOfWeek(), format == DateTimeOutputFormat::DateTimeAndShortWeekday) << " ";
|
s << printDayOfWeek(dayOfWeek(), format == DateTimeOutputFormat::DateTimeAndShortWeekday) << ' ';
|
||||||
if(format == DateTimeOutputFormat::DateOnly
|
if(format == DateTimeOutputFormat::DateOnly
|
||||||
|| format == DateTimeOutputFormat::DateAndTime
|
|| format == DateTimeOutputFormat::DateAndTime
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|
||||||
s << setw(4) << year() << "-" << setw(2) << month() << "-" << setw(2) << day();
|
s << setw(4) << year() << '-' << setw(2) << month() << '-' << setw(2) << day();
|
||||||
if(format == DateTimeOutputFormat::DateAndTime
|
if(format == DateTimeOutputFormat::DateAndTime
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday)
|
||||||
|
@ -134,15 +212,32 @@ void DateTime::toString(string &result, DateTimeOutputFormat format, bool noMill
|
||||||
|| format == DateTimeOutputFormat::DateAndTime
|
|| format == DateTimeOutputFormat::DateAndTime
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|
|| format == DateTimeOutputFormat::DateTimeAndWeekday
|
||||||
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday) {
|
|| format == DateTimeOutputFormat::DateTimeAndShortWeekday) {
|
||||||
s << setw(2) << hour() << ":" << setw(2) << minute() << ":" << setw(2) << second();
|
s << setw(2) << hour() << ':' << setw(2) << minute() << ':' << setw(2) << second();
|
||||||
int ms = millisecond();
|
int ms = millisecond();
|
||||||
if(!noMilliseconds && ms > 0) {
|
if(!noMilliseconds && ms > 0) {
|
||||||
s << "." << ms;
|
s << '.' << setw(3) << ms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = s.str();
|
result = s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the string representation of the current instance in the ISO format,
|
||||||
|
* eg. 2016-08-29T21:32:31.588539814+02:00.
|
||||||
|
*/
|
||||||
|
string DateTime::toIsoString(TimeSpan timeZoneDelta) const
|
||||||
|
{
|
||||||
|
stringstream s(stringstream::in | stringstream::out);
|
||||||
|
s << setfill('0');
|
||||||
|
s << setw(4) << year() << '-' << setw(2) << month() << '-' << setw(2) << day()
|
||||||
|
<< 'T' << setw(2) << hour() << ':' << setw(2) << minute() << ':' << setw(2) << second() << '.' << setw(3) << millisecond();
|
||||||
|
if(!timeZoneDelta.isNull()) {
|
||||||
|
s << (timeZoneDelta.isNegative() ? '-' : '+');
|
||||||
|
s << setw(2) << timeZoneDelta.hours() << ':' << setw(2) << timeZoneDelta.minutes();
|
||||||
|
}
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the string representation as C-style string for the given day of week.
|
* \brief Returns the string representation as C-style string for the given day of week.
|
||||||
*
|
*
|
||||||
|
|
|
@ -61,6 +61,8 @@ public:
|
||||||
static DateTime fromTime(int hour = 0, int minute = 0, int second = 0, double millisecond = 0.0);
|
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);
|
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);
|
||||||
static DateTime fromString(const std::string &str);
|
static DateTime fromString(const std::string &str);
|
||||||
|
static DateTime fromString(const char *str);
|
||||||
|
static std::pair<DateTime, TimeSpan> fromIsoString(const char *str);
|
||||||
static DateTime fromTimeStamp(time_t timeStamp);
|
static DateTime fromTimeStamp(time_t timeStamp);
|
||||||
static DateTime fromTimeStampGmt(time_t timeStamp);
|
static DateTime fromTimeStampGmt(time_t timeStamp);
|
||||||
|
|
||||||
|
@ -81,6 +83,7 @@ public:
|
||||||
constexpr bool isSameDay(const DateTime &other) const;
|
constexpr bool isSameDay(const DateTime &other) const;
|
||||||
std::string toString(DateTimeOutputFormat format = DateTimeOutputFormat::DateAndTime, bool noMilliseconds = false) const;
|
std::string toString(DateTimeOutputFormat format = DateTimeOutputFormat::DateAndTime, bool noMilliseconds = false) const;
|
||||||
void toString(std::string &result, DateTimeOutputFormat format = DateTimeOutputFormat::DateAndTime, bool noMilliseconds = false) const;
|
void toString(std::string &result, DateTimeOutputFormat format = DateTimeOutputFormat::DateAndTime, bool noMilliseconds = false) const;
|
||||||
|
std::string toIsoString(TimeSpan delta) const;
|
||||||
static const char *printDayOfWeek(DayOfWeek dayOfWeek, bool abbreviation = false);
|
static const char *printDayOfWeek(DayOfWeek dayOfWeek, bool abbreviation = false);
|
||||||
|
|
||||||
static constexpr DateTime eternity();
|
static constexpr DateTime eternity();
|
||||||
|
@ -121,6 +124,8 @@ private:
|
||||||
static const int m_daysInMonth366[12];
|
static const int m_daysInMonth366[12];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a DateTime.
|
* \brief Constructs a DateTime.
|
||||||
*/
|
*/
|
||||||
|
@ -162,6 +167,14 @@ inline DateTime DateTime::fromDateAndTime(int year, int month, int day, int hour
|
||||||
return DateTime();
|
return DateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Parses the given std::string as DateTime.
|
||||||
|
*/
|
||||||
|
inline DateTime DateTime::fromString(const std::string &str)
|
||||||
|
{
|
||||||
|
return fromString(str.data());
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the number of ticks which represent the value of the current instance.
|
* \brief Gets the number of ticks which represent the value of the current instance.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef CHRONO_FORMAT_H
|
||||||
|
#define CHRONO_FORMAT_H
|
||||||
|
|
||||||
|
#include "./datetime.h"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
inline std::ostream &operator<< (std::ostream &out, const ChronoUtilities::DateTime &value)
|
||||||
|
{
|
||||||
|
return out << value.toString(ChronoUtilities::DateTimeOutputFormat::DateAndTime, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<< (std::ostream &out, const ChronoUtilities::TimeSpan &value)
|
||||||
|
{
|
||||||
|
return out << value.toString(ChronoUtilities::TimeSpanOutputFormat::Normal, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CHRONO_FORMAT_H
|
|
@ -18,32 +18,29 @@ using namespace ConversionUtilities;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Parses the given std::string \a str as TimeSpan.
|
* \brief Parses the given C-style string as TimeSpan.
|
||||||
*/
|
*/
|
||||||
TimeSpan TimeSpan::fromString(const string &str)
|
TimeSpan TimeSpan::fromString(const char *str, char separator)
|
||||||
{
|
|
||||||
return TimeSpan::fromString(str, ':');
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Parses the given std::string \a str as TimeSpan.
|
|
||||||
*/
|
|
||||||
TimeSpan TimeSpan::fromString(const string &str, char separator)
|
|
||||||
{
|
{
|
||||||
vector<double> parts;
|
vector<double> parts;
|
||||||
string::size_type start = 0;
|
size_t partsSize = 1;
|
||||||
string::size_type end = str.find(separator, start);
|
for(const char *i = str; *i; ++i) {
|
||||||
while(true) {
|
*i == separator && ++partsSize;
|
||||||
parts.push_back(stringToNumber<double>(str.substr(start, end - start)));
|
}
|
||||||
if(end == string::npos) {
|
parts.reserve(partsSize);
|
||||||
|
|
||||||
|
for(const char *i = str; ;) {
|
||||||
|
if(*i == separator) {
|
||||||
|
parts.emplace_back(stringToNumber<double>(string(str, i)));
|
||||||
|
str = ++i;
|
||||||
|
} else if(*i == '\0') {
|
||||||
|
parts.emplace_back(stringToNumber<double>(string(str, i)));
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
start = end + 1;
|
|
||||||
if(start >= str.size()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
end = str.find(separator, start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(parts.size()) {
|
switch(parts.size()) {
|
||||||
case 0:
|
case 0:
|
||||||
return TimeSpan();
|
return TimeSpan();
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
static constexpr TimeSpan fromMinutes(double minutes);
|
static constexpr TimeSpan fromMinutes(double minutes);
|
||||||
static constexpr TimeSpan fromHours(double hours);
|
static constexpr TimeSpan fromHours(double hours);
|
||||||
static constexpr TimeSpan fromDays(double days);
|
static constexpr TimeSpan fromDays(double days);
|
||||||
static TimeSpan fromString(const std::string &str);
|
static TimeSpan fromString(const std::string &str, char separator = ':');
|
||||||
static TimeSpan fromString(const std::string &str, char separator);
|
static TimeSpan fromString(const char *str, char separator);
|
||||||
static constexpr TimeSpan negativeInfinity();
|
static constexpr TimeSpan negativeInfinity();
|
||||||
static constexpr TimeSpan infinity();
|
static constexpr TimeSpan infinity();
|
||||||
|
|
||||||
|
@ -134,6 +134,14 @@ constexpr inline TimeSpan TimeSpan::fromDays(double days)
|
||||||
return TimeSpan(static_cast<int64>(days * static_cast<double>(m_ticksPerDay)));
|
return TimeSpan(static_cast<int64>(days * static_cast<double>(m_ticksPerDay)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Parses the given std::string as TimeSpan.
|
||||||
|
*/
|
||||||
|
inline TimeSpan TimeSpan::fromString(const std::string &str, char separator)
|
||||||
|
{
|
||||||
|
return TimeSpan::fromString(str.data(), separator);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new instace of the TimeSpan class with the minimal number of ticks.
|
* \brief Constructs a new instace of the TimeSpan class with the minimal number of ticks.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../chrono/datetime.h"
|
#include "../chrono/datetime.h"
|
||||||
#include "../chrono/timespan.h"
|
#include "../chrono/timespan.h"
|
||||||
#include "../chrono/period.h"
|
#include "../chrono/period.h"
|
||||||
|
#include "../chrono/format.h"
|
||||||
#include "../conversion/conversionexception.h"
|
#include "../conversion/conversionexception.h"
|
||||||
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
@ -42,20 +43,20 @@ CPPUNIT_TEST_SUITE_REGISTRATION(ChronoTests);
|
||||||
void ChronoTests::testDateTime()
|
void ChronoTests::testDateTime()
|
||||||
{
|
{
|
||||||
// test year(), month(), ...
|
// test year(), month(), ...
|
||||||
auto test1 = DateTime::fromDateAndTime(2012, 2, 29, 15, 34, 20, 33.0);
|
const auto test1 = DateTime::fromDateAndTime(2012, 2, 29, 15, 34, 20, 33.0);
|
||||||
CPPUNIT_ASSERT(test1.year() == 2012);
|
CPPUNIT_ASSERT_EQUAL(2012, test1.year());
|
||||||
CPPUNIT_ASSERT(test1.month() == 2);
|
CPPUNIT_ASSERT_EQUAL(2, test1.month());
|
||||||
CPPUNIT_ASSERT(test1.day() == 29);
|
CPPUNIT_ASSERT_EQUAL(29, test1.day());
|
||||||
CPPUNIT_ASSERT(test1.minute() == 34);
|
CPPUNIT_ASSERT_EQUAL(34, test1.minute());
|
||||||
CPPUNIT_ASSERT(test1.second() == 20);
|
CPPUNIT_ASSERT_EQUAL(20, test1.second());
|
||||||
CPPUNIT_ASSERT(test1.millisecond() == 33);
|
CPPUNIT_ASSERT_EQUAL(33, test1.millisecond());
|
||||||
CPPUNIT_ASSERT(test1.dayOfWeek() == DayOfWeek::Wednesday);
|
CPPUNIT_ASSERT(test1.dayOfWeek() == DayOfWeek::Wednesday);
|
||||||
CPPUNIT_ASSERT(test1.dayOfYear() == (31 + 29));
|
CPPUNIT_ASSERT_EQUAL((31 + 29), test1.dayOfYear());
|
||||||
CPPUNIT_ASSERT(test1.isLeapYear());
|
CPPUNIT_ASSERT(test1.isLeapYear());
|
||||||
CPPUNIT_ASSERT(test1.toString(DateTimeOutputFormat::DateTimeAndShortWeekday) == "Wed 2012-02-29 15:34:20.33");
|
CPPUNIT_ASSERT_EQUAL(string("Wed 2012-02-29 15:34:20.033"), test1.toString(DateTimeOutputFormat::DateTimeAndShortWeekday));
|
||||||
|
|
||||||
// test fromTimeStamp()
|
// test fromTimeStamp()
|
||||||
auto test2 = DateTime::fromTimeStampGmt(1453840331);
|
const auto test2 = DateTime::fromTimeStampGmt(1453840331);
|
||||||
CPPUNIT_ASSERT(test2.toString(DateTimeOutputFormat::DateTimeAndShortWeekday) == "Tue 2016-01-26 20:32:11");
|
CPPUNIT_ASSERT(test2.toString(DateTimeOutputFormat::DateTimeAndShortWeekday) == "Tue 2016-01-26 20:32:11");
|
||||||
|
|
||||||
// test whether ConversionException() is thrown when invalid values are specified
|
// test whether ConversionException() is thrown when invalid values are specified
|
||||||
|
@ -63,6 +64,13 @@ void ChronoTests::testDateTime()
|
||||||
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 2, 29, 15, 61, 20, 33), ConversionException);
|
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 2, 29, 15, 61, 20, 33), ConversionException);
|
||||||
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 4, 31, 15, 0, 20, 33), ConversionException);
|
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 4, 31, 15, 0, 20, 33), ConversionException);
|
||||||
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 3, 31, 15, 0, 61, 33), ConversionException);
|
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 3, 31, 15, 0, 61, 33), ConversionException);
|
||||||
|
|
||||||
|
// test fromString()/toString()
|
||||||
|
CPPUNIT_ASSERT_EQUAL(test1, DateTime::fromString("2012-02-29 15:34:20.033"));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(string("2012-02-29 15:34:20.033"), test1.toString(DateTimeOutputFormat::DateAndTime, false));
|
||||||
|
CPPUNIT_ASSERT_THROW(TimeSpan::fromString("2012-02-29 15:34:34:20.033"), ConversionException);
|
||||||
|
const auto test3 = DateTime::fromIsoString("2016-08-29T21:32:31.125+02:00");
|
||||||
|
CPPUNIT_ASSERT_EQUAL(string("2016-08-29T21:32:31.125+02:00"), test3.first.toIsoString(test3.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Reference in New Issue