TimeConverter::ExactTimestamp TimeConverter::fromString(const std::string &str) const { struct tm bt; // parse input string sscanf(str.c_str(), "%04u-%02u-%02uT%02u:%02u:%02u", &bt.tm_year, &bt.tm_mon, &bt.tm_mday, &bt.tm_hour, &bt.tm_min, &bt.tm_sec); // fix some ranges and variables bt.tm_year -=1900; bt.tm_mon -=1; bt.tm_isdst =-1; // auto-detect day-light-saving // convert to time_t const time_t tsLocal=mktime(&bt); // test if mktime() explicitly (?!) returned an error if( tsLocal==static_cast<time_t>(-1) ) throw ExceptionInvalidTime(SYSTEM_SAVE_LOCATION, str, "mktime() returned error"); // fix to skip local timezone const time_t tsRead=tsLocal+bt.tm_gmtoff; // check timezone offset const char *tzPart =str.c_str()+(4+1 + 2+1 + 2 + 1 +2+1 + 2+1 +2); ParsedFraction fracTmp=parseFraction(str, tzPart); assert(fracTmp.first>=0); assert(fracTmp.first< 1); const int tzOffset=parseTimezoneOffset(str, fracTmp.second); // compute actual time const time_t utcTime =tsRead+tzOffset; // return final result return ExactTimestamp( Persistency::Timestamp(utcTime), fracTmp.first ); }
static double parse_time(const char * time) { unsigned vTotal = 0, vCur = 0; for(;;) { char c = *time++; if (c == 0) return (double) (vTotal + vCur); else if (pfc::char_is_numeric( c ) ) { vCur = vCur * 10 + (unsigned)(c-'0'); } else if (c == ':') { if (vCur >= 60) {PFC_ASSERT(!"Invalid input"); return 0; } vTotal += vCur; vCur = 0; vTotal *= 60; } else if (c == '.') { return (double) (vTotal + vCur) + parseFraction(time); } else { PFC_ASSERT(!"Invalid input"); return 0; } } }