From 2b6b7d97cb2b68c72299dcedc2dc986e775c8953 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 29 Oct 2016 00:41:01 +0300 Subject: [PATCH] Add microsecond precision to RFC 3339 dates --- source/time/datetime.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/source/time/datetime.cpp b/source/time/datetime.cpp index 26bd7cd..e8170cc 100644 --- a/source/time/datetime.cpp +++ b/source/time/datetime.cpp @@ -107,7 +107,7 @@ void DateTime::init(int y, unsigned char m, unsigned char d, unsigned char h, un 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}))$"); + static Regex re("^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(.([0-9]+))?(Z|[-+]([0-9]{2}):([0-9]{2}))$"); RegMatch m = re.match(str); if(!m) @@ -119,14 +119,24 @@ DateTime DateTime::parse_rfc3339(const string &str) unsigned hr = lexical_cast(m[4].str); unsigned minute = lexical_cast(m[5].str); unsigned second = lexical_cast(m[6].str); + unsigned us = 0; + const string &sec_frac = m[8].str; + if(!sec_frac.empty()) + { + us = lexical_cast(sec_frac); + for(unsigned i=sec_frac.size(); i<6; ++i) + us *= 10; + for(unsigned i=sec_frac.size(); i>6; --i) + us /= 10; + } - DateTime result = DateTime(year, month, mday, hr, minute, second); + DateTime result = DateTime(year, month, mday, hr, minute, second, us); int tzoff = 0; - if(m[7].str!="Z") + if(m[9].str!="Z") { - tzoff = lexical_cast(m[8].str)*60+lexical_cast(m[9].str); - if(m[7].str[0]=='-') + tzoff = lexical_cast(m[10].str)*60+lexical_cast(m[11].str); + if(m[9].str[0]=='-') tzoff = -tzoff; } @@ -316,6 +326,8 @@ string DateTime::format(const string &fmt) const string DateTime::format_rfc3339() const { string result = format("%Y-%m-%dT%H:%M:%S"); + if(usec) + result += Msp::format(".%06d", usec); if(const TimeDelta &offs = zone.get_offset()) { int m = abs(static_cast(offs/Time::min)); -- 2.45.2