void parse_author_line(char *ident, const struct ident **author, struct time *time) { char *nameend = strchr(ident, '<'); char *emailend = strchr(ident, '>'); const char *name, *email = ""; if (nameend && emailend) *nameend = *emailend = 0; name = chomp_string(ident); if (nameend) email = chomp_string(nameend + 1); if (!*name) name = *email ? email : unknown_ident.name; if (!*email) email = *name ? name : unknown_ident.email; *author = get_author(name, email); /* Parse epoch and timezone */ if (time && emailend && emailend[1] == ' ') { char *secs = emailend + 2; char *zone = strchr(secs, ' '); parse_timesec(time, secs); if (zone && strlen(zone) == STRING_SIZE(" +0700")) parse_timezone(time, zone + 1); } }
static gboolean parse_textual_date (SoupDate *date, const char *date_string) { /* If it starts with a word, it must be a weekday, which we skip */ if (g_ascii_isalpha (*date_string)) { while (g_ascii_isalpha (*date_string)) date_string++; if (*date_string == ',') date_string++; while (g_ascii_isspace (*date_string)) date_string++; } /* If there's now another word, this must be an asctime-date */ if (g_ascii_isalpha (*date_string)) { /* (Sun) Nov 6 08:49:37 1994 */ if (!parse_month (date, &date_string) || !parse_day (date, &date_string) || !parse_time (date, &date_string) || !parse_year (date, &date_string)) return FALSE; /* There shouldn't be a timezone, but check anyway */ parse_timezone (date, &date_string); } else { /* Non-asctime date, so some variation of * (Sun,) 06 Nov 1994 08:49:37 GMT */ if (!parse_day (date, &date_string) || !parse_month (date, &date_string) || !parse_year (date, &date_string) || !parse_time (date, &date_string)) return FALSE; /* This time there *should* be a timezone, but we * survive if there isn't. */ parse_timezone (date, &date_string); } return TRUE; }
time_t xep82_datetime(const char *stamp) { struct tm tm; long offset; char *s; memset(&tm, 0, sizeof(struct tm)); if ((s = strptime(stamp, FORMAT, &tm)) == NULL) return (time_t)-1; /* ignore fractional second addendum */ if (*s++ == '.') while (isdigit(*s++)); tm.tm_isdst = -1; offset = *s != '\0' ? parse_timezone(s) : 0; return mktime(&tm) - offset; }
bool parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *line) { if (match_blame_header("author ", &line)) { string_ncopy_do(author, SIZEOF_STR, line, strlen(line)); } else if (match_blame_header("author-mail ", &line)) { char *end = strchr(line, '>'); if (end) *end = 0; if (*line == '<') line++; commit->author = get_author(author, line); author[0] = 0; } else if (match_blame_header("author-time ", &line)) { parse_timesec(&commit->time, line); } else if (match_blame_header("author-tz ", &line)) { parse_timezone(&commit->time, line); } else if (match_blame_header("summary ", &line)) { string_ncopy(commit->title, line, strlen(line)); } else if (match_blame_header("previous ", &line)) { if (strlen(line) <= SIZEOF_REV) return FALSE; string_copy_rev(commit->parent_id, line); line += SIZEOF_REV; commit->parent_filename = get_path(line); if (!commit->parent_filename) return TRUE; } else if (match_blame_header("filename ", &line)) { commit->filename = get_path(line); return TRUE; } return FALSE; }
bool imap_parse_datetime(const char *str, time_t *timestamp_r, int *timezone_offset_r) { struct tm tm; str = imap_parse_date_internal(str, &tm); if (str == NULL) return FALSE; if (str[0] != ' ') return FALSE; str++; /* hh: */ if (!i_isdigit(str[0]) || !i_isdigit(str[1]) || str[2] != ':') return FALSE; tm.tm_hour = (str[0]-'0') * 10 + (str[1]-'0'); str += 3; /* mm: */ if (!i_isdigit(str[0]) || !i_isdigit(str[1]) || str[2] != ':') return FALSE; tm.tm_min = (str[0]-'0') * 10 + (str[1]-'0'); str += 3; /* ss */ if (!i_isdigit(str[0]) || !i_isdigit(str[1]) || str[2] != ' ') return FALSE; tm.tm_sec = (str[0]-'0') * 10 + (str[1]-'0'); str += 3; /* timezone */ *timezone_offset_r = parse_timezone(str); tm.tm_isdst = -1; if (imap_mktime(&tm, timestamp_r)) *timestamp_r -= *timezone_offset_r * 60; return TRUE; }
static bool message_date_parser_tokens(struct message_date_parser_context *ctx, time_t *timestamp_r, int *timezone_offset_r) { struct tm tm; const unsigned char *value; size_t i, len; int ret; /* [weekday_name "," ] dd month_name [yy]yy hh:mi[:ss] timezone */ memset(&tm, 0, sizeof(tm)); rfc822_skip_lwsp(&ctx->parser); /* skip the optional weekday */ if (next_token(ctx, &value, &len) <= 0) return FALSE; if (len == 3) { if (*ctx->parser.data != ',') return FALSE; ctx->parser.data++; rfc822_skip_lwsp(&ctx->parser); if (next_token(ctx, &value, &len) <= 0) return FALSE; } /* dd */ if (len < 1 || len > 2 || !i_isdigit(value[0])) return FALSE; tm.tm_mday = value[0]-'0'; if (len == 2) { if (!i_isdigit(value[1])) return FALSE; tm.tm_mday = (tm.tm_mday * 10) + (value[1]-'0'); } /* month name */ if (next_token(ctx, &value, &len) <= 0 || len < 3) return FALSE; for (i = 0; i < 12; i++) { if (i_memcasecmp(month_names[i], value, 3) == 0) { tm.tm_mon = i; break; } } if (i == 12) return FALSE; /* [yy]yy */ if (next_token(ctx, &value, &len) <= 0 || (len != 2 && len != 4)) return FALSE; for (i = 0; i < len; i++) { if (!i_isdigit(value[i])) return FALSE; tm.tm_year = tm.tm_year * 10 + (value[i]-'0'); } if (len == 2) { /* two digit year, assume 1970+ */ if (tm.tm_year < 70) tm.tm_year += 100; } else { if (tm.tm_year < 1900) return FALSE; tm.tm_year -= 1900; } /* hh, allow also single digit */ if (next_token(ctx, &value, &len) <= 0 || len < 1 || len > 2 || !i_isdigit(value[0])) return FALSE; tm.tm_hour = value[0]-'0'; if (len == 2) { if (!i_isdigit(value[1])) return FALSE; tm.tm_hour = tm.tm_hour * 10 + (value[1]-'0'); } /* :mm (may be the last token) */ if (!IS_TIME_SEP(*ctx->parser.data)) return FALSE; ctx->parser.data++; rfc822_skip_lwsp(&ctx->parser); if (next_token(ctx, &value, &len) < 0 || len != 2 || !i_isdigit(value[0]) || !i_isdigit(value[1])) return FALSE; tm.tm_min = (value[0]-'0') * 10 + (value[1]-'0'); /* [:ss] */ if (ctx->parser.data != ctx->parser.end && IS_TIME_SEP(*ctx->parser.data)) { ctx->parser.data++; rfc822_skip_lwsp(&ctx->parser); if (next_token(ctx, &value, &len) <= 0 || len != 2 || !i_isdigit(value[0]) || !i_isdigit(value[1])) return FALSE; tm.tm_sec = (value[0]-'0') * 10 + (value[1]-'0'); } if ((ret = next_token(ctx, &value, &len)) < 0) return FALSE; if (ret == 0) { /* missing timezone */ *timezone_offset_r = 0; } else { /* timezone */ *timezone_offset_r = parse_timezone(value, len); } tm.tm_isdst = -1; *timestamp_r = utc_mktime(&tm); if (*timestamp_r == (time_t)-1) return FALSE; *timestamp_r -= *timezone_offset_r * 60; return TRUE; }
std::time_t parse_rfc_datetime(std::string value) { boost::replace_all(value, " -", " #"); std::replace(value.begin(), value.end(), '-', ' '); boost::replace_all(value, " #", " -"); std::tm t; memset(&t, 0, sizeof(std::tm)); int x, zone = 0; std::string s; std::string::size_type pos; while (!value.empty()) { pos = value.find(' '); if (pos != std::string::npos) { s = value.substr(0, pos); value.erase(0, pos + 1); } else { s = value; value.clear(); } std::transform(s.begin(), s.end(), s.begin(), toupper); if (parse_timezone(s, zone)) continue; if ((x = atoi(s.c_str())) > 0) { if ((x < 32) && (!t.tm_mday)) { t.tm_mday = x; continue; } else { if ((!t.tm_year) && (t.tm_mon || (x > 12))) { if (x < 32) { t.tm_year = x + 100; } else if (x < 1000) { t.tm_year = x; } else { t.tm_year = x - 1900; } continue; } } } std::string::size_type first, last; if ((first = s.find_first_of(':')) < (last = s.find_last_of(':'))) { t.tm_hour = atoi(s.substr(0, first).c_str()); t.tm_min = atoi(s.substr(first + 1, last).c_str()); t.tm_sec = atoi(s.substr(last + 1).c_str()); continue; } if (s == "DST") { t.tm_isdst = true; continue; } if (parse_month(s, x) && (!t.tm_mon)) { t.tm_mon = x; } } if (!t.tm_year) { t.tm_year = 80; } if (t.tm_mon > 11) { t.tm_mon = 11; } if (!t.tm_mday) { t.tm_mday = 1; } t.tm_sec -= (zone + ctime::timezone()); return mktime(&t); }