summaryrefslogtreecommitdiff
path: root/louloulibs/utils
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2016-10-11 00:18:48 +0200
committerlouiz’ <louiz@louiz.org>2016-10-11 00:20:43 +0200
commit548e4ad473e7be22f971184312cc5ce9b8fe56b7 (patch)
tree3b7be9c89c931bb49ad9bc7e14d6e21a446e90f0 /louloulibs/utils
parent116472920ce4bcd4c9512db67108cdbf9895e8ad (diff)
downloadbiboumi-548e4ad473e7be22f971184312cc5ce9b8fe56b7.tar.gz
biboumi-548e4ad473e7be22f971184312cc5ce9b8fe56b7.tar.bz2
biboumi-548e4ad473e7be22f971184312cc5ce9b8fe56b7.tar.xz
biboumi-548e4ad473e7be22f971184312cc5ce9b8fe56b7.zip
Parse the timezone myself, instead of using the broken strptime
See https://lab.louiz.org/louiz/biboumi/issues/3215 https://github.com/andikleen/glibc/blob/master/time/strptime_l.c#L746-L747 for why strptime() sucks We use std::get_time now, to parse the date and time. And we parse the timezone by hand. fix #3215
Diffstat (limited to 'louloulibs/utils')
-rw-r--r--louloulibs/utils/time.cpp44
1 files changed, 39 insertions, 5 deletions
diff --git a/louloulibs/utils/time.cpp b/louloulibs/utils/time.cpp
index abf0a84..7ad6663 100644
--- a/louloulibs/utils/time.cpp
+++ b/louloulibs/utils/time.cpp
@@ -1,6 +1,10 @@
#include <utils/time.hpp>
#include <time.h>
+#include <sstream>
+#include <iomanip>
+#include <locale>
+
namespace utils
{
std::string to_string(const std::time_t& timestamp)
@@ -14,12 +18,42 @@ std::string to_string(const std::time_t& timestamp)
std::time_t parse_datetime(const std::string& stamp)
{
- auto stamp2 = stamp.substr(0, stamp.size() - 1) + "z";
- struct tm tm;
- if (!::strptime(stamp2.data(), "%FT%T%Z", &tm))
+ static const char* format = "%Y-%m-%dT%H:%M:%S";
+ std::tm t = {};
+ std::istringstream ss(stamp);
+ ss.imbue(std::locale("en_US.utf-8"));
+
+ std::string timezone;
+ ss >> std::get_time(&t, format) >> timezone;
+ if (ss.fail())
+ return -1;
+
+ if (timezone.empty())
return -1;
- auto res = ::timegm(&tm);
- return res;
+
+ if (timezone.compare(0, 1, "Z") != 0)
+ {
+ std::stringstream tz_ss;
+ tz_ss << timezone;
+ int multiplier = -1;
+ char prefix;
+ int hours;
+ char sep;
+ int minutes;
+ tz_ss >> prefix >> hours >> sep >> minutes;
+ if (tz_ss.fail())
+ return -1;
+ if (prefix == '-')
+ multiplier = +1;
+ else if (prefix != '+')
+ return -1;
+
+ t.tm_hour += multiplier * hours;
+ t.tm_min += multiplier * minutes;
+ }
+ return ::timegm(&t);
}
}
+
+