fru: support two time string formats

Support parsing two time string formats to enable use of ipmi-fru-parser
and entity-manager to provide FRU details on dbus.

Tested: Verified the entity-manager dbus output for the FRU MfgDate is
now parsed correctly.

Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I053ec225b51166269c5a5a800ad8d607fd0cc233
diff --git a/ipmi_fru_info_area.cpp b/ipmi_fru_info_area.cpp
index 85d2007..b220f02 100644
--- a/ipmi_fru_info_area.cpp
+++ b/ipmi_fru_info_area.cpp
@@ -2,9 +2,11 @@
 
 #include <algorithm>
 #include <ctime>
+#include <iomanip>
 #include <map>
 #include <numeric>
 #include <phosphor-logging/elog.hpp>
+#include <sstream>
 
 namespace ipmi
 {
@@ -193,6 +195,29 @@
     }
 }
 
+std::time_t timeStringToRaw(const std::string& input)
+{
+    // TODO: For non-US region timestamps, pass in region information for the
+    // FRU to avoid the month/day swap.
+    // 2017-02-24 - 13:59:00, Tue Nov 20 23:08:00 2018
+    static const std::vector<std::string> patterns = {"%Y-%m-%d - %H:%M:%S",
+                                                      "%a %b %d %H:%M:%S %Y"};
+
+    std::tm time = {};
+
+    for (const auto& pattern : patterns)
+    {
+        std::istringstream timeStream(input);
+        timeStream >> std::get_time(&time, pattern.c_str());
+        if (!timeStream.fail())
+        {
+            break;
+        }
+    }
+
+    return std::mktime(&time);
+}
+
 /**
  * @brief Appends Build Date
  *
@@ -205,9 +230,7 @@
     auto iter = propMap.find(buildDate);
     if ((iter != propMap.end()) && (iter->second.size() > 0))
     {
-        tm time = {};
-        strptime(iter->second.c_str(), "%F - %H:%M:%S", &time);
-        time_t raw = mktime(&time);
+        std::time_t raw = timeStringToRaw(iter->second);
 
         // From FRU Spec:
         // "Mfg. Date / Time