in source/date_time.c [570:642]
int aws_date_time_init_from_str_cursor(
struct aws_date_time *dt,
const struct aws_byte_cursor *date_str_cursor,
enum aws_date_format fmt) {
AWS_ERROR_PRECONDITION(date_str_cursor->len <= AWS_DATE_TIME_STR_MAX_LEN, AWS_ERROR_OVERFLOW_DETECTED);
AWS_ZERO_STRUCT(*dt);
struct tm parsed_time;
bool successfully_parsed = false;
time_t seconds_offset = 0;
if (fmt == AWS_DATE_FORMAT_ISO_8601 || fmt == AWS_DATE_FORMAT_AUTO_DETECT) {
if (!s_parse_iso_8601(date_str_cursor, &parsed_time)) {
dt->utc_assumed = true;
successfully_parsed = true;
}
}
if (fmt == AWS_DATE_FORMAT_ISO_8601_BASIC || (fmt == AWS_DATE_FORMAT_AUTO_DETECT && !successfully_parsed)) {
if (!s_parse_iso_8601_basic(date_str_cursor, &parsed_time)) {
dt->utc_assumed = true;
successfully_parsed = true;
}
}
if (fmt == AWS_DATE_FORMAT_RFC822 || (fmt == AWS_DATE_FORMAT_AUTO_DETECT && !successfully_parsed)) {
if (!s_parse_rfc_822(date_str_cursor, &parsed_time, dt)) {
successfully_parsed = true;
if (dt->utc_assumed) {
if (dt->tz[0] == '+' || dt->tz[0] == '-') {
/* in this format, the offset is in format +/-HHMM so convert that to seconds and we'll use
* the offset later. */
char min_str[3] = {0};
char hour_str[3] = {0};
hour_str[0] = dt->tz[1];
hour_str[1] = dt->tz[2];
min_str[0] = dt->tz[3];
min_str[1] = dt->tz[4];
long hour = strtol(hour_str, NULL, 10);
long min = strtol(min_str, NULL, 10);
seconds_offset = (time_t)(hour * 3600 + min * 60);
if (dt->tz[0] == '-') {
seconds_offset = -seconds_offset;
}
}
}
}
}
if (!successfully_parsed) {
return aws_raise_error(AWS_ERROR_INVALID_DATE_STR);
}
if (dt->utc_assumed || seconds_offset) {
dt->timestamp = aws_timegm(&parsed_time);
} else {
dt->timestamp = mktime(&parsed_time);
}
/* negative means we need to move west (increase the timestamp), positive means head east, so decrease the
* timestamp. */
dt->timestamp -= seconds_offset;
dt->milliseconds = 0U;
dt->gmt_time = s_get_time_struct(dt, false);
dt->local_time = s_get_time_struct(dt, true);
return AWS_OP_SUCCESS;
}