From 33e388ae6e82777f8a7a05415bc1c01d1e57ca0f Mon Sep 17 00:00:00 2001
From: Sergey Yakubov <sergey.yakubov@desy.de>
Date: Tue, 25 Jun 2019 17:04:51 +0200
Subject: [PATCH] do not use get_time

---
 common/cpp/src/data_structs/data_structs.cpp  | 40 ++++++++++++++-----
 .../data_structs/test_data_structs.cpp        |  3 +-
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/common/cpp/src/data_structs/data_structs.cpp b/common/cpp/src/data_structs/data_structs.cpp
index 985f25a86..0e28a0618 100644
--- a/common/cpp/src/data_structs/data_structs.cpp
+++ b/common/cpp/src/data_structs/data_structs.cpp
@@ -107,26 +107,44 @@ std::string IsoDateFromEpochNanosecs(uint64_t time_from_epoch_nanosec) {
 }
 
 uint64_t NanosecsEpochFromISODate(std::string date_time) {
-    std::istringstream iss{date_time};
+    double frac = 0;
+    int pos = date_time.find_first_of('.');
+    if (pos!=std::string::npos) {
+        std::string frac_str = date_time.substr(pos);
+        if (sscanf(frac_str.c_str(), "%lf", &frac)!=1) {
+            return 0;
+        }
+        date_time = date_time.substr(0, pos);
+    }
+
     std::tm tm{};
-    if (!(iss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S"))) {
+
+    int year, month, day, hour, minute, second;
+    hour = 0;
+    minute = 0;
+    second = 0;
+
+    auto n = sscanf(date_time.c_str(), "%d-%d-%dT%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
+    if (!(year >= 1970 && month >= 1 && month <= 12 && day >= 1 && day <= 31) || (n != 3 && n != 6)) {
+        return 0;
+    }
+    if ((n==3 && date_time.size()!=10) || (n==6 && date_time.size()!=19)) {
         return 0;
     }
 
+    tm.tm_sec = second;
+    tm.tm_min = minute;
+    tm.tm_hour = hour;
+    tm.tm_mday = day;
+    tm.tm_mon = month-1;
+    tm.tm_year = year-1900;
+
     system_clock::time_point tp = system_clock::from_time_t (timegm(&tm));
     uint64_t ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(tp).
                   time_since_epoch().count();
 
-    if (iss.eof()) {
-        return ns > 0 ? ns : 1;
-    }
-
-    double zz = 0;
-    if (iss.peek() != '.' || !(iss >> zz)) {
-        return 0;
-    }
+    ns = ns + uint64_t(frac * 1000000000) ;
 
-    ns = ns + uint64_t(zz * 1000000000);
     return ns > 0 ? ns : 1;
 }
 
diff --git a/common/cpp/unittests/data_structs/test_data_structs.cpp b/common/cpp/unittests/data_structs/test_data_structs.cpp
index 381e62a55..83e93235f 100644
--- a/common/cpp/unittests/data_structs/test_data_structs.cpp
+++ b/common/cpp/unittests/data_structs/test_data_structs.cpp
@@ -136,8 +136,7 @@ auto tests = std::vector<TestEpochFromISODate> {
     TestEpochFromISODate{"2019-07-25T15:38:11.100010002", 1564069091100010002},
 //errors
     TestEpochFromISODate{"1970-13-01T00:00:00.000000002", 0},
-    TestEpochFromISODate{"1970-12-01T00:00:00,0", 0},
-
+    TestEpochFromISODate{"1970-12-01T00:00:00.", 0},
 };
 
 TEST(FileInFo, NanosecsEpochFromISODate) {
-- 
GitLab