| 161 | } |
| 162 | |
| 163 | int utime_t::parse_date(const std::string& date, uint64_t *epoch, uint64_t *nsec, |
| 164 | std::string *out_date, |
| 165 | std::string *out_time) { |
| 166 | struct tm tm; |
| 167 | memset(&tm, 0, sizeof(tm)); |
| 168 | |
| 169 | if (nsec) |
| 170 | *nsec = 0; |
| 171 | |
| 172 | const char *p = strptime(date.c_str(), "%Y-%m-%d", &tm); |
| 173 | if (p) { |
| 174 | if (*p == ' ' || *p == 'T') { |
| 175 | p++; |
| 176 | // strptime doesn't understand fractional/decimal seconds, and |
| 177 | // it also only takes format chars or literals, so we have to |
| 178 | // get creative. |
| 179 | char fmt[32] = {0}; |
| 180 | strncpy(fmt, p, sizeof(fmt) - 1); |
| 181 | fmt[0] = '%'; |
| 182 | fmt[1] = 'H'; |
| 183 | fmt[2] = ':'; |
| 184 | fmt[3] = '%'; |
| 185 | fmt[4] = 'M'; |
| 186 | fmt[6] = '%'; |
| 187 | fmt[7] = 'S'; |
| 188 | const char *subsec = 0; |
| 189 | char *q = fmt + 8; |
| 190 | if (*q == '.') { |
| 191 | ++q; |
| 192 | subsec = p + 9; |
| 193 | q = fmt + 9; |
| 194 | while (*q && isdigit(*q)) { |
| 195 | ++q; |
| 196 | } |
| 197 | } |
| 198 | // look for tz... |
| 199 | if (*q == '-' || *q == '+') { |
| 200 | *q = '%'; |
| 201 | *(q+1) = 'z'; |
| 202 | *(q+2) = 0; |
| 203 | } |
| 204 | p = strptime(p, fmt, &tm); |
| 205 | if (!p) { |
| 206 | return -EINVAL; |
| 207 | } |
| 208 | if (nsec && subsec) { |
| 209 | unsigned i; |
| 210 | char buf[10]; /* 9 digit + null termination */ |
| 211 | for (i = 0; (i < sizeof(buf) - 1) && isdigit(*subsec); ++i, ++subsec) { |
| 212 | buf[i] = *subsec; |
| 213 | } |
| 214 | for (; i < sizeof(buf) - 1; ++i) { |
| 215 | buf[i] = '0'; |
| 216 | } |
| 217 | buf[i] = '\0'; |
| 218 | std::string err; |
| 219 | *nsec = (uint64_t)strict_strtol(buf, 10, &err); |
| 220 | if (!err.empty()) { |
nothing calls this directly
no test coverage detected