int StringUtils_digitToInt(char digit) { if (StringUtils_isDigit(digit)) { return (digit - 48); } else return -1; }
uint64_t Conversions_generalizedTimeToMsTime(const char* gtString) { int gtStringLen = strlen(gtString); if (gtStringLen < 14) return -1; int year = StringUtils_digitsToInt(gtString, 4); if (year < 0) return -1; int month = StringUtils_digitsToInt(gtString + 4, 2); if (month < 0) return -1; int day = StringUtils_digitsToInt(gtString + 6, 2); if (day < 0) return -1; int hour = StringUtils_digitsToInt(gtString + 8, 2); if (hour < 0) return -1; int min = StringUtils_digitsToInt(gtString + 10, 2); if (min < 0) return -1; int seconds = StringUtils_digitsToInt(gtString + 12, 2); if (seconds < 0) return -1; struct tm tmTime; tmTime.tm_year = year - 1900; tmTime.tm_mon = month - 1; tmTime.tm_mday = day; tmTime.tm_hour = hour; tmTime.tm_min = min; tmTime.tm_sec = seconds; int msOffset = 0; const char* parsePos = gtString + 14; /* parse optional fraction of second field */ if (*(parsePos) == '.') { parsePos++; const char* fractionOfSecondStart = parsePos; int fractionOfSecondLen = 0; int secondValue = 1; while (StringUtils_isDigit(fractionOfSecondStart[fractionOfSecondLen])) { fractionOfSecondLen++; secondValue = secondValue * 10; } if (fractionOfSecondLen > 0) { int fractionOfSecond = StringUtils_digitsToInt(fractionOfSecondStart, fractionOfSecondLen); msOffset = (fractionOfSecond * 1000) / secondValue; } parsePos += fractionOfSecondLen; } time_t t = 0; switch (*parsePos) { case 0: /* treat time as localtime */ t = mktime(&tmTime); break; case 'Z': /* treat time as GMT(UTC) time */ t = timegm(&tmTime); break; case '+': /* subtract offset */ { t = timegm(&tmTime); int secondsOffset = getSecondsOffset(parsePos + 1); t = t - secondsOffset; } break; case '-': /* add offset */ { t = timegm(&tmTime); int secondsOffset = getSecondsOffset(parsePos + 1); t = t + secondsOffset; } break; default: return -1; } uint64_t msTime = t * 1000; msTime += msOffset; return msTime; }