public static ZonedDateTime parseDateTime()

in core/src/main/java/com/alibaba/druid/util/MySqlUtils.java [1436:1915]


    public static ZonedDateTime parseDateTime(final byte[] str, final int off, final int len, ZoneId zoneId) {
        if (str == null) {
            throw new IllegalArgumentException("str not be null");
        }

        if (len < 8) {
            throw new IllegalArgumentException(new String(str, UTF8));
        }

        byte y0 = str[off];
        byte y1 = str[off + 1];
        byte y2 = str[off + 2];
        byte y3 = str[off + 3];

        byte M0 = 0, M1 = 0, d0 = 0, d1 = 0;
        byte h0 = 0, h1 = 0, m0 = 0, m1 = 0, s0 = 0, s1 = 0, S0 = '0', S1 = '0', S2 = '0';

        final byte c4 = str[off + 4];
        final byte c5 = str[off + 5];
        final byte c6 = str[off + 6];
        final byte c7 = str[off + 7];
        byte c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18;

        int nanos = 0;
        switch (len) {
            case 8:
                // yyyyMMdd
                if (c4 == '-' && c6 == '-') {
                    M0 = '0';
                    M1 = c5;
                    d0 = '0';
                    d1 = c7;
                } else if (y2 == ':' && c5 == ':') {
                    h0 = y0;
                    h1 = y1;
                    m0 = y3;
                    m1 = c4;
                    s0 = c6;
                    s1 = c7;

                    y0 = '1';
                    y1 = '9';
                    y2 = '7';
                    y3 = '0';
                    M0 = '0';
                    M1 = '1';
                    d0 = '0';
                    d1 = '1';
                } else {
                    M0 = c4;
                    M1 = c5;
                    d0 = c6;
                    d1 = c7;
                }
                break;
            case 9:
                // yyyy-M-dd or yyyy-MM-d
                c8 = str[off + 8];

                if (c4 != '-') {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }

                if (c6 == '-') {
                    M0 = '0';
                    M1 = c5;
                    d0 = c7;
                    d1 = c8;
                } else if (c7 == '-') {
                    M0 = c5;
                    M1 = c6;
                    d0 = '0';
                    d1 = c8;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }
                break;
            case 10:
                c8 = str[off + 8];
                c9 = str[off + 9];
                // yyyy-MM-dd
                if (c4 != '-' || c7 != '-') {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }

                M0 = c5;
                M1 = c6;
                d0 = c8;
                d1 = c9;
                break;
            case 14:
                c8 = str[off + 8];
                c9 = str[off + 9];
                c10 = str[off + 10];
                c11 = str[off + 11];
                c12 = str[off + 12];
                c13 = str[off + 13];

                if (c8 == ' ') {
                    // yyyy-M-d H:m:s
                    if (c4 == '-' && c6 == '-' & c10 == ':' && c12 == ':') {
                        M0 = '0';
                        M1 = c5;
                        d0 = '0';
                        d1 = c7;
                        h0 = '0';
                        h1 = c9;
                        m0 = '0';
                        m1 = c11;
                        s0 = '0';
                        s1 = c13;
                    } else {
                        throw new IllegalArgumentException(new String(str, UTF8));
                    }
                } else {
                    // yyyyMMddHHmmss
                    M0 = c4;
                    M1 = c5;
                    d0 = c6;
                    d1 = c7;
                    h0 = c8;
                    h1 = c9;
                    m0 = c10;
                    m1 = c11;
                    s0 = c12;
                    s1 = c13;
                }
                break;
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 21:
            case 22:
            case 23:
            case 26:
            case 27:
            case 28:
            case 29:
                if (len == 19 || len >= 23) {
                    c8 = str[off + 8];
                    c9 = str[off + 9];
                    c10 = str[off + 10];
                    c11 = str[off + 11];
                    c12 = str[off + 12];
                    c13 = str[off + 13];
                    c14 = str[off + 14];
                    c15 = str[off + 15];
                    c16 = str[off + 16];
                    c17 = str[off + 17];
                    c18 = str[off + 18];

                    // yyyy-MM-dd HH:mm:ss
                    if (c4 == '-' && c7 == '-'
                            && (c10 == ' ' || c10 == 'T')
                            && c13 == ':' && c16 == ':') {
                        M0 = c5;
                        M1 = c6;
                        d0 = c8;
                        d1 = c9;
                        h0 = c11;
                        h1 = c12;
                        m0 = c14;
                        m1 = c15;
                        s0 = c17;
                        s1 = c18;

                        if (len == 19) {
                            break;
                        }

                        // yyyy-MM-dd HH:mm:ss.SSS
                        final byte c19 = str[off + 19];
                        final byte c20 = str[off + 20];
                        final byte c21 = str[off + 21];
                        final byte c22 = str[off + 22];

                        if (len == 23) {
                            if (c19 == '.') {
                                S0 = c20;
                                S1 = c21;
                                S2 = c22;
                            } else if (c19 == ' ' && c20 == 'U' && c21 == 'T' && c22 == 'C') {
                                // skip
                                zoneId = ZoneOffset.UTC;
                            } else {
                                throw new IllegalArgumentException(new String(str, UTF8));
                            }
                            break;
                        }

                        if (c19 == '.') {
                            S0 = c20;
                            S1 = c21;
                            S2 = c22;
                        } else {
                            throw new IllegalArgumentException(new String(str, UTF8));
                        }

                        if (len == 29) {
                            final byte c23 = str[off + 23];
                            final byte c24 = str[off + 24];
                            final byte c25 = str[off + 25];
                            final byte c26 = str[off + 26];
                            final byte c27 = str[off + 27];
                            final byte c28 = str[off + 28];

                            if (c23 < '0' || c23 > '9'
                                    || c24 < '0' || c24 > '9'
                                    || c25 < '0' || c25 > '9'
                                    || c26 < '0' || c26 > '9'
                                    || c27 < '0' || c27 > '9'
                                    || c28 < '0' || c28 > '9') {
                                throw new IllegalArgumentException(new String(str, UTF8));
                            }

                            nanos = (c23 - '0') * 100000
                                    + (c24 - '0') * 10000
                                    + (c25 - '0') * 1000
                                    + (c26 - '0') * 100
                                    + (c27 - '0') * 10
                                    + (c28 - '0');
                        } else if (len == 28) {
                            final byte c23 = str[off + 23];
                            final byte c24 = str[off + 24];
                            final byte c25 = str[off + 25];
                            final byte c26 = str[off + 26];
                            final byte c27 = str[off + 27];

                            if (c23 < '0' || c23 > '9'
                                    || c24 < '0' || c24 > '9'
                                    || c25 < '0' || c25 > '9'
                                    || c26 < '0' || c26 > '9'
                                    || c27 < '0' || c27 > '9') {
                                throw new IllegalArgumentException(new String(str, UTF8));
                            }

                            nanos = (c23 - '0') * 100000
                                    + (c24 - '0') * 10000
                                    + (c25 - '0') * 1000
                                    + (c26 - '0') * 100
                                    + (c27 - '0') * 10;
                        } else if (len == 27) {
                            final byte c23 = str[off + 23];
                            final byte c24 = str[off + 24];
                            final byte c25 = str[off + 25];
                            final byte c26 = str[off + 26];

                            if (c23 < '0' || c23 > '9'
                                    || c24 < '0' || c24 > '9'
                                    || c25 < '0' || c25 > '9'
                                    || c26 < '0' || c26 > '9') {
                                throw new IllegalArgumentException(new String(str, UTF8));
                            }

                            nanos = (c23 - '0') * 100000
                                    + (c24 - '0') * 10000
                                    + (c25 - '0') * 1000
                                    + (c26 - '0') * 100;
                        } else if (len == 26) {
                            final byte c23 = str[off + 23];
                            final byte c24 = str[off + 24];
                            final byte c25 = str[off + 25];

                            if (c23 < '0' || c23 > '9'
                                    || c24 < '0' || c24 > '9'
                                    || c25 < '0' || c25 > '9') {
                                throw new IllegalArgumentException(new String(str, UTF8));
                            }

                            nanos = (c23 - '0') * 100000
                                    + (c24 - '0') * 10000
                                    + (c25 - '0') * 1000;
                        }

                        break;
                    }
                }

                if (c4 != '-') {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }

                int off2;
                if (c6 == '-') {
                    M0 = '0';
                    M1 = c5;
                    off2 = off + 7;
                } else if (c7 == '-') {
                    M0 = c5;
                    M1 = c6;
                    off2 = off + 8;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }

            {
                byte n0 = str[off2];
                byte n1, n2;

                if ((n1 = str[off2 + 1]) == ' ' || n1 == 'T') {
                    d0 = '0';
                    d1 = n0;
                    off2 += 2;
                } else if ((n2 = str[off2 + 2]) == ' ' || n2 == 'T') {
                    d0 = n0;
                    d1 = n1;
                    off2 += 3;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }
            }

            {
                byte n0 = str[off2];
                byte n1, n2;

                if ((n1 = str[off2 + 1]) == ':') {
                    h0 = '0';
                    h1 = n0;
                    off2 += 2;
                } else if ((n2 = str[off2 + 2]) == ':') {
                    h0 = n0;
                    h1 = n1;
                    off2 += 3;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }
            }

            {
                byte n0 = str[off2];
                byte n1, n2;

                if ((n1 = str[off2 + 1]) == ':') {
                    m0 = '0';
                    m1 = n0;
                    off2 += 2;
                } else if (off2 + 2 < off + len && (n2 = str[off2 + 2]) == ':') {
                    m0 = n0;
                    m1 = n1;
                    off2 += 3;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }
            }

            if (off2 == off + len - 1) {
                s0 = '0';
                s1 = str[off2];
            } else if (off2 == off + len - 2) {
                byte n0 = str[off2];
                byte n1 = str[off2 + 1];
                if (n1 == '.') {
                    s0 = '0';
                    s1 = n0;
                } else {
                    s0 = n0;
                    s1 = n1;
                }
            } else {
                byte x0 = str[off + len - 1];
                byte x1 = str[off + len - 2];
                byte x2 = str[off + len - 3];
                byte x3 = str[off + len - 4];

                int lastOff;
                if (x0 == '.') {
                    // skip
                    lastOff = off + len - 2;
                } else if (x1 == '.') {
                    S0 = x0;
                    lastOff = off + len - 3;
                } else if (x2 == '.') {
                    S0 = x1;
                    S1 = x0;
                    lastOff = off + len - 4;
                } else if (x3 == '.') {
                    S0 = x2;
                    S1 = x1;
                    S2 = x0;
                    lastOff = off + len - 5;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }

                byte k0 = str[lastOff];
                byte k1 = str[lastOff - 1];
                byte k2 = str[lastOff - 2];
                if (k1 == ':') {
                    s0 = '0';
                    s1 = k0;
                } else if (k2 == ':') {
                    s1 = k0;
                    s0 = k1;
                } else {
                    throw new IllegalArgumentException(new String(str, UTF8));
                }
            }
            break;
            default:
                throw new IllegalArgumentException(new String(str, UTF8));
        }

        if (y0 < '0' || y0 > '9'
                || y1 < '0' || y1 > '9'
                || y2 < '0' || y2 > '9'
                || y3 < '0' || y3 > '9') {
            throw new IllegalArgumentException(new String(str, UTF8));
        }
        int year = (y0 - '0') * 1000
                + (y1 - '0') * 100
                + (y2 - '0') * 10
                + (y3 - '0');

        if (M0 < '0' || M0 > '1') {
            throw new IllegalArgumentException(new String(str, UTF8));
        }
        if (M1 < '0' || M1 > '9') {
            throw new IllegalArgumentException(new String(str, UTF8));
        }
        int month = (M0 - '0') * 10 + (M1 - '0');
        if (month < 1 || month > 12) {
            throw new IllegalArgumentException(new String(str, UTF8));
        }

        if (d0 < '0' || d0 > '9') {
            throw new IllegalArgumentException(new String(str, UTF8));
        }
        if (d1 < '0' || d1 > '9') {
            throw new IllegalArgumentException(new String(str, UTF8));
        }
        int dayOfMonth = (d0 - '0') * 10 + (d1 - '0');
        if (dayOfMonth < 1) {
            throw new IllegalArgumentException(new String(str, UTF8));
        }

        final int maxDayOfMonth;
        switch (month) {
            case 2:
                maxDayOfMonth = 29;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                maxDayOfMonth = 30;
                break;
            default:
                maxDayOfMonth = 31;
                break;
        }
        if (dayOfMonth > maxDayOfMonth) {
            throw new IllegalArgumentException(new String(str, UTF8));
        }

        ZonedDateTime zdt;
        if (h0 == 0) {
            zdt = LocalDate
                    .of(year, month, dayOfMonth)
                    .atStartOfDay(zoneId);
        } else {
            int hour = (h0 - '0') * 10 + (h1 - '0');
            int minute = (m0 - '0') * 10 + (m1 - '0');
            int second = (s0 - '0') * 10 + (s1 - '0');
            int nanoSecond = ((S0 - '0') * 100 + (S1 - '0') * 10 + (S2 - '0')) * 1000000 + nanos;

            if (hour > 24 || minute > 60 || second > 61) {
                throw new IllegalArgumentException(new String(str, UTF8));
            }

            zdt = LocalDateTime
                    .of(year, month, dayOfMonth, hour, minute, second, nanoSecond)
                    .atZone(zoneId);
        }

        return zdt;
    }