int aws_date_time_init_from_str_cursor()

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;
}