Add conversion from RFC3339 string to DateTime
authorMikko Rasa <tdb@tdb.fi>
Sun, 24 Jul 2016 14:24:01 +0000 (17:24 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 24 Jul 2016 14:24:01 +0000 (17:24 +0300)
source/time/datetime.cpp
source/time/datetime.h

index c77796f7bc0bd8c8cd378d739fb5a458f006a491..26bd7cdb7d59925a0caf076b22dab059e8498a60 100644 (file)
@@ -1,6 +1,7 @@
 #include <cstdlib>
 #include <stdexcept>
 #include <msp/strings/format.h>
+#include <msp/strings/regex.h>
 #include "datetime.h"
 #include "timestamp.h"
 
@@ -104,6 +105,36 @@ void DateTime::init(int y, unsigned char m, unsigned char d, unsigned char h, un
                throw out_of_range("DateTime::DateTime mday");
 }
 
+DateTime DateTime::parse_rfc3339(const string &str)
+{
+       static Regex re("^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[-+]([0-9]{2}):([0-9]{2}))$");
+
+       RegMatch m = re.match(str);
+       if(!m)
+               throw invalid_argument("DateTime::parse_rfc3339");
+
+       unsigned year = lexical_cast<unsigned>(m[1].str);
+       unsigned month = lexical_cast<unsigned>(m[2].str);
+       unsigned mday = lexical_cast<unsigned>(m[3].str);
+       unsigned hr = lexical_cast<unsigned>(m[4].str);
+       unsigned minute = lexical_cast<unsigned>(m[5].str);
+       unsigned second = lexical_cast<unsigned>(m[6].str);
+
+       DateTime result = DateTime(year, month, mday, hr, minute, second);
+
+       int tzoff = 0;
+       if(m[7].str!="Z")
+       {
+               tzoff = lexical_cast<unsigned>(m[8].str)*60+lexical_cast<unsigned>(m[9].str);
+               if(m[7].str[0]=='-')
+                       tzoff = -tzoff;
+       }
+
+       result.set_timezone(tzoff);
+
+       return result;
+}
+
 void DateTime::add_days(int days)
 {
        int new_year = year;
index f065d3219e7f679d3741bf03dad4f2680d06a30d..b7f578cd9f71326ae510c0780c8714f195aa684d 100644 (file)
@@ -43,6 +43,8 @@ private:
        void init(int, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned);
 
 public:
+       static DateTime parse_rfc3339(const std::string &);
+
        int get_year() const { return year; }
        unsigned char get_month() const { return month; }
        unsigned char get_mday() const { return mday; }
@@ -80,6 +82,9 @@ private:
 inline void operator<<(LexicalConverter &c, const DateTime &d)
 { c.result(d.format_rfc3339()); }
 
+inline void operator>>(const LexicalConverter &c, DateTime &d)
+{ d = DateTime::parse_rfc3339(c.get()); }
+
 } // namespace Time
 } // namespace Msp