private final IonType load_timestamp()

in src/com/amazon/ion/impl/IonReaderTextRawTokensX.java [1731:1829]


    private final IonType load_timestamp(StringBuilder sb, int c)
        throws IOException
    {
        // we read the year in our caller, we should only be
        // here is we read 4 digits and then a dash or a 'T'
        assert (c == '-' || c == 'T');

        sb.append((char)c);

        // if it's 'T' we done: yyyyT
        if (c == 'T') {
            c = read_char(); // because we'll unread it before we return
            return load_finish_number(sb, c, IonTokenConstsX.TOKEN_TIMESTAMP);
        }

        // read month
        load_fixed_digits(sb, 2);

        c = read_char();
        if (c == 'T') {
            sb.append((char)c);
            c = read_char(); // because we'll unread it before we return
            return load_finish_number(sb, c, IonTokenConstsX.TOKEN_TIMESTAMP);
        }
        if (c != '-') bad_token(c);

        // read day
        sb.append((char)c);
        load_fixed_digits(sb, 2);

        // look for the 'T', otherwise we're done (and happy about it)
        c = read_char();
        if (c != 'T') {
            return load_finish_number(sb, c, IonTokenConstsX.TOKEN_TIMESTAMP);
        }

        // so either we're done or we must at least hours and minutes
        // hour
        sb.append((char)c);
        c = read_char();
        if (!IonTokenConstsX.isDigit(c)) {
            return load_finish_number(sb, c, IonTokenConstsX.TOKEN_TIMESTAMP);
        }
        sb.append((char)c);
        load_fixed_digits(sb,1); // we already read the first digit
        c = read_char();
        if (c != ':') bad_token(c);

        // minutes
        sb.append((char)c);
        load_fixed_digits(sb, 2);
        c = read_char();
        if (c == ':') {
            // seconds are optional
            // and first we'll have the whole seconds
            sb.append((char)c);
            load_fixed_digits(sb, 2);
            c = read_char();
            if (c == '.') {
                sb.append((char)c);
                c = read_char();
                // Per spec and W3C Note http://www.w3.org/TR/NOTE-datetime
                // We require at least one digit after the decimal point.
                if (!IonTokenConstsX.isDigit(c)) {
                    expected_but_found("at least one digit after timestamp's decimal point", c);
                }
                c = load_digits(sb,c);
            }
        }

        // since we have a time, we have to have a timezone of some sort
        // the timezone offset starts with a '+' '-' 'Z' or 'z'
        if (c == 'z' || c == 'Z') {
            sb.append((char)c);
            // read ahead since we'll check for a valid ending in a bit
            c = read_char();
        }
        else if (c == '+' || c == '-') {
            // then ... hours of time offset
            sb.append((char)c);
            load_fixed_digits(sb, 2);
            c = read_char();
            if (c != ':') {
                // those hours need their minutes if it wasn't a 'z'
                // (above) then it has to be a +/- hours { : minutes }
                bad_token(c);
            }
            // and finally the *not* optional minutes of time offset
            sb.append((char)c);
            load_fixed_digits(sb, 2);
            c = read_char();
        }
        else {
            // some sort of offset is required with a time value
            // if it wasn't a 'z' (above) then it has to be a +/- hours { : minutes }
            bad_token(c);
        }
        return load_finish_number(sb, c, IonTokenConstsX.TOKEN_TIMESTAMP);
    }