From 312dc3325b43b092f2a5a634b1c445d32a0d8202 Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Tue, 12 Jun 2018 09:54:35 -0500 Subject: [PATCH] add struct tm support to DateTime #2365 --- Foundation/include/Poco/DateTime.h | 43 ++++++++++++--------- Foundation/src/DateTime.cpp | 46 ++++++++++++++++++++++- Foundation/testsuite/src/DateTimeTest.cpp | 18 +++++++++ Foundation/testsuite/src/DateTimeTest.h | 1 + 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/Foundation/include/Poco/DateTime.h b/Foundation/include/Poco/DateTime.h index ab6989471..1a59a0384 100644 --- a/Foundation/include/Poco/DateTime.h +++ b/Foundation/include/Poco/DateTime.h @@ -23,6 +23,9 @@ #include "Poco/Timespan.h" +struct tm; + + namespace Poco { @@ -86,10 +89,13 @@ public: FRIDAY, SATURDAY }; - + DateTime(); /// Creates a DateTime for the current date and time. + DateTime(const tm& tmStruct); + /// Creates a DateTime from tm struct. + DateTime(const Timestamp& timestamp); /// Creates a DateTime for the date and time given in /// a Timestamp. @@ -206,7 +212,7 @@ public: /// Returns the date and time expressed in UTC-based /// time. UTC base time is midnight, October 15, 1582. /// Resolution is 100 nanoseconds. - + bool operator == (const DateTime& dateTime) const; bool operator != (const DateTime& dateTime) const; bool operator < (const DateTime& dateTime) const; @@ -219,28 +225,31 @@ public: Timespan operator - (const DateTime& dateTime) const; DateTime& operator += (const Timespan& span); DateTime& operator -= (const Timespan& span); - + + tm makeTM() const; + /// Converts DateTime to tm struct. + void makeUTC(int tzd); /// Converts a local time into UTC, by applying the given time zone differential. - + void makeLocal(int tzd); /// Converts a UTC time into a local time, by applying the given time zone differential. - + static bool isLeapYear(int year); /// Returns true if the given year is a leap year; /// false otherwise. - + static int daysOfMonth(int year, int month); /// Returns the number of days in the given month /// and year. Month is from 1 to 12. - + static bool isValid(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0); /// Checks if the given date and time is valid /// (all arguments are within a proper range). /// /// Returns true if all arguments are valid, false otherwise. - -protected: + +protected: static double toJulianDay(Timestamp::UtcTimeVal utcTime); /// Computes the Julian day for an UTC time. @@ -264,14 +273,14 @@ private: ///utility functions used to correct the overflow in computeGregorian Timestamp::UtcTimeVal _utcTime; - short _year; - short _month; - short _day; - short _hour; - short _minute; - short _second; - short _millisecond; - short _microsecond; + short _year; + short _month; + short _day; + short _hour; + short _minute; + short _second; + short _millisecond; + short _microsecond; }; diff --git a/Foundation/src/DateTime.cpp b/Foundation/src/DateTime.cpp index 7c17acefa..dda9169d5 100644 --- a/Foundation/src/DateTime.cpp +++ b/Foundation/src/DateTime.cpp @@ -16,6 +16,7 @@ #include "Poco/Timespan.h" #include #include +#include namespace Poco { @@ -43,6 +44,27 @@ DateTime::DateTime() } +DateTime::DateTime(const tm& tmStruct): + _year(tmStruct.tm_year + 1900), + _month(tmStruct.tm_mon + 1), + _day(tmStruct.tm_mday), + _hour(tmStruct.tm_hour), + _minute(tmStruct.tm_min), + _second(tmStruct.tm_sec), + _millisecond(0), + _microsecond(0) +{ + poco_assert (_year >= 0 && _year <= 9999); + poco_assert (_month >= 1 && _month <= 12); + poco_assert (_day >= 1 && _day <= daysOfMonth(_year, _month)); + poco_assert (_hour >= 0 && _hour <= 23); + poco_assert (_minute >= 0 && _minute <= 59); + poco_assert (_second >= 0 && _second <= 60); + + _utcTime = toUtcTime(toJulianDay(_year, _month, _day)) + 10*(_hour*Timespan::HOURS + _minute*Timespan::MINUTES + _second*Timespan::SECONDS); +} + + DateTime::DateTime(const Timestamp& timestamp): _utcTime(timestamp.utcTime()) { @@ -50,7 +72,7 @@ DateTime::DateTime(const Timestamp& timestamp): computeDaytime(); } - + DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond): _year(year), _month(month), @@ -284,6 +306,28 @@ DateTime& DateTime::operator -= (const Timespan& span) } +tm DateTime::makeTM() const +{ + tm tmStruct; + + tmStruct.tm_sec = _second; + tmStruct.tm_min = _minute; + tmStruct.tm_hour = _hour; + tmStruct.tm_mday = _day; + poco_assert (_month > 0); + tmStruct.tm_mon = _month - 1; + poco_assert (_year >= 1900); + tmStruct.tm_year = _year - 1900; + tmStruct.tm_wday = dayOfWeek(); + int doy = dayOfYear(); + poco_assert (_year >0); + tmStruct.tm_yday = doy - 1; + tmStruct.tm_isdst = -1; + + return tmStruct; +} + + void DateTime::makeUTC(int tzd) { operator -= (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS)); diff --git a/Foundation/testsuite/src/DateTimeTest.cpp b/Foundation/testsuite/src/DateTimeTest.cpp index 0d5cfca2e..4b946bdd6 100644 --- a/Foundation/testsuite/src/DateTimeTest.cpp +++ b/Foundation/testsuite/src/DateTimeTest.cpp @@ -854,6 +854,23 @@ void DateTimeTest::testLeapSeconds() } +void DateTimeTest::testTM() +{ + time_t now; + time(&now); + tm* pTM = gmtime(&now); + DateTime dt(*pTM); + assertTrue (dt.second() == pTM->tm_sec); + assertTrue (dt.minute() == pTM->tm_min); + assertTrue (dt.hour() == pTM->tm_hour); + assertTrue (dt.day() == pTM->tm_mday); + assertTrue (dt.month() == pTM->tm_mon + 1); + assertTrue (dt.year() == pTM->tm_year + 1900); + assertTrue (dt.dayOfWeek() == pTM->tm_wday); + assertTrue (dt.dayOfYear() == pTM->tm_yday + 1); +} + + void DateTimeTest::setUp() { } @@ -886,6 +903,7 @@ CppUnit::Test* DateTimeTest::suite() CppUnit_addTest(pSuite, DateTimeTest, testIncrementDecrement); CppUnit_addTest(pSuite, DateTimeTest, testUTC); CppUnit_addTest(pSuite, DateTimeTest, testLeapSeconds); + CppUnit_addTest(pSuite, DateTimeTest, testTM); return pSuite; } diff --git a/Foundation/testsuite/src/DateTimeTest.h b/Foundation/testsuite/src/DateTimeTest.h index ce5194220..6c62a564b 100644 --- a/Foundation/testsuite/src/DateTimeTest.h +++ b/Foundation/testsuite/src/DateTimeTest.h @@ -41,6 +41,7 @@ public: void testIncrementDecrement(); void testUTC(); void testLeapSeconds(); + void testTM(); void setUp(); void tearDown();