From ac7267a71ee2dd861f5379b8a4fa0cbdad4d130a Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 3 Jan 2025 06:23:17 +0800 Subject: [PATCH] improve performance --- .../com/alibaba/fastjson2/util/DateUtils.java | 5761 +++++------------ .../com/alibaba/fastjson2/util/IOUtils.java | 88 +- .../alibaba/fastjson2/util/DateUtilsTest.java | 22 +- .../alibaba/fastjson2/util/IOUtilsTest.java | 52 + 4 files changed, 1705 insertions(+), 4218 deletions(-) diff --git a/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java b/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java index c27d8c439..233fa2129 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java @@ -293,410 +293,169 @@ public static LocalDateTime parseLocalDateTime(char[] str, int off, int len) { } } - public static LocalTime parseLocalTime5(byte[] bytes, int off) { - if (off + 5 > bytes.length) { + public static LocalTime parseLocalTime5(byte[] str, int off) { + if (off + 5 > str.length) { return null; } - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - - byte h0, h1, i0, i1; + int hour, minute; int second = 0; - if (c2 == ':') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - } else if (c1 == ':' && c3 == ':') { - h0 = '0'; - h1 = c0; - i0 = '0'; - i1 = c2; - second = c4 - '0'; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); + if (str[off + 2] == ':') { + hour = digit2(str, off); + minute = digit2(str, off + 3); + } else if (str[off + 1] == ':' && str[off + 3] == ':') { + hour = digit1(str, off); + minute = digit1(str, off + 2); + second = digit1(str, off + 4); } else { return null; } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - return LocalTime.of(hour, minute, second); + return localTime(hour, minute, second); } - public static LocalTime parseLocalTime5(char[] chars, int off) { - if (off + 5 > chars.length) { - return null; - } - - char c0 = chars[off]; - char c1 = chars[off + 1]; - char c2 = chars[off + 2]; - char c3 = chars[off + 3]; - char c4 = chars[off + 4]; - - char h0, h1, i0, i1; - int second = 0; - if (c2 == ':') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - } else if (c1 == ':' && c3 == ':') { - h0 = '0'; - h1 = c0; - i0 = '0'; - i1 = c2; - second = c4 - '0'; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { + public static LocalTime parseLocalTime5(char[] str, int off) { + if (off + 5 > str.length) { return null; } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); + int hour, minute, second = 0; + if (str[off + 2] == ':') { + hour = digit2(str, off); + minute = digit2(str, off + 3); + } else if (str[off + 1] == ':' && str[off + 3] == ':') { + hour = digit1(str, off); + minute = digit1(str, off + 2); + second = digit1(str, off + 4); } else { return null; } - return LocalTime.of(hour, minute, second); + return localTime(hour, minute, second); } - public static LocalTime parseLocalTime6(byte[] bytes, int off) { - if (off + 5 > bytes.length) { + public static LocalTime parseLocalTime6(byte[] str, int off) { + if (off + 5 > str.length) { return null; } - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - byte c5 = bytes[off + 5]; + byte c1 = str[off + 1]; + byte c4 = str[off + 4]; - byte h0, h1, i0, i1, s0, s1; - if (c2 == ':' && c4 == ':') { - h0 = c0; - h1 = c1; - i0 = '0'; - i1 = c3; - s0 = '0'; - s1 = c5; + int hour, minute, second; + if (str[off + 2] == ':' && c4 == ':') { + hour = digit2(str, off); + minute = digit1(str, off + 3); + second = digit1(str, off + 5); } else if (c1 == ':' && c4 == ':') { - h0 = '0'; - h1 = c0; - i0 = c2; - i1 = c3; - s0 = '0'; - s1 = c5; - } else if (c1 == ':' && c3 == ':') { - h0 = '0'; - h1 = c0; - i0 = '0'; - i1 = c2; - s0 = c4; - s1 = c5; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + hour = digit1(str, off); + minute = digit2(str, off + 2); + second = digit1(str, off + 5); + } else if (c1 == ':' && str[off + 3] == ':') { + hour = digit1(str, off); + minute = digit1(str, off + 2); + second = digit2(str, off + 4); } else { return null; } - return LocalTime.of(hour, minute, second); + return localTime(hour, minute, second); } - public static LocalTime parseLocalTime6(char[] chars, int off) { - if (off + 5 > chars.length) { + public static LocalTime parseLocalTime6(char[] str, int off) { + if (off + 5 > str.length) { return null; } - char c0 = chars[off]; - char c1 = chars[off + 1]; - char c2 = chars[off + 2]; - char c3 = chars[off + 3]; - char c4 = chars[off + 4]; - char c5 = chars[off + 5]; + char c1 = str[off + 1]; + char c4 = str[off + 4]; - char h0, h1, i0, i1, s0, s1; - if (c2 == ':' && c4 == ':') { - h0 = c0; - h1 = c1; - i0 = '0'; - i1 = c3; - s0 = '0'; - s1 = c5; + int hour, minute, second; + if (str[off + 2] == ':' && c4 == ':') { + hour = digit2(str, off); + minute = digit1(str, off + 3); + second = digit1(str, off + 5); } else if (c1 == ':' && c4 == ':') { - h0 = '0'; - h1 = c0; - i0 = c2; - i1 = c3; - s0 = '0'; - s1 = c5; - } else if (c1 == ':' && c3 == ':') { - h0 = '0'; - h1 = c0; - i0 = '0'; - i1 = c2; - s0 = c4; - s1 = c5; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + hour = digit1(str, off); + minute = digit2(str, off + 2); + second = digit1(str, off + 5); + } else if (c1 == ':' && str[off + 3] == ':') { + hour = digit1(str, off); + minute = digit1(str, off + 2); + second = digit2(str, off + 4); } else { return null; } - return LocalTime.of(hour, minute, second); + return localTime(hour, minute, second); } - public static LocalTime parseLocalTime7(byte[] bytes, int off) { - if (off + 5 > bytes.length) { + public static LocalTime parseLocalTime7(byte[] str, int off) { + if (off + 5 > str.length) { return null; } - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - byte c5 = bytes[off + 5]; - byte c6 = bytes[off + 6]; + byte c2 = str[off + 2]; + byte c4 = str[off + 4]; - byte h0, h1, i0, i1, s0, s1; - if (c1 == ':' && c4 == ':') { - h0 = '0'; - h1 = c0; - i0 = c2; - i1 = c3; - s0 = c5; - s1 = c6; + int hour, minute, second; + if (str[off + 1] == ':' && c4 == ':') { + hour = digit1(str, off); + minute = digit2(str, off + 2); + second = digit2(str, off + 5); } else if (c2 == ':' && c4 == ':') { - h0 = c0; - h1 = c1; - i0 = '0'; - i1 = c3; - s0 = c5; - s1 = c6; - } else if (c2 == ':' && c5 == ':') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = '0'; - s1 = c6; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + hour = digit2(str, off); + minute = digit1(str, off + 3); + second = digit2(str, off + 5); + } else if (c2 == ':' && str[off + 5] == ':') { + hour = digit2(str, off); + minute = digit2(str, off + 3); + second = digit1(str, off + 6); } else { return null; } - return LocalTime.of(hour, minute, second); + return localTime(hour, minute, second); } - public static LocalTime parseLocalTime7(char[] chars, int off) { - if (off + 5 > chars.length) { + public static LocalTime parseLocalTime7(char[] str, int off) { + if (off + 5 > str.length) { return null; } - char c0 = chars[off]; - char c1 = chars[off + 1]; - char c2 = chars[off + 2]; - char c3 = chars[off + 3]; - char c4 = chars[off + 4]; - char c5 = chars[off + 5]; - char c6 = chars[off + 6]; + char c2 = str[off + 2]; + char c4 = str[off + 4]; - char h0, h1, i0, i1, s0, s1; - if (c1 == ':' && c4 == ':') { - h0 = '0'; - h1 = c0; - i0 = c2; - i1 = c3; - s0 = c5; - s1 = c6; + int hour, minute, second; + if (str[off + 1] == ':' && c4 == ':') { + hour = digit1(str, off); + minute = digit2(str, off + 2); + second = digit2(str, off + 5); } else if (c2 == ':' && c4 == ':') { - h0 = c0; - h1 = c1; - i0 = '0'; - i1 = c3; - s0 = c5; - s1 = c6; - } else if (c2 == ':' && c5 == ':') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = '0'; - s1 = c6; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + hour = digit2(str, off); + minute = digit1(str, off + 3); + second = digit2(str, off + 5); + } else if (c2 == ':' && str[off + 5] == ':') { + hour = digit2(str, off); + minute = digit2(str, off + 3); + second = digit1(str, off + 6); } else { return null; } - return LocalTime.of(hour, minute, second); + return localTime(hour, minute, second); } public static LocalTime parseLocalTime8(byte[] bytes, int off) { - if (off + 8 > bytes.length) { - return null; - } - - char c0 = (char) bytes[off]; - char c1 = (char) bytes[off + 1]; - char c2 = (char) bytes[off + 2]; - char c3 = (char) bytes[off + 3]; - char c4 = (char) bytes[off + 4]; - char c5 = (char) bytes[off + 5]; - char c6 = (char) bytes[off + 6]; - char c7 = (char) bytes[off + 7]; - - return parseLocalTime(c0, c1, c2, c3, c4, c5, c6, c7); + return off + 8 > bytes.length || bytes[off + 2] != ':' || bytes[off + 5] != ':' + ? null + : localTime(digit2(bytes, off), digit2(bytes, off + 3), digit2(bytes, off + 6)); } public static LocalTime parseLocalTime8(char[] bytes, int off) { - if (off + 8 > bytes.length) { - return null; - } - - char c0 = bytes[off]; - char c1 = bytes[off + 1]; - char c2 = bytes[off + 2]; - char c3 = bytes[off + 3]; - char c4 = bytes[off + 4]; - char c5 = bytes[off + 5]; - char c6 = bytes[off + 6]; - char c7 = bytes[off + 7]; - - return parseLocalTime(c0, c1, c2, c3, c4, c5, c6, c7); + return off + 8 > bytes.length || bytes[off + 2] != ':' || bytes[off + 5] != ':' + ? null + : localTime(digit2(bytes, off), digit2(bytes, off + 3), digit2(bytes, off + 6)); } public static LocalTime parseLocalTime( @@ -751,3515 +510,1383 @@ public static LocalTime parseLocalTime( return LocalTime.of(hour, minute, second); } - public static LocalTime parseLocalTime10(byte[] bytes, int off) { - if (off + 10 > bytes.length) { + public static LocalTime parseLocalTime10(byte[] str, int off) { + if (off + 10 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; + } else { + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int millis = digit1(str, off + 9); + if (millis > 0) { + millis *= 100000000; + } + return ((hour | minute | second | minute) < 0) + ? null + : LocalTime.of(hour, minute, second, millis); } + } - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - byte c5 = bytes[off + 5]; - byte c6 = bytes[off + 6]; - byte c7 = bytes[off + 7]; - byte c8 = bytes[off + 8]; - byte c9 = bytes[off + 9]; - - byte h0, h1, i0, i1, s0, s1, m0; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - } else { + public static LocalTime parseLocalTime10(char[] str, int off) { + if (off + 10 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; + } else { + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int millis = digit1(str, off + 9); + if (millis > 0) { + millis *= 100000000; + } + return ((hour | minute | second | minute) < 0) + ? null + : LocalTime.of(hour, minute, second, millis); } + } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { + public static LocalTime parseLocalTime11(byte[] str, int off) { + if (off + 11 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; + } else { + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int millis = digit2(str, off + 9); + if (millis > 0) { + millis *= 10000000; + } + return ((hour | minute | second | minute) < 0) + ? null + : LocalTime.of(hour, minute, second, millis); } + } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { + public static LocalTime parseLocalTime11(char[] str, int off) { + if (off + 11 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; + } else { + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int millis = digit2(str, off + 9); + if (millis > 0) { + millis *= 10000000; + } + return ((hour | minute | second | minute) < 0) + ? null + : LocalTime.of(hour, minute, second, millis); } + } - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { + public static LocalTime parseLocalTime12(byte[] str, int off) { + if (off + 12 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; - } - - int millis; - if (m0 >= '0' && m0 <= '9') { - millis = (m0 - '0') * 100; - millis *= 1000_000; } else { - return null; + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int millis = digit3(str, off + 9); + if (millis > 0) { + millis *= 1000000; + } + return ((hour | minute | second | minute) < 0) + ? null + : LocalTime.of(hour, minute, second, millis); } - - return LocalTime.of(hour, minute, second, millis); } - public static LocalTime parseLocalTime10(char[] bytes, int off) { - if (off + 10 > bytes.length) { - return null; - } - - char c0 = bytes[off]; - char c1 = bytes[off + 1]; - char c2 = bytes[off + 2]; - char c3 = bytes[off + 3]; - char c4 = bytes[off + 4]; - char c5 = bytes[off + 5]; - char c6 = bytes[off + 6]; - char c7 = bytes[off + 7]; - char c8 = bytes[off + 8]; - char c9 = bytes[off + 9]; - - char h0, h1, i0, i1, s0, s1, m0; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { + public static LocalTime parseLocalTime12(char[] str, int off) { + if (off + 12 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); } else { - return null; + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int millis = digit3(str, off + 9); + if (millis > 0) { + millis *= 1000000; + } + return ((hour | minute | second | minute) < 0) + ? null + : LocalTime.of(hour, minute, second, millis); } + } - int millis; - if (m0 >= '0' && m0 <= '9') { - millis = (m0 - '0') * 100; - millis *= 1000_000; - } else { + public static LocalTime parseLocalTime18(byte[] str, int off) { + if (off + 18 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; } - - return LocalTime.of(hour, minute, second, millis); + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int nanos = readNanos(str, 9, off + 9); + return (hour | minute | second | nanos) < 0 + ? null + : LocalTime.of(hour, minute, second, nanos); } - public static LocalTime parseLocalTime11(byte[] bytes, int off) { - if (off + 11 > bytes.length) { + public static LocalTime parseLocalTime18(char[] str, int off) { + if (off + 18 > str.length || str[off + 2] != ':' || str[off + 5] != ':' || str[off + 8] != '.') { return null; } + int hour = digit2(str, off); + int minute = digit2(str, off + 3); + int second = digit2(str, off + 6); + int nanos = readNanos(str, 9, off + 9); + return (hour | minute | second | nanos) < 0 + ? null + : LocalTime.of(hour, minute, second, nanos); + } - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - byte c5 = bytes[off + 5]; - byte c6 = bytes[off + 6]; - byte c7 = bytes[off + 7]; - byte c8 = bytes[off + 8]; - byte c9 = bytes[off + 9]; - byte c10 = bytes[off + 10]; + private static LocalTime localTime(int hour, int minute, int second) { + return (hour | minute | second) < 0 + ? null + : LocalTime.of(hour, minute, second); + } - byte h0, h1, i0, i1, s0, s1, m0, m1; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - m1 = c10; - } else { + public static LocalDateTime parseLocalDateTime(byte[] str, int off, int len) { + if (str == null || len == 0) { return null; } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; + switch (len) { + case 4: + if (str[off] == 'n' && str[off + 1] == 'u' && str[off + 2] == 'l' && str[off + 3] == 'l') { + return null; + } + String input = new String(str, off, len); + throw new DateTimeParseException("illegal input " + input, input, 0); + case 8: { + LocalDate localDate = parseLocalDate8(str, off); + if (localDate == null) { + return null; + } + return LocalDateTime.of(localDate, LocalTime.MIN); + } + case 9: { + LocalDate localDate = parseLocalDate9(str, off); + if (localDate == null) { + return null; + } + return LocalDateTime.of(localDate, LocalTime.MIN); + } + case 10: { + LocalDate localDate = parseLocalDate10(str, off); + if (localDate == null) { + return null; + } + return LocalDateTime.of(localDate, LocalTime.MIN); + } + case 11: { + return LocalDateTime.of( + parseLocalDate11(str, off), + LocalTime.MIN + ); + } + case 12: + return parseLocalDateTime12(str, off); + case 14: + return parseLocalDateTime14(str, off); + case 16: + return parseLocalDateTime16(str, off); + case 17: + return parseLocalDateTime17(str, off); + case 18: + return parseLocalDateTime18(str, off); + case 19: + return parseLocalDateTime19(str, off); + case 20: + return parseLocalDateTime20(str, off); + default: + return parseLocalDateTimeX(str, off, len); } + } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { + public static LocalDate parseLocalDate(String str) { + if (str == null) { return null; } - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + LocalDate localDate; + if (STRING_CODER != null && STRING_VALUE != null && STRING_CODER.applyAsInt(str) == 0) { + byte[] bytes = JDKUtils.STRING_VALUE.apply(str); + localDate = parseLocalDate(bytes, 0, bytes.length); } else { - return null; + char[] chars = JDKUtils.getCharArray(str); + localDate = parseLocalDate(chars, 0, chars.length); } - int millis; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - millis = (m0 - '0') * 100 + (m1 - '0') * 10; - millis *= 1000_000; - } else { - return null; + if (localDate == null) { + switch (str) { + case "": + case "null": + case "00000000": + case "0000年00月00日": + case "0000-0-00": + case "0000-00-00": + return null; + default: + throw new DateTimeParseException(str, str, 0); + } } - return LocalTime.of(hour, minute, second, millis); + return localDate; } - public static LocalTime parseLocalTime11(char[] bytes, int off) { - if (off + 11 > bytes.length) { + public static LocalDate parseLocalDate(byte[] str, int off, int len) { + if (str == null || len == 0) { return null; } - char c0 = bytes[off]; - char c1 = bytes[off + 1]; - char c2 = bytes[off + 2]; - char c3 = bytes[off + 3]; - char c4 = bytes[off + 4]; - char c5 = bytes[off + 5]; - char c6 = bytes[off + 6]; - char c7 = bytes[off + 7]; - char c8 = bytes[off + 8]; - char c9 = bytes[off + 9]; - char c10 = bytes[off + 10]; - - char h0, h1, i0, i1, s0, s1, m0, m1; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - m1 = c10; - } else { - return null; + if (off + len > str.length) { + String input = new String(str, off, len); + throw new DateTimeParseException("illegal input " + input, input, 0); } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; + switch (len) { + case 8: + return parseLocalDate8(str, off); + case 9: + return parseLocalDate9(str, off); + case 10: + return parseLocalDate10(str, off); + case 11: + return parseLocalDate11(str, off); + default: + if (len == 4 && str[off] == 'n' && str[off + 1] == 'u' && str[off + 2] == 'l' && str[off + 3] == 'l') { + return null; + } + String input = new String(str, off, len); + throw new DateTimeParseException("illegal input " + input, input, 0); } + } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { + public static LocalDate parseLocalDate(char[] str, int off, int len) { + if (str == null || len == 0) { return null; } - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; + if (off + len > str.length) { + String input = new String(str, off, len); + throw new DateTimeParseException("illegal input " + input, input, 0); } - int millis; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9') { - millis = (m0 - '0') * 100 + (m1 - '0') * 10; - millis *= 1000_000; - } else { - return null; + switch (len) { + case 8: + return parseLocalDate8(str, off); + case 9: + return parseLocalDate9(str, off); + case 10: + return parseLocalDate10(str, off); + case 11: + return parseLocalDate11(str, off); + default: + if (len == 4 && str[off] == 'n' && str[off + 1] == 'u' && str[off + 2] == 'l' && str[off + 3] == 'l') { + return null; + } + String input = new String(str, off, len); + throw new DateTimeParseException("illegal input " + input, input, 0); } - - return LocalTime.of(hour, minute, second, millis); } - public static LocalTime parseLocalTime12(byte[] bytes, int off) { - if (off + 12 > bytes.length) { - return null; - } + public static long parseMillis(byte[] bytes, int off, int len) { + return parseMillis(bytes, off, len, StandardCharsets.UTF_8, DEFAULT_ZONE_ID); + } - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - byte c5 = bytes[off + 5]; - byte c6 = bytes[off + 6]; - byte c7 = bytes[off + 7]; - byte c8 = bytes[off + 8]; - byte c9 = bytes[off + 9]; - byte c10 = bytes[off + 10]; - byte c11 = bytes[off + 11]; + public static long parseMillis(byte[] bytes, int off, int len, Charset charset) { + return parseMillis(bytes, off, len, charset, DEFAULT_ZONE_ID); + } - byte h0, h1, i0, i1, s0, s1, m0, m1, m2; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - m1 = c10; - m2 = c11; - } else { - return null; + public static long parseMillis(byte[] chars, int off, int len, Charset charset, ZoneId zoneId) { + if (chars == null || len == 0) { + return 0; } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' + if (len == 4 + && chars[off] == 'n' + && chars[off + 1] == 'u' + && chars[off + 2] == 'l' + && chars[off + 3] == 'l' ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; + return 0; } - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' + char c10; + long millis; + char c0 = (char) chars[off]; + if (c0 == '"' && chars[len - 1] == '"') { + try (JSONReader jsonReader = JSONReader.of(chars, off, len, charset)) { + Date date = (Date) ObjectReaderImplDate.INSTANCE.readObject( + jsonReader, + null, + null, + 0 + ); + millis = date.getTime(); + } + } else if (len == 19) { + millis = DateUtils.parseMillis19(chars, off, zoneId); + } else if (len > 19 + // ISO Date with offset example '2011-12-03+01:00' + || (len == 16 && ((c10 = (char) chars[off + 10]) == '+' || c10 == '-')) ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } + ZonedDateTime zdt = parseZonedDateTime(chars, off, len, zoneId); + if (zdt == null) { + String input = new String(chars, off, len - off); + throw new DateTimeParseException("illegal input " + input, input, 0); + } + millis = zdt.toInstant().toEpochMilli(); + } else if ((c0 == '-' || c0 >= '0' && c0 <= '9') && IOUtils.isNumber(chars, off, len)) { + millis = TypeUtils.parseLong(chars, off, len); + if (len == 8 && millis >= 19700101 && millis <= 21000101) { + int year = (int) millis / 10000; + int month = ((int) millis % 10000) / 100; + int dom = (int) millis % 100; - int millis; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - && m2 >= '0' && m2 <= '9' - ) { - millis = (m0 - '0') * 100 + (m1 - '0') * 10 + (m2 - '0'); - millis *= 1000_000; + if (month >= 1 && month <= 12) { + int max = 31; + switch (month) { + case 2: + boolean leapYear = (year & 3) == 0 && ((year % 100) != 0 || (year % 400) == 0); + max = leapYear ? 29 : 28; + break; + case 4: + case 6: + case 9: + case 11: + max = 30; + break; + } + if (dom <= max) { + LocalDateTime ldt = LocalDateTime.of(year, month, dom, 0, 0, 0); + ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); + long seconds = zdt.toEpochSecond(); + millis = seconds * 1000L; + } + } + } } else { - return null; + char last = (char) chars[len - 1]; + if (last == 'Z') { + zoneId = UTC; + } + LocalDateTime ldt = DateUtils.parseLocalDateTime(chars, off, len); + if (ldt == null + // && "0000-00-00".equals(str) + && chars[off] == '0' + && chars[off + 1] == '0' + && chars[off + 2] == '0' + && chars[off + 3] == '0' + && chars[off + 4] == '-' + && chars[off + 5] == '0' + && chars[off + 6] == '0' + && chars[off + 7] == '-' + && chars[off + 8] == '0' + && chars[off + 9] == '0' + ) { + ldt = LocalDateTime.of(1970, 1, 1, 0, 0, 0); + } + ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); + long seconds = zdt.toEpochSecond(); + int nanos = ldt.getNano(); + if (seconds < 0 && nanos > 0) { + millis = (seconds + 1) * 1000 + nanos / 1000_000 - 1000; + } else { + millis = seconds * 1000L + nanos / 1000_000; + } } - - return LocalTime.of(hour, minute, second, millis); + return millis; } - public static LocalTime parseLocalTime12(char[] bytes, int off) { - if (off + 12 > bytes.length) { - return null; - } - - char c0 = bytes[off]; - char c1 = bytes[off + 1]; - char c2 = bytes[off + 2]; - char c3 = bytes[off + 3]; - char c4 = bytes[off + 4]; - char c5 = bytes[off + 5]; - char c6 = bytes[off + 6]; - char c7 = bytes[off + 7]; - char c8 = bytes[off + 8]; - char c9 = bytes[off + 9]; - char c10 = bytes[off + 10]; - char c11 = bytes[off + 11]; - - char h0, h1, i0, i1, s0, s1, m0, m1, m2; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - m1 = c10; - m2 = c11; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - int millis; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - && m2 >= '0' && m2 <= '9' - ) { - millis = (m0 - '0') * 100 + (m1 - '0') * 10 + (m2 - '0'); - millis *= 1000_000; - } else { - return null; - } - - return LocalTime.of(hour, minute, second, millis); + public static long parseMillis(char[] bytes, int off, int len) { + return parseMillis(bytes, off, len, DEFAULT_ZONE_ID); } - public static LocalTime parseLocalTime18(byte[] bytes, int off) { - if (off + 18 > bytes.length) { - return null; - } - - byte c0 = bytes[off]; - byte c1 = bytes[off + 1]; - byte c2 = bytes[off + 2]; - byte c3 = bytes[off + 3]; - byte c4 = bytes[off + 4]; - byte c5 = bytes[off + 5]; - byte c6 = bytes[off + 6]; - byte c7 = bytes[off + 7]; - byte c8 = bytes[off + 8]; - byte c9 = bytes[off + 9]; - byte c10 = bytes[off + 10]; - byte c11 = bytes[off + 11]; - byte c12 = bytes[off + 12]; - byte c13 = bytes[off + 13]; - byte c14 = bytes[off + 14]; - byte c15 = bytes[off + 15]; - byte c16 = bytes[off + 16]; - byte c17 = bytes[off + 17]; - - byte h0, h1, i0, i1, s0, s1, m0, m1, m2, m3, m4, m5, m6, m7, m8; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - m1 = c10; - m2 = c11; - m3 = c12; - m4 = c13; - m5 = c14; - m6 = c15; - m7 = c16; - m8 = c17; - } else { - return null; + public static long parseMillis(char[] chars, int off, int len, ZoneId zoneId) { + if (chars == null || len == 0) { + return 0; } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' + if (len == 4 + && chars[off] == 'n' + && chars[off + 1] == 'u' + && chars[off + 2] == 'l' + && chars[off + 3] == 'l' ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; + return 0; } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' + char c10; + long millis; + char c0 = chars[off]; + if (c0 == '"' && chars[len - 1] == '"') { + try (JSONReader jsonReader = JSONReader.of(chars, off, len)) { + Date date = (Date) ObjectReaderImplDate.INSTANCE.readObject( + jsonReader, + null, + null, + 0 + ); + millis = date.getTime(); + } + } else if (len == 19) { + millis = DateUtils.parseMillis19(chars, off, zoneId); + } else if (len > 19 + // ISO Date with offset example '2011-12-03+01:00' + || (len == 16 && ((c10 = chars[off + 10]) == '+' || c10 == '-')) ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } + ZonedDateTime zdt = parseZonedDateTime(chars, off, len, zoneId); + if (zdt == null) { + String input = new String(chars, off, len - off); + throw new DateTimeParseException("illegal input " + input, input, 0); + } + millis = zdt.toInstant().toEpochMilli(); + } else if ((c0 == '-' || c0 >= '0' && c0 <= '9') && IOUtils.isNumber(chars, off, len)) { + millis = TypeUtils.parseLong(chars, off, len); + if (len == 8 && millis >= 19700101 && millis <= 21000101) { + int year = (int) millis / 10000; + int month = ((int) millis % 10000) / 100; + int dom = (int) millis % 100; - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + if (month >= 1 && month <= 12) { + int max = 31; + switch (month) { + case 2: + boolean leapYear = (year & 3) == 0 && ((year % 100) != 0 || (year % 400) == 0); + max = leapYear ? 29 : 28; + break; + case 4: + case 6: + case 9: + case 11: + max = 30; + break; + } + if (dom <= max) { + LocalDateTime ldt = LocalDateTime.of(year, month, dom, 0, 0, 0); + ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); + long seconds = zdt.toEpochSecond(); + millis = seconds * 1000L; + } + } + } } else { - return null; - } - - int millis; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - && m2 >= '0' && m2 <= '9' - && m3 >= '0' && m3 <= '9' - && m4 >= '0' && m4 <= '9' - && m5 >= '0' && m5 <= '9' - && m6 >= '0' && m6 <= '9' - && m7 >= '0' && m7 <= '9' - && m8 >= '0' && m8 <= '9' - ) { - millis = (m0 - '0') * 1000_000_00 - + (m1 - '0') * 1000_000_0 - + (m2 - '0') * 1000_000 - + (m3 - '0') * 1000_00 - + (m4 - '0') * 1000_0 - + (m5 - '0') * 1000 - + (m6 - '0') * 100 - + (m7 - '0') * 10 - + (m8 - '0'); - } else { - return null; - } - - return LocalTime.of(hour, minute, second, millis); - } - - public static LocalTime parseLocalTime18(char[] bytes, int off) { - if (off + 18 > bytes.length) { - return null; - } - - char c0 = bytes[off]; - char c1 = bytes[off + 1]; - char c2 = bytes[off + 2]; - char c3 = bytes[off + 3]; - char c4 = bytes[off + 4]; - char c5 = bytes[off + 5]; - char c6 = bytes[off + 6]; - char c7 = bytes[off + 7]; - char c8 = bytes[off + 8]; - char c9 = bytes[off + 9]; - char c10 = bytes[off + 10]; - char c11 = bytes[off + 11]; - char c12 = bytes[off + 12]; - char c13 = bytes[off + 13]; - char c14 = bytes[off + 14]; - char c15 = bytes[off + 15]; - char c16 = bytes[off + 16]; - char c17 = bytes[off + 17]; - - char h0, h1, i0, i1, s0, s1, m0, m1, m2, m3, m4, m5, m6, m7, m8; - if (c2 == ':' && c5 == ':' && c8 == '.') { - h0 = c0; - h1 = c1; - i0 = c3; - i1 = c4; - s0 = c6; - s1 = c7; - m0 = c9; - m1 = c10; - m2 = c11; - m3 = c12; - m4 = c13; - m5 = c14; - m6 = c15; - m7 = c16; - m8 = c17; - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - int millis; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - && m2 >= '0' && m2 <= '9' - && m3 >= '0' && m3 <= '9' - && m4 >= '0' && m4 <= '9' - && m5 >= '0' && m5 <= '9' - && m6 >= '0' && m6 <= '9' - && m7 >= '0' && m7 <= '9' - && m8 >= '0' && m8 <= '9' - ) { - millis = (m0 - '0') * 1000_000_00 - + (m1 - '0') * 1000_000_0 - + (m2 - '0') * 1000_000 - + (m3 - '0') * 1000_00 - + (m4 - '0') * 1000_0 - + (m5 - '0') * 1000 - + (m6 - '0') * 100 - + (m7 - '0') * 10 - + (m8 - '0'); - } else { - return null; - } - - return LocalTime.of(hour, minute, second, millis); - } - - public static LocalDateTime parseLocalDateTime(byte[] str, int off, int len) { - if (str == null || len == 0) { - return null; - } - - switch (len) { - case 4: - if (str[off] == 'n' && str[off + 1] == 'u' && str[off + 2] == 'l' && str[off + 3] == 'l') { - return null; - } - String input = new String(str, off, len); - throw new DateTimeParseException("illegal input " + input, input, 0); - case 8: { - LocalDate localDate = parseLocalDate8(str, off); - if (localDate == null) { - return null; - } - return LocalDateTime.of(localDate, LocalTime.MIN); - } - case 9: { - LocalDate localDate = parseLocalDate9(str, off); - if (localDate == null) { - return null; - } - return LocalDateTime.of(localDate, LocalTime.MIN); - } - case 10: { - LocalDate localDate = parseLocalDate10(str, off); - if (localDate == null) { - return null; - } - return LocalDateTime.of(localDate, LocalTime.MIN); - } - case 11: { - return LocalDateTime.of( - parseLocalDate11(str, off), - LocalTime.MIN - ); - } - case 12: - return parseLocalDateTime12(str, off); - case 14: - return parseLocalDateTime14(str, off); - case 16: - return parseLocalDateTime16(str, off); - case 17: - return parseLocalDateTime17(str, off); - case 18: - return parseLocalDateTime18(str, off); - case 19: - return parseLocalDateTime19(str, off); - case 20: - return parseLocalDateTime20(str, off); - default: - return parseLocalDateTimeX(str, off, len); - } - } - - public static LocalDate parseLocalDate(String str) { - if (str == null) { - return null; - } - - LocalDate localDate; - if (STRING_CODER != null && STRING_VALUE != null && STRING_CODER.applyAsInt(str) == 0) { - byte[] bytes = JDKUtils.STRING_VALUE.apply(str); - localDate = parseLocalDate(bytes, 0, bytes.length); - } else { - char[] chars = JDKUtils.getCharArray(str); - localDate = parseLocalDate(chars, 0, chars.length); - } - - if (localDate == null) { - switch (str) { - case "": - case "null": - case "00000000": - case "0000年00月00日": - case "0000-0-00": - case "0000-00-00": - return null; - default: - throw new DateTimeParseException(str, str, 0); - } - } - - return localDate; - } - - public static LocalDate parseLocalDate(byte[] str, int off, int len) { - if (str == null || len == 0) { - return null; - } - - if (off + len > str.length) { - String input = new String(str, off, len); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - switch (len) { - case 8: - return parseLocalDate8(str, off); - case 9: - return parseLocalDate9(str, off); - case 10: - return parseLocalDate10(str, off); - case 11: - return parseLocalDate11(str, off); - default: - if (len == 4 && str[off] == 'n' && str[off + 1] == 'u' && str[off + 2] == 'l' && str[off + 3] == 'l') { - return null; - } - String input = new String(str, off, len); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - } - - public static LocalDate parseLocalDate(char[] str, int off, int len) { - if (str == null || len == 0) { - return null; - } - - if (off + len > str.length) { - String input = new String(str, off, len); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - switch (len) { - case 8: - return parseLocalDate8(str, off); - case 9: - return parseLocalDate9(str, off); - case 10: - return parseLocalDate10(str, off); - case 11: - return parseLocalDate11(str, off); - default: - if (len == 4 && str[off] == 'n' && str[off + 1] == 'u' && str[off + 2] == 'l' && str[off + 3] == 'l') { - return null; - } - String input = new String(str, off, len); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - } - - public static long parseMillis(byte[] bytes, int off, int len) { - return parseMillis(bytes, off, len, StandardCharsets.UTF_8, DEFAULT_ZONE_ID); - } - - public static long parseMillis(byte[] bytes, int off, int len, Charset charset) { - return parseMillis(bytes, off, len, charset, DEFAULT_ZONE_ID); - } - - public static long parseMillis(byte[] chars, int off, int len, Charset charset, ZoneId zoneId) { - if (chars == null || len == 0) { - return 0; - } - - if (len == 4 - && chars[off] == 'n' - && chars[off + 1] == 'u' - && chars[off + 2] == 'l' - && chars[off + 3] == 'l' - ) { - return 0; - } - - char c10; - long millis; - char c0 = (char) chars[off]; - if (c0 == '"' && chars[len - 1] == '"') { - try (JSONReader jsonReader = JSONReader.of(chars, off, len, charset)) { - Date date = (Date) ObjectReaderImplDate.INSTANCE.readObject( - jsonReader, - null, - null, - 0 - ); - millis = date.getTime(); - } - } else if (len == 19) { - millis = DateUtils.parseMillis19(chars, off, zoneId); - } else if (len > 19 - // ISO Date with offset example '2011-12-03+01:00' - || (len == 16 && ((c10 = (char) chars[off + 10]) == '+' || c10 == '-')) - ) { - ZonedDateTime zdt = parseZonedDateTime(chars, off, len, zoneId); - if (zdt == null) { - String input = new String(chars, off, len - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - millis = zdt.toInstant().toEpochMilli(); - } else if ((c0 == '-' || c0 >= '0' && c0 <= '9') && IOUtils.isNumber(chars, off, len)) { - millis = TypeUtils.parseLong(chars, off, len); - if (len == 8 && millis >= 19700101 && millis <= 21000101) { - int year = (int) millis / 10000; - int month = ((int) millis % 10000) / 100; - int dom = (int) millis % 100; - - if (month >= 1 && month <= 12) { - int max = 31; - switch (month) { - case 2: - boolean leapYear = (year & 3) == 0 && ((year % 100) != 0 || (year % 400) == 0); - max = leapYear ? 29 : 28; - break; - case 4: - case 6: - case 9: - case 11: - max = 30; - break; - } - if (dom <= max) { - LocalDateTime ldt = LocalDateTime.of(year, month, dom, 0, 0, 0); - ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); - long seconds = zdt.toEpochSecond(); - millis = seconds * 1000L; - } - } - } - } else { - char last = (char) chars[len - 1]; - if (last == 'Z') { - zoneId = UTC; - } - LocalDateTime ldt = DateUtils.parseLocalDateTime(chars, off, len); - if (ldt == null - // && "0000-00-00".equals(str) - && chars[off] == '0' - && chars[off + 1] == '0' - && chars[off + 2] == '0' - && chars[off + 3] == '0' - && chars[off + 4] == '-' - && chars[off + 5] == '0' - && chars[off + 6] == '0' - && chars[off + 7] == '-' - && chars[off + 8] == '0' - && chars[off + 9] == '0' - ) { - ldt = LocalDateTime.of(1970, 1, 1, 0, 0, 0); - } - ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); - long seconds = zdt.toEpochSecond(); - int nanos = ldt.getNano(); - if (seconds < 0 && nanos > 0) { - millis = (seconds + 1) * 1000 + nanos / 1000_000 - 1000; - } else { - millis = seconds * 1000L + nanos / 1000_000; - } - } - return millis; - } - - public static long parseMillis(char[] bytes, int off, int len) { - return parseMillis(bytes, off, len, DEFAULT_ZONE_ID); - } - - public static long parseMillis(char[] chars, int off, int len, ZoneId zoneId) { - if (chars == null || len == 0) { - return 0; - } - - if (len == 4 - && chars[off] == 'n' - && chars[off + 1] == 'u' - && chars[off + 2] == 'l' - && chars[off + 3] == 'l' - ) { - return 0; - } - - char c10; - long millis; - char c0 = chars[off]; - if (c0 == '"' && chars[len - 1] == '"') { - try (JSONReader jsonReader = JSONReader.of(chars, off, len)) { - Date date = (Date) ObjectReaderImplDate.INSTANCE.readObject( - jsonReader, - null, - null, - 0 - ); - millis = date.getTime(); - } - } else if (len == 19) { - millis = DateUtils.parseMillis19(chars, off, zoneId); - } else if (len > 19 - // ISO Date with offset example '2011-12-03+01:00' - || (len == 16 && ((c10 = chars[off + 10]) == '+' || c10 == '-')) - ) { - ZonedDateTime zdt = parseZonedDateTime(chars, off, len, zoneId); - if (zdt == null) { - String input = new String(chars, off, len - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - millis = zdt.toInstant().toEpochMilli(); - } else if ((c0 == '-' || c0 >= '0' && c0 <= '9') && IOUtils.isNumber(chars, off, len)) { - millis = TypeUtils.parseLong(chars, off, len); - if (len == 8 && millis >= 19700101 && millis <= 21000101) { - int year = (int) millis / 10000; - int month = ((int) millis % 10000) / 100; - int dom = (int) millis % 100; - - if (month >= 1 && month <= 12) { - int max = 31; - switch (month) { - case 2: - boolean leapYear = (year & 3) == 0 && ((year % 100) != 0 || (year % 400) == 0); - max = leapYear ? 29 : 28; - break; - case 4: - case 6: - case 9: - case 11: - max = 30; - break; - } - if (dom <= max) { - LocalDateTime ldt = LocalDateTime.of(year, month, dom, 0, 0, 0); - ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); - long seconds = zdt.toEpochSecond(); - millis = seconds * 1000L; - } - } - } - } else { - char last = chars[len - 1]; - if (last == 'Z') { - len--; - zoneId = UTC; - } - LocalDateTime ldt = DateUtils.parseLocalDateTime(chars, off, len); - if (ldt == null - // && "0000-00-00".equals(str) - && chars[off] == '0' - && chars[off + 1] == '0' - && chars[off + 2] == '0' - && chars[off + 3] == '0' - && chars[off + 4] == '-' - && chars[off + 5] == '0' - && chars[off + 6] == '0' - && chars[off + 7] == '-' - && chars[off + 8] == '0' - && chars[off + 9] == '0' - ) { - ldt = LocalDateTime.of(1970, 1, 1, 0, 0, 0); - } - - if (ldt == null) { - String input = new String(chars, off, len - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); - long seconds = zdt.toEpochSecond(); - int nanos = ldt.getNano(); - if (seconds < 0 && nanos > 0) { - millis = (seconds + 1) * 1000 + nanos / 1000_000 - 1000; - } else { - millis = seconds * 1000L + nanos / 1000_000; - } - } - return millis; - } - - /** - * yyyy-m-d - * yyyyMMdd - * d-MMM-yy - */ - public static LocalDate parseLocalDate8(byte[] str, int off) { - if (off + 8 > str.length) { - return null; - } - - char c1 = (char) str[off + 1]; - char c3 = (char) str[off + 3]; - char c4 = (char) str[off + 4]; - - int year, month, dom; - if (c4 == '-' && str[off + 6] == '-') { - year = digit4(str, off); - month = digit1(str, off + 5); - dom = digit1(str, off + 7); - } else if (c1 == '/' && c3 == '/') { - month = digit1(str, off); - dom = digit1(str, off + 2); - year = digit4(str, off + 4); - } else if (c1 == '-' && str[off + 5] == '-') { - // d-MMM-yy - dom = digit1(str, off); - month = DateUtils.month((char) str[off + 2], c3, c4); - year = digit2(str, off + 6); - if (year != -1) { - year += 2000; - } - } else { - year = digit4(str, off); - month = digit2(str, off + 4); - dom = digit2(str, off + 6); - } - - if ((year == 0 && month == 0 && dom == 0) || (year | month | dom) < 0) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * yyyy-m-d - * yyyyMMdd - * d-MMM-yy - */ - public static LocalDate parseLocalDate8(char[] str, int off) { - if (off + 8 > str.length) { - return null; - } - - char c1 = str[off + 1]; - char c3 = str[off + 3]; - char c4 = str[off + 4]; - - int year, month, dom; - if (c4 == '-' && str[off + 6] == '-') { - year = digit4(str, off); - month = digit1(str, off + 5); - dom = digit1(str, off + 7); - } else if (c1 == '/' && c3 == '/') { - month = digit1(str, off); - dom = digit1(str, off + 2); - year = digit4(str, off + 4); - } else if (c1 == '-' && str[off + 5] == '-') { - // d-MMM-yy - dom = digit1(str, off); - month = DateUtils.month((char) str[off + 2], c3, c4); - year = digit2(str, off + 6); - if (year != -1) { - year += 2000; - } - } else { - year = digit4(str, off); - month = digit2(str, off + 4); - dom = digit2(str, off + 6); - } - - if ((year == 0 && month == 0 && dom == 0) || (year | month | dom) < 0) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * yyyy-MM-d - * yyyy-M-dd - * dd-MMM-yy - */ - public static LocalDate parseLocalDate9(byte[] str, int off) { - if (off + 9 > str.length) { - return null; - } - - char c0 = (char) str[off]; - char c1 = (char) str[off + 1]; - char c2 = (char) str[off + 2]; - char c3 = (char) str[off + 3]; - char c4 = (char) str[off + 4]; - char c5 = (char) str[off + 5]; - char c6 = (char) str[off + 6]; - char c7 = (char) str[off + 7]; - char c8 = (char) str[off + 8]; - - char y0, y1, y2, y3, m0, m1, d0, d1; - if (c4 == '-' && c7 == '-') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - } else if (c4 == '-' && c6 == '-') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - } else if (c4 == '/' && c7 == '/') { // tw : yyyy/mm/d - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - } else if (c4 == '/' && c6 == '/') { // tw : yyyy/m/dd - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - } else if (c1 == '.' && c4 == '.') { - d0 = '0'; - d1 = c0; - - m0 = c2; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '.' && c4 == '.') { - d0 = c0; - d1 = c1; - - m0 = '0'; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c1 == '-' && c4 == '-') { - d0 = '0'; - d1 = c0; - - m0 = c2; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '-' && c4 == '-') { - d0 = c0; - d1 = c1; - - m0 = '0'; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '-' && c6 == '-') { - // dd-MMM-yy - d0 = c0; - d1 = c1; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = '2'; - y1 = '0'; - y2 = c7; - y3 = c8; - } else if (c1 == '/' && c4 == '/') { - // M/dd/dddd - m0 = '0'; - m1 = c0; - - d0 = c2; - d1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '/' && c4 == '/') { - // MM/d/dddd - m0 = c0; - m1 = c1; - - d0 = '0'; - d1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else { - return null; - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - if (year == 0 && month == 0 && dom == 0) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * yyyy-MM-d - * yyyy-M-dd - * dd-MMM-yy - */ - public static LocalDate parseLocalDate9(char[] str, int off) { - if (off + 9 > str.length) { - return null; - } - - char c0 = str[off]; - char c1 = str[off + 1]; - char c2 = str[off + 2]; - char c3 = str[off + 3]; - char c4 = str[off + 4]; - char c5 = str[off + 5]; - char c6 = str[off + 6]; - char c7 = str[off + 7]; - char c8 = str[off + 8]; - - char y0, y1, y2, y3, m0, m1, d0, d1; - if (c4 == '-' && c7 == '-') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - } else if (c4 == '-' && c6 == '-') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - } else if (c4 == '/' && c7 == '/') { // tw : yyyy/mm/d - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - } else if (c4 == '/' && c6 == '/') { // tw : yyyy/m/dd - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - } else if (c1 == '.' && c4 == '.') { - d0 = '0'; - d1 = c0; - - m0 = c2; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '.' && c4 == '.') { - d0 = c0; - d1 = c1; - - m0 = '0'; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c1 == '-' && c4 == '-') { - d0 = '0'; - d1 = c0; - - m0 = c2; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '-' && c4 == '-') { - d0 = c0; - d1 = c1; - - m0 = '0'; - m1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c4 == '年' && c6 == '月' && c8 == '日') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = '0'; - d1 = c7; - } else if (c4 == '년' && c6 == '월' && c8 == '일') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = '0'; - d1 = c7; - } else if (c2 == '-' && c6 == '-') { - // dd-MMM-yy - d0 = c0; - d1 = c1; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = '2'; - y1 = '0'; - y2 = c7; - y3 = c8; - } else if (c1 == '/' && c4 == '/') { - // M/dd/dddd - m0 = '0'; - m1 = c0; - - d0 = c2; - d1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else if (c2 == '/' && c4 == '/') { - // MM/d/dddd - m0 = c0; - m1 = c1; - - d0 = '0'; - d1 = c3; - - y0 = c5; - y1 = c6; - y2 = c7; - y3 = c8; - } else { - return null; - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - if (year == 0 && month == 0 && dom == 0) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * yyyy-MM-dd - * yyyy/MM/dd - * MM/dd/yyyy - * dd.MM.yyyy - * yyyy年M月dd日 - * yyyy年MM月d日 - * yyyy MMM d - */ - public static LocalDate parseLocalDate10(byte[] str, int off) { - if (off + 10 > str.length) { - return null; - } - - char c0 = (char) str[off]; - char c1 = (char) str[off + 1]; - char c2 = (char) str[off + 2]; - char c3 = (char) str[off + 3]; - char c4 = (char) str[off + 4]; - char c5 = (char) str[off + 5]; - char c6 = (char) str[off + 6]; - char c7 = (char) str[off + 7]; - char c8 = (char) str[off + 8]; - char c9 = (char) str[off + 9]; - - char y0, y1, y2, y3, m0, m1, d0, d1; - if (c4 == '-' && c7 == '-') { - // yyyy-MM-dd - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - } else if (c4 == '/' && c7 == '/') { - // tw : yyyy/mm/dd - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - } else if (c2 == '.' && c5 == '.') { - // dd.MM.yyyy - d0 = c0; - d1 = c1; - - m0 = c3; - m1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - } else if (c2 == '-' && c5 == '-') { - // dd-MM-yyyy - d0 = c0; - d1 = c1; - - m0 = c3; - m1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - } else if (c2 == '/' && c5 == '/') { - // MM/dd/yyyy - m0 = c0; - m1 = c1; - - d0 = c3; - d1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - } else if (c1 == ' ' && c5 == ' ') { - // yyyy MMM d - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - d0 = '0'; - d1 = c0; - } else { - return null; - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - if (year == 0 && month == 0 && dom == 0) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * yyyy-MM-dd - * yyyy/MM/dd - * MM/dd/yyyy - * dd.MM.yyyy - * yyyy年M月dd日 - * yyyy年MM月d日 - * yyyy MMM d - */ - public static LocalDate parseLocalDate10(char[] str, int off) { - if (off + 10 > str.length) { - return null; - } - - char c0 = str[off]; - char c1 = str[off + 1]; - char c2 = str[off + 2]; - char c3 = str[off + 3]; - char c4 = str[off + 4]; - char c5 = str[off + 5]; - char c6 = str[off + 6]; - char c7 = str[off + 7]; - char c8 = str[off + 8]; - char c9 = str[off + 9]; - - char y0, y1, y2, y3, m0, m1, d0, d1; - if (c4 == '-' && c7 == '-') { - // yyyy-MM-dd - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - } else if (c4 == '/' && c7 == '/') { - // tw : yyyy/mm/dd - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - } else if (c2 == '.' && c5 == '.') { - // dd.MM.yyyy - d0 = c0; - d1 = c1; - - m0 = c3; - m1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - } else if (c2 == '-' && c5 == '-') { - // dd-MM-yyyy - d0 = c0; - d1 = c1; - - m0 = c3; - m1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - } else if (c2 == '/' && c5 == '/') { - // MM/dd/yyyy - m0 = c0; - m1 = c1; - - d0 = c3; - d1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - } else if (c4 == '年' && c6 == '月' && c9 == '日') { - // yyyy年M月dd日 - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - } else if (c4 == '년' && c6 == '월' && c9 == '일') { - // yyyy년M월dd일 - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - } else if (c4 == '年' && c7 == '月' && c9 == '日') { - // // yyyy年MM月d日 - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - } else if (c4 == '년' && c7 == '월' && c9 == '일') { - // yyyy년MM월d일 - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - } else if (c1 == ' ' && c5 == ' ') { - // yyyy MMM d - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - d0 = '0'; - d1 = c0; - } else { - return null; - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - if (year == 0 && month == 0 && dom == 0) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * yyyy年MM月dd日 - * yyyy년MM월dd일 - */ - public static LocalDate parseLocalDate11(char[] str, int off) { - if (off + 11 > str.length) { - return null; - } - - char c4 = str[off + 4]; - char c7 = str[off + 7]; - char c10 = str[off + 10]; - - int year, month, dom; - if ((c4 == '年' && c7 == '月' && c10 == '日') || (c4 == '-' && c7 == '-' && c10 == 'Z') || (c4 == '년' && c7 == '월' && c10 == '일')) { - year = digit4(str, off); - month = digit2(str, off + 5); - dom = digit2(str, off + 8); - } else if (str[off + 2] == ' ' && str[off + 6] == ' ') { - year = digit4(str, off + 7); - month = DateUtils.month(str[off + 3], c4, str[off + 5]); - dom = digit2(str, off); - } else { - return null; - } - - if ((year | month | dom) < 0 || (year == 0 && month == 0 && dom == 0)) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - /** - * - */ - public static LocalDate parseLocalDate11(byte[] str, int off) { - if (off + 11 > str.length) { - return null; - } - - int year, month, dom; - if (str[off + 4] == '-' && str[off + 7] == '-' && str[off + 10] == 'Z') { - year = digit4(str, off); - month = digit2(str, off + 5); - dom = digit2(str, off + 8); - } else if (str[off + 2] == ' ' && str[off + 6] == ' ') { - year = digit4(str, off + 7); - month = DateUtils.month((char) str[off + 3], (char) str[off + 4], (char) str[off + 5]); - dom = digit2(str, off); - } else { - return null; - } - - if ((year | month | dom) < 0 || (year == 0 && month == 0 && dom == 0)) { - return null; - } - - return LocalDate.of(year, month, dom); - } - - public static LocalDateTime parseLocalDateTime12(char[] str, int off) { - if (off + 12 > str.length) { - String input = new String(str, off, str.length - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - int year = digit4(str, off); - int month = digit2(str, off + 4); - int dom = digit2(str, off + 6); - int hour = digit2(str, off + 8); - int minute = digit2(str, off + 10); - - if ((year | month | dom | hour | minute) < 0) { - String input = new String(str, off, off + 12); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - if (year == 0 && month == 0 && dom == 0 && hour == 0 && minute == 0) { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, 0); - } - - /** - * parseLocalDateTime use format 'yyyyMMddHHmm' - */ - public static LocalDateTime parseLocalDateTime12(byte[] str, int off) { - if (off + 12 > str.length) { - String input = new String(str, off, str.length - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - int year = digit4(str, off); - int month = digit2(str, off + 4); - int dom = digit2(str, off + 6); - int hour = digit2(str, off + 8); - int minute = digit2(str, off + 10); - - if ((year | month | dom | hour | minute) < 0) { - String input = new String(str, off, off + 12); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - if (year == 0 && month == 0 && dom == 0 && hour == 0 && minute == 0) { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, 0); - } - - /** - * yyyyMMddHHmmss - */ - public static LocalDateTime parseLocalDateTime14(char[] str, int off) { - if (off + 14 > str.length) { - return null; - } - - char y0 = str[off]; - char y1 = str[off + 1]; - char y2 = str[off + 2]; - char y3 = str[off + 3]; - char m0 = str[off + 4]; - char m1 = str[off + 5]; - char d0 = str[off + 6]; - char d1 = str[off + 7]; - char h0 = str[off + 8]; - char h1 = str[off + 9]; - char i0 = str[off + 10]; - char i1 = str[off + 11]; - char s0 = str[off + 12]; - char s1 = str[off + 13]; - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, second); - } - - /** - * yyyyMMddHHmmss - */ - public static LocalDateTime parseLocalDateTime14(byte[] str, int off) { - if (off + 14 > str.length) { - return null; - } - - char y0 = (char) str[off]; - char y1 = (char) str[off + 1]; - char y2 = (char) str[off + 2]; - char y3 = (char) str[off + 3]; - char m0 = (char) str[off + 4]; - char m1 = (char) str[off + 5]; - char d0 = (char) str[off + 6]; - char d1 = (char) str[off + 7]; - char h0 = (char) str[off + 8]; - char h1 = (char) str[off + 9]; - char i0 = (char) str[off + 10]; - char i1 = (char) str[off + 11]; - char s0 = (char) str[off + 12]; - char s1 = (char) str[off + 13]; - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, second); - } - - /** - * yyyy-MM-ddTHH:mm - * yyyy-MM-dd HH:mm - * yyyyMMddTHHmmssZ - * yyyy-MM-ddTH:m:s - * yyyy-MM-dd H:m:s - */ - public static LocalDateTime parseLocalDateTime16(char[] str, int off) { - if (off + 16 > str.length) { - return null; - } - - char c0 = str[off]; - char c1 = str[off + 1]; - char c2 = str[off + 2]; - char c3 = str[off + 3]; - char c4 = str[off + 4]; - char c5 = str[off + 5]; - char c6 = str[off + 6]; - char c7 = str[off + 7]; - char c8 = str[off + 8]; - char c9 = str[off + 9]; - char c10 = str[off + 10]; - char c11 = str[off + 11]; - char c12 = str[off + 12]; - char c13 = str[off + 13]; - char c14 = str[off + 14]; - char c15 = str[off + 15]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0 = '0', s1 = '0'; - if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - } else if (c8 == 'T' && c15 == 'Z') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - m0 = c4; - m1 = c5; - d0 = c6; - d1 = c7; - h0 = c9; - h1 = c10; - i0 = c11; - i1 = c12; - s0 = c13; - s1 = c14; - } else if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c12 == ':' && c14 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = '0'; - h1 = c11; - - i0 = '0'; - i1 = c13; - - s1 = c15; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':') { - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - d0 = '0'; - d1 = c0; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { - // d MMM yyyy H:m:ss - // 6 DEC 2020 2:3:14 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = '0'; - h1 = c11; - - i0 = '0'; - i1 = c13; - - s1 = c15; - } else { - return null; - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, second); - } - - /** - * yyyy-MM-ddTHH:mm - * yyyy-MM-dd HH:mm - * yyyyMMddTHHmmssZ - * yyyy-MM-ddTH:m:s - * yyyy-MM-dd H:m:s - */ - public static LocalDateTime parseLocalDateTime16(byte[] str, int off) { - if (off + 16 > str.length) { - return null; - } - - byte c0 = str[off]; - byte c1 = str[off + 1]; - byte c2 = str[off + 2]; - byte c3 = str[off + 3]; - byte c4 = str[off + 4]; - byte c5 = str[off + 5]; - byte c6 = str[off + 6]; - byte c7 = str[off + 7]; - byte c8 = str[off + 8]; - byte c9 = str[off + 9]; - byte c10 = str[off + 10]; - byte c11 = str[off + 11]; - byte c12 = str[off + 12]; - byte c13 = str[off + 13]; - byte c14 = str[off + 14]; - byte c15 = str[off + 15]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0 = '0', s1 = '0'; - if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':') { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = (char) c5; - m1 = (char) c6; - - d0 = (char) c8; - d1 = (char) c9; - - h0 = (char) c11; - h1 = (char) c12; - - i0 = (char) c14; - i1 = (char) c15; - } else if (c8 == 'T' && c15 == 'Z') { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - m0 = (char) c4; - m1 = (char) c5; - d0 = (char) c6; - d1 = (char) c7; - h0 = (char) c9; - h1 = (char) c10; - i0 = (char) c11; - i1 = (char) c12; - s0 = (char) c13; - s1 = (char) c14; - } else if (c4 == -27 && c5 == -71 && c6 == -76 // 年 - && c8 == -26 && c9 == -100 && c10 == -120 // 月 - && c13 == -26 && c14 == -105 && c15 == -91 // 日 - ) { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = '0'; - m1 = (char) c7; - - d0 = (char) c11; - d1 = (char) c12; - - h0 = '0'; - h1 = '0'; - - i0 = '0'; - i1 = '0'; - } else if (c4 == -27 && c5 == -71 && c6 == -76 // 年 - && c9 == -26 && c10 == -100 && c11 == -120 // 月 - && c13 == -26 && c14 == -105 && c15 == -91 // 日 - ) { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = (char) c7; - m1 = (char) c8; - - d0 = '0'; - d1 = (char) c12; - - h0 = '0'; - h1 = '0'; - - i0 = '0'; - i1 = '0'; - } else if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c12 == ':' && c14 == ':') { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = (char) c5; - m1 = (char) c6; - - d0 = (char) c8; - d1 = (char) c9; - - h0 = '0'; - h1 = (char) c11; - - i0 = '0'; - i1 = (char) c13; - - s1 = (char) c15; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':') { - y0 = (char) c6; - y1 = (char) c7; - y2 = (char) c8; - y3 = (char) c9; - - int month = DateUtils.month((char) c2, (char) c3, (char) c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - d0 = '0'; - d1 = (char) c0; - - h0 = (char) c11; - h1 = (char) c12; - - i0 = (char) c14; - i1 = (char) c15; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { - // d MMM yyyy H:m:ss - // 6 DEC 2020 2:3:14 - d0 = '0'; - d1 = (char) c0; - - int month = DateUtils.month((char) c2, (char) c3, (char) c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = (char) c6; - y1 = (char) c7; - y2 = (char) c8; - y3 = (char) c9; - - h0 = '0'; - h1 = (char) c11; - - i0 = '0'; - i1 = (char) c13; - - s1 = (char) c15; - } else { - return null; - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, second); - } - - /** - * yyyy-MM-ddTHH:mmZ - * yyyy-MM-dd HH:mmZ - * yyyy-M-dTHH:mm:ss - * yyyy-M-d HH:mm:ss - */ - public static LocalDateTime parseLocalDateTime17(char[] str, int off) { - if (off + 17 > str.length) { - String input = new String(str, off, str.length - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - char c0 = str[off]; - char c1 = str[off + 1]; - char c2 = str[off + 2]; - char c3 = str[off + 3]; - char c4 = str[off + 4]; - char c5 = str[off + 5]; - char c6 = str[off + 6]; - char c7 = str[off + 7]; - char c8 = str[off + 8]; - char c9 = str[off + 9]; - char c10 = str[off + 10]; - char c11 = str[off + 11]; - char c12 = str[off + 12]; - char c13 = str[off + 13]; - char c14 = str[off + 14]; - char c15 = str[off + 15]; - char c16 = str[off + 16]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1; - int nanoOfSecond = 0; - if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':' && c16 == 'Z') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = '0'; - s1 = '0'; - } else if (c4 == '-' && c6 == '-' && (c8 == ' ' || c8 == 'T') && c11 == ':' && c14 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = '0'; - d1 = c7; - - h0 = c9; - h1 = c10; - - i0 = c12; - i1 = c13; - - s0 = c15; - s1 = c16; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':') { - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - d0 = c0; - d1 = c1; - - h0 = c12; - h1 = c13; - - i0 = c15; - i1 = c16; - - s0 = '0'; - s1 = '0'; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { - // d MMM yyyy H:m:ss - // 6 DEC 2020 1:3:14 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = '0'; - h1 = c11; - - i0 = '0'; - i1 = c13; - - s0 = c15; - s1 = c16; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { - // d MMM yyyy H:mm:s - // 6 DEC 2020 1:13:4 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = '0'; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = '0'; - s1 = c16; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { - // d MMM yyyy HH:m:s - // 6 DEC 2020 11:3:4 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = c11; - h1 = c12; - - i0 = '0'; - i1 = c14; - - s0 = '0'; - s1 = c16; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { - // dd MMM yyyy H:m:s - // 16 DEC 2020 1:3:4 - d0 = c0; - d1 = c1; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - return null; - } - - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; - - h0 = '0'; - h1 = c12; - - i0 = '0'; - i1 = c14; - - s0 = '0'; - s1 = c16; - } else { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c4; - m1 = c5; - - d0 = c6; - d1 = c7; - - h0 = c8; - h1 = c9; - - i0 = c10; - i1 = c11; - - s0 = c12; - s1 = c13; - - if (c14 >= '0' && c14 <= '9' - && c15 >= '0' && c15 <= '9' - && c16 >= '0' && c16 <= '9' - ) { - nanoOfSecond = ((c14 - '0') * 100 + (c15 - '0') * 10 + (c16 - '0')) * 1_000_000; - } else { - return null; - } - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - return null; - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - return null; - } - - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - return null; - } - - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - return null; - } - - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - return null; - } - - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); - } else { - return null; - } - - return LocalDateTime.of(year, month, dom, hour, minute, second, nanoOfSecond); - } - - /** - * yyyy-MM-ddTHH:mmZ - * yyyy-MM-dd HH:mmZ - * yyyy-M-dTHH:mm:ss - * yyyy-M-d HH:mm:ss - */ - public static LocalDateTime parseLocalDateTime17(byte[] str, int off) { - if (off + 17 > str.length) { - String input = new String(str, off, str.length - off); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - byte c0 = str[off]; - byte c1 = str[off + 1]; - byte c2 = str[off + 2]; - byte c3 = str[off + 3]; - byte c4 = str[off + 4]; - byte c5 = str[off + 5]; - byte c6 = str[off + 6]; - byte c7 = str[off + 7]; - byte c8 = str[off + 8]; - byte c9 = str[off + 9]; - byte c10 = str[off + 10]; - byte c11 = str[off + 11]; - byte c12 = str[off + 12]; - byte c13 = str[off + 13]; - byte c14 = str[off + 14]; - byte c15 = str[off + 15]; - byte c16 = str[off + 16]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1; - int nanoOfSecond = 0; - if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':' && c16 == 'Z') { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = (char) c5; - m1 = (char) c6; - - d0 = (char) c8; - d1 = (char) c9; - - h0 = (char) c11; - h1 = (char) c12; - - i0 = (char) c14; - i1 = (char) c15; - - s0 = '0'; - s1 = '0'; - } else if (c4 == '-' && c6 == '-' && (c8 == ' ' || c8 == 'T') && c11 == ':' && c14 == ':') { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = '0'; - m1 = (char) c5; - - d0 = '0'; - d1 = (char) c7; - - h0 = (char) c9; - h1 = (char) c10; - - i0 = (char) c12; - i1 = (char) c13; - - s0 = (char) c15; - s1 = (char) c16; - } else if (c4 == -27 && c5 == -71 && c6 == -76 // 年 - && c9 == -26 && c10 == -100 && c11 == -120 // 月 - && c14 == -26 && c15 == -105 && c16 == -91 // 日 - ) { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; - - m0 = (char) c7; - m1 = (char) c8; - - d0 = (char) c12; - d1 = (char) c13; - - h0 = '0'; - h1 = '0'; - - i0 = '0'; - i1 = '0'; - - s0 = '0'; - s1 = '0'; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':') { - y0 = (char) c7; - y1 = (char) c8; - y2 = (char) c9; - y3 = (char) c10; - - int month = DateUtils.month((char) c3, (char) c4, (char) c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - d0 = (char) c0; - d1 = (char) c1; - - h0 = (char) c12; - h1 = (char) c13; - - i0 = (char) c15; - i1 = (char) c16; - - s0 = '0'; - s1 = '0'; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { - // d MMM yyyy H:m:ss - // 6 DEC 2020 1:3:14 - d0 = '0'; - d1 = (char) c0; - - int month = DateUtils.month((char) c2, (char) c3, (char) c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = (char) c6; - y1 = (char) c7; - y2 = (char) c8; - y3 = (char) c9; - - h0 = '0'; - h1 = (char) c11; - - i0 = '0'; - i1 = (char) c13; - - s0 = (char) c15; - s1 = (char) c16; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { - // d MMM yyyy H:mm:s - // 6 DEC 2020 1:13:4 - d0 = '0'; - d1 = (char) c0; - - int month = DateUtils.month((char) c2, (char) c3, (char) c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + char last = chars[len - 1]; + if (last == 'Z') { + len--; + zoneId = UTC; + } + LocalDateTime ldt = DateUtils.parseLocalDateTime(chars, off, len); + if (ldt == null + // && "0000-00-00".equals(str) + && chars[off] == '0' + && chars[off + 1] == '0' + && chars[off + 2] == '0' + && chars[off + 3] == '0' + && chars[off + 4] == '-' + && chars[off + 5] == '0' + && chars[off + 6] == '0' + && chars[off + 7] == '-' + && chars[off + 8] == '0' + && chars[off + 9] == '0' + ) { + ldt = LocalDateTime.of(1970, 1, 1, 0, 0, 0); } - y0 = (char) c6; - y1 = (char) c7; - y2 = (char) c8; - y3 = (char) c9; - - h0 = '0'; - h1 = (char) c11; - - i0 = (char) c13; - i1 = (char) c14; - - s0 = '0'; - s1 = (char) c16; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { - // d MMM yyyy HH:m:s - // 6 DEC 2020 11:3:4 - d0 = '0'; - d1 = (char) c0; - - int month = DateUtils.month((char) c2, (char) c3, (char) c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 17); + if (ldt == null) { + String input = new String(chars, off, len - off); throw new DateTimeParseException("illegal input " + input, input, 0); } - y0 = (char) c6; - y1 = (char) c7; - y2 = (char) c8; - y3 = (char) c9; - - h0 = (char) c11; - h1 = (char) c12; + ZonedDateTime zdt = ZonedDateTime.ofLocal(ldt, zoneId, null); + long seconds = zdt.toEpochSecond(); + int nanos = ldt.getNano(); + if (seconds < 0 && nanos > 0) { + millis = (seconds + 1) * 1000 + nanos / 1000_000 - 1000; + } else { + millis = seconds * 1000L + nanos / 1000_000; + } + } + return millis; + } - i0 = '0'; - i1 = (char) c14; + /** + * yyyy-m-d + * yyyyMMdd + * d-MMM-yy + */ + public static LocalDate parseLocalDate8(byte[] str, int off) { + if (off + 8 > str.length) { + return null; + } - s0 = '0'; - s1 = (char) c16; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { - // dd MMM yyyy H:m:s - // 16 DEC 2020 1:3:4 - d0 = (char) c0; - d1 = (char) c1; + char c1 = (char) str[off + 1]; + char c3 = (char) str[off + 3]; + char c4 = (char) str[off + 4]; - int month = DateUtils.month((char) c3, (char) c4, (char) c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + int year, month, dom; + if (c4 == '-' && str[off + 6] == '-') { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit1(str, off + 7); + } else if (c1 == '/' && c3 == '/') { + month = digit1(str, off); + dom = digit1(str, off + 2); + year = digit4(str, off + 4); + } else if (c1 == '-' && str[off + 5] == '-') { + // d-MMM-yy + dom = digit1(str, off); + month = DateUtils.month((char) str[off + 2], c3, c4); + year = digit2(str, off + 6); + if (year != -1) { + year += 2000; } + } else { + year = digit4(str, off); + month = digit2(str, off + 4); + dom = digit2(str, off + 6); + } - y0 = (char) c7; - y1 = (char) c8; - y2 = (char) c9; - y3 = (char) c10; + if ((year | month | dom) <= 0) { + return null; + } - h0 = '0'; - h1 = (char) c12; + return LocalDate.of(year, month, dom); + } - i0 = '0'; - i1 = (char) c14; + /** + * yyyy-m-d + * yyyyMMdd + * d-MMM-yy + */ + public static LocalDate parseLocalDate8(char[] str, int off) { + if (off + 8 > str.length) { + return null; + } - s0 = '0'; - s1 = (char) c16; - } else { - y0 = (char) c0; - y1 = (char) c1; - y2 = (char) c2; - y3 = (char) c3; + char c1 = str[off + 1]; + char c3 = str[off + 3]; + char c4 = str[off + 4]; - m0 = (char) c4; - m1 = (char) c5; + int year, month, dom; + if (c4 == '-' && str[off + 6] == '-') { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit1(str, off + 7); + } else if (c1 == '/' && c3 == '/') { + month = digit1(str, off); + dom = digit1(str, off + 2); + year = digit4(str, off + 4); + } else if (c1 == '-' && str[off + 5] == '-') { + // d-MMM-yy + dom = digit1(str, off); + month = DateUtils.month((char) str[off + 2], c3, c4); + year = digit2(str, off + 6); + if (year != -1) { + year += 2000; + } + } else { + year = digit4(str, off); + month = digit2(str, off + 4); + dom = digit2(str, off + 6); + } - d0 = (char) c6; - d1 = (char) c7; + if ((year | month | dom) <= 0) { + return null; + } - h0 = (char) c8; - h1 = (char) c9; + return LocalDate.of(year, month, dom); + } - i0 = (char) c10; - i1 = (char) c11; + /** + * yyyy-MM-d + * yyyy-M-dd + * dd-MMM-yy + */ + public static LocalDate parseLocalDate9(byte[] str, int off) { + if (off + 9 > str.length) { + return null; + } - s0 = (char) c12; - s1 = (char) c13; + char c1 = (char) str[off + 1]; + char c2 = (char) str[off + 2]; + char c4 = (char) str[off + 4]; + char c6 = (char) str[off + 6]; + char c7 = (char) str[off + 7]; - if (c14 >= '0' && c14 <= '9' - && c15 >= '0' && c15 <= '9' - && c16 >= '0' && c16 <= '9' - ) { - nanoOfSecond = ((c14 - '0') * 100 + (c15 - '0') * 10 + (c16 - '0')) * 1_000_000; - } else { - return null; + int year, month, dom; + if ((c4 == '-' && c7 == '-') + || (c4 == '/' && c7 == '/') // tw : yyyy/mm/d + ) { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit1(str, off + 8); + } else if ((c4 == '-' && c6 == '-') + || (c4 == '/' && c6 == '/') // tw : yyyy/m/dd + ) { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit2(str, off + 7); + } else if (c1 == '.' && c4 == '.') { + dom = digit1(str, off); + month = digit2(str, off + 2); + year = digit4(str, off + 5); + } else if ((c2 == '.' && c4 == '.') + || (c2 == '-' && c4 == '-') + ) { + dom = digit2(str, off); + month = digit1(str, off + 3); + year = digit4(str, off + 5); + } else if (c1 == '-' && c4 == '-') { + dom = digit1(str, off); + month = digit2(str, off + 2); + year = digit4(str, off + 5); + } else if (c2 == '-' && c6 == '-') { + // dd-MMM-yy + dom = digit2(str, off); + month = DateUtils.month((char) str[off + 3], c4, (char) str[off + 5]); + year = digit2(str, off + 7); + if (year != -1) { + year += 2000; } + } else if (c1 == '/' && c4 == '/') { + // M/dd/dddd + month = digit1(str, off); + dom = digit2(str, off + 2); + year = digit4(str, off + 5); + } else if (c2 == '/' && c4 == '/') { + // MM/d/dddd + month = digit2(str, off); + dom = digit1(str, off + 3); + year = digit4(str, off + 5); + } else { + return null; } - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + if ((year | month | dom) <= 0) { + return null; } - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + return LocalDate.of(year, month, dom); + } + + /** + * yyyy-MM-d + * yyyy-M-dd + * dd-MMM-yy + */ + public static LocalDate parseLocalDate9(char[] str, int off) { + if (off + 9 > str.length) { + return null; } - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' + char c1 = str[off + 1]; + char c2 = str[off + 2]; + char c4 = str[off + 4]; + char c6 = str[off + 6]; + char c7 = str[off + 7]; + char c8 = str[off + 8]; + + int year, month, dom; + if ((c4 == '-' && c7 == '-') + || (c4 == '/' && c7 == '/') // tw : yyyy/mm/d ) { - dom = (d0 - '0') * 10 + (d1 - '0'); + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit1(str, off + 8); + } else if ((c4 == '-' && c6 == '-') + || (c4 == '/' && c6 == '/') // tw : yyyy/m/dd + ) { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit2(str, off + 7); + } else if ((c4 == '年' && c6 == '月' && c8 == '日') + || (c4 == '년' && c6 == '월' && c8 == '일') + ) { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit1(str, off + 7); + } else if (c1 == '.' && c4 == '.') { + dom = digit1(str, off); + month = digit2(str, off + 2); + year = digit4(str, off + 5); + } else if ((c2 == '.' && c4 == '.') + || (c2 == '-' && c4 == '-') + ) { + dom = digit2(str, off); + month = digit1(str, off + 3); + year = digit4(str, off + 5); + } else if (c1 == '-' && c4 == '-') { + dom = digit1(str, off); + month = digit2(str, off + 2); + year = digit4(str, off + 5); + } else if (c2 == '-' && c6 == '-') { + // dd-MMM-yy + dom = digit2(str, off); + month = DateUtils.month(str[off + 3], c4, str[off + 5]); + year = digit2(str, off + 7); + if (year != -1) { + year += 2000; + } + } else if (c1 == '/' && c4 == '/') { + // M/dd/dddd + month = digit1(str, off); + dom = digit2(str, off + 2); + year = digit4(str, off + 5); + } else if (c2 == '/' && c4 == '/') { + // MM/d/dddd + month = digit2(str, off); + dom = digit1(str, off + 3); + year = digit4(str, off + 5); } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + return null; } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + if ((year | month | dom) <= 0) { + return null; } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + return LocalDate.of(year, month, dom); + } + + /** + * yyyy-MM-dd + * yyyy/MM/dd + * MM/dd/yyyy + * dd.MM.yyyy + * yyyy年M月dd日 + * yyyy年MM月d日 + * yyyy MMM d + */ + public static LocalDate parseLocalDate10(byte[] str, int off) { + if (off + 10 > str.length) { + return null; } - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + char c2 = (char) str[off + 2]; + char c4 = (char) str[off + 4]; + char c5 = (char) str[off + 5]; + char c7 = (char) str[off + 7]; + + int year, month, dom; + if ((c4 == '-' && c7 == '-') || (c4 == '/' && c7 == '/')) { + // yyyy-MM-dd + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + } else if ((c2 == '.' && c5 == '.') || (c2 == '-' && c5 == '-')) { + // dd.MM.yyyy + dom = digit2(str, off); + month = digit2(str, off + 3); + year = digit4(str, off + 6); + } else if (c2 == '/' && c5 == '/') { + // MM/dd/yyyy + month = digit2(str, off); + dom = digit2(str, off + 3); + year = digit4(str, off + 6); + } else if (str[off + 1] == ' ' && c5 == ' ') { + dom = digit1(str, off); + month = DateUtils.month(c2, (char) str[off + 3], c4); + year = digit4(str, off + 6); } else { - String input = new String(str, off, 17); - throw new DateTimeParseException("illegal input " + input, input, 0); + return null; } - return LocalDateTime.of(year, month, dom, hour, minute, second, nanoOfSecond); + return (year | month | dom) <= 0 + ? null + : LocalDate.of(year, month, dom); } /** - * yyyy-M-ddTHH:mm:ss - * yyyy-M-dd HH:mm:ss - * yyyy-MM-dTHH:mm:ss - * yyyy-MM-d HH:mm:ss - * yyyy-MM-ddTH:mm:ss - * yyyy-MM-dd H:mm:ss - * yyyy-MM-ddTHH:m:ss - * yyyy-MM-dd HH:m:ss - * yyyy-MM-ddTHH:mm:s - * yyyy-MM-dd HH:mm:s + * yyyy-MM-dd + * yyyy/MM/dd + * MM/dd/yyyy + * dd.MM.yyyy + * yyyy年M月dd日 + * yyyy年MM月d日 + * yyyy MMM d */ - public static LocalDateTime parseLocalDateTime18(char[] str, int off) { - if (off + 18 > str.length) { - String input = new String(str, off, str.length - off); - throw new DateTimeParseException("illegal input " + input, input, 0); + public static LocalDate parseLocalDate10(char[] str, int off) { + if (off + 10 > str.length) { + return null; } - char c0 = str[off]; char c1 = str[off + 1]; char c2 = str[off + 2]; - char c3 = str[off + 3]; char c4 = str[off + 4]; char c5 = str[off + 5]; char c6 = str[off + 6]; char c7 = str[off + 7]; - char c8 = str[off + 8]; char c9 = str[off + 9]; - char c10 = str[off + 10]; - char c11 = str[off + 11]; - char c12 = str[off + 12]; - char c13 = str[off + 13]; - char c14 = str[off + 14]; - char c15 = str[off + 15]; - char c16 = str[off + 16]; - char c17 = str[off + 17]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1; - if (c4 == '-' && c6 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - - h0 = c10; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - - h0 = c10; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c12 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = '0'; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = '0'; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = '0'; - s1 = c17; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { - // d MMM yyyy H:mm:ss - // 6 DEC 2020 2:13:14 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = '0'; - h1 = c11; - - i0 = c13; - i1 = c14; + int year, month, dom; + char y0, y1, y2, y3, m0, m1, d0, d1; + if ((c4 == '-' && c7 == '-') || (c4 == '/' && c7 == '/')) { + // yyyy-MM-dd + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + } else if ((c2 == '.' && c5 == '.') || (c2 == '-' && c5 == '-')) { + // dd.MM.yyyy + dom = digit2(str, off); + month = digit2(str, off + 3); + year = digit4(str, off + 6); + } else if (c2 == '/' && c5 == '/') { + // MM/dd/yyyy + month = digit2(str, off); + dom = digit2(str, off + 3); + year = digit4(str, off + 6); + } else if ((c4 == '年' && c6 == '月' && c9 == '日') + || (c4 == '년' && c6 == '월' && c9 == '일') + ) { + // yyyy年M月dd日 + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit2(str, off + 7); + } else if ((c4 == '年' && c7 == '月' && c9 == '日') + || (c4 == '년' && c7 == '월' && c9 == '일') + ) { + // yyyy年M月dd日 + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit1(str, off + 8); + } else if (c1 == ' ' && c5 == ' ') { + // d MMM yyyy + dom = digit1(str, off); + month = DateUtils.month(c2, (char) str[off + 3], c4); + year = digit4(str, off + 6); + } else { + return null; + } - s0 = c16; - s1 = c17; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { - // d MMM yyyy HH:m:ss - // 6 DEC 2020 12:3:14 - d0 = '0'; - d1 = c0; + return (year | month | dom) <= 0 + ? null + : LocalDate.of(year, month, dom); + } - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + /** + * yyyy年MM月dd日 + * yyyy년MM월dd일 + */ + public static LocalDate parseLocalDate11(char[] str, int off) { + if (off + 11 > str.length) { + return null; + } - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; + char c4 = str[off + 4]; + char c7 = str[off + 7]; + char c10 = str[off + 10]; - h0 = c11; - h1 = c12; + int year, month, dom; + if ((c4 == '年' && c7 == '月' && c10 == '日') + || (c4 == '-' && c7 == '-' && c10 == 'Z') + || (c4 == '년' && c7 == '월' && c10 == '일')) { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + } else if (str[off + 2] == ' ' && str[off + 6] == ' ') { + year = digit4(str, off + 7); + month = DateUtils.month(str[off + 3], c4, str[off + 5]); + dom = digit2(str, off); + } else { + return null; + } - i0 = '0'; - i1 = c14; + if ((year | month | dom) < 0 || (year == 0 && month == 0 && dom == 0)) { + return null; + } - s0 = c16; - s1 = c17; - } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c16 == ':') { - // d MMM yyyy HH:m:ss - // 6 DEC 2020 12:3:14 - d0 = '0'; - d1 = c0; + return LocalDate.of(year, month, dom); + } - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + /** + * + */ + public static LocalDate parseLocalDate11(byte[] str, int off) { + if (off + 11 > str.length) { + return null; + } - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; + int year, month, dom; + if (str[off + 4] == '-' && str[off + 7] == '-' && str[off + 10] == 'Z') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + } else if (str[off + 2] == ' ' && str[off + 6] == ' ') { + year = digit4(str, off + 7); + month = DateUtils.month((char) str[off + 3], (char) str[off + 4], (char) str[off + 5]); + dom = digit2(str, off); + } else { + return null; + } - h0 = c11; - h1 = c12; + if ((year | month | dom) < 0 || (year == 0 && month == 0 && dom == 0)) { + return null; + } - i0 = c14; - i1 = c15; + return LocalDate.of(year, month, dom); + } - s0 = '0'; - s1 = c17; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':' && c16 == ':') { - // dd MMM yyyy HH:m:s - // 16 DEC 2020 12:3:4 - d0 = c0; - d1 = c1; + public static LocalDateTime parseLocalDateTime12(char[] str, int off) { + if (off + 12 > str.length) { + String input = new String(str, off, str.length - off); + throw new DateTimeParseException("illegal input " + input, input, 0); + } - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + int year = digit4(str, off); + int month = digit2(str, off + 4); + int dom = digit2(str, off + 6); + int hour = digit2(str, off + 8); + int minute = digit2(str, off + 10); - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; + if ((year | month | dom | hour | minute) < 0) { + String input = new String(str, off, off + 12); + throw new DateTimeParseException("illegal input " + input, input, 0); + } - h0 = c12; - h1 = c13; + if (year == 0 && month == 0 && dom == 0 && hour == 0 && minute == 0) { + return null; + } - i0 = '0'; - i1 = c15; + return LocalDateTime.of(year, month, dom, hour, minute, 0); + } - s0 = '0'; - s1 = c17; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c16 == ':') { - // dd MMM yyyy H:mm:s - // 16 DEC 2020 1:13:4 - d0 = c0; - d1 = c1; + /** + * parseLocalDateTime use format 'yyyyMMddHHmm' + */ + public static LocalDateTime parseLocalDateTime12(byte[] str, int off) { + if (off + 12 > str.length) { + String input = new String(str, off, str.length - off); + throw new DateTimeParseException("illegal input " + input, input, 0); + } - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + int year = digit4(str, off); + int month = digit2(str, off + 4); + int dom = digit2(str, off + 6); + int hour = digit2(str, off + 8); + int minute = digit2(str, off + 10); - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; + if ((year | month | dom | hour | minute) < 0) { + String input = new String(str, off, off + 12); + throw new DateTimeParseException("illegal input " + input, input, 0); + } - h0 = '0'; - h1 = c12; + if (year == 0 && month == 0 && dom == 0 && hour == 0 && minute == 0) { + return null; + } - i0 = c14; - i1 = c15; + return LocalDateTime.of(year, month, dom, hour, minute, 0); + } - s0 = '0'; - s1 = c17; - } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { - // dd MMM yyyy H:mm:s - // 16 DEC 2020 1:13:4 - d0 = c0; - d1 = c1; + /** + * yyyyMMddHHmmss + */ + public static LocalDateTime parseLocalDateTime14(char[] str, int off) { + if (off + 14 > str.length) { + return null; + } - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + int year = digit4(str, off); + int month = digit2(str, off + 4); + int dom = digit2(str, off + 6); + int hour = digit2(str, off + 8); + int minute = digit2(str, off + 10); + int second = digit2(str, off + 12); - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; + return (year | month | dom | hour | minute | second) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); + } - h0 = '0'; - h1 = c12; + /** + * yyyyMMddHHmmss + */ + public static LocalDateTime parseLocalDateTime14(byte[] str, int off) { + if (off + 14 > str.length) { + return null; + } - i0 = '0'; - i1 = c14; + int year = digit4(str, off); + int month = digit2(str, off + 4); + int dom = digit2(str, off + 6); + int hour = digit2(str, off + 8); + int minute = digit2(str, off + 10); + int second = digit2(str, off + 12); - s0 = c16; - s1 = c17; - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); + return (year | month | dom | hour | minute | second) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); + } + + /** + * yyyy-MM-ddTHH:mm + * yyyy-MM-dd HH:mm + * yyyyMMddTHHmmssZ + * yyyy-MM-ddTH:m:s + * yyyy-MM-dd H:m:s + */ + public static LocalDateTime parseLocalDateTime16(char[] str, int off) { + if (off + 16 > str.length) { + return null; } - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); + char c1 = str[off + 1]; + char c2 = str[off + 2]; + char c3 = str[off + 3]; + char c4 = str[off + 4]; + char c5 = str[off + 5]; + char c7 = str[off + 7]; + char c10 = str[off + 10]; + char c12 = str[off + 12]; + char c13 = str[off + 13]; + char c14 = str[off + 14]; + + int year, month, dom, hour, minute, second = 0; + if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + } else if (str[off + 8] == 'T' && str[off + 15] == 'Z') { + year = digit4(str, off); + month = digit2(str, off + 4); + dom = digit2(str, off + 6); + hour = digit2(str, off + 9); + minute = digit2(str, off + 11); + second = digit2(str, off + 13); + } else if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c12 == ':' && c14 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit1(str, off + 11); + minute = digit1(str, off + 13); + second = digit1(str, off + 15); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':') { + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { + // d MMM yyyy H:m:ss + // 6 DEC 2020 2:3:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit1(str, off + 13); + second = digit1(str, off + 15); } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); + return null; } - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); + return (year | month | dom | hour | minute | second) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); + } + + /** + * yyyy-MM-ddTHH:mm + * yyyy-MM-dd HH:mm + * yyyyMMddTHHmmssZ + * yyyy-MM-ddTH:m:s + * yyyy-MM-dd H:m:s + */ + public static LocalDateTime parseLocalDateTime16(byte[] str, int off) { + if (off + 16 > str.length) { + return null; } - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' + byte c1 = str[off + 1]; + byte c2 = str[off + 2]; + byte c3 = str[off + 3]; + byte c4 = str[off + 4]; + byte c5 = str[off + 5]; + byte c6 = str[off + 6]; + byte c7 = str[off + 7]; + byte c8 = str[off + 8]; + byte c9 = str[off + 9]; + byte c10 = str[off + 10]; + byte c11 = str[off + 11]; + byte c12 = str[off + 12]; + byte c13 = str[off + 13]; + byte c14 = str[off + 14]; + byte c15 = str[off + 15]; + + int year, month, dom, hour, minute, second = 0; + if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + } else if (str[off + 8] == 'T' && str[off + 15] == 'Z') { + year = digit4(str, off); + month = digit2(str, off + 4); + dom = digit2(str, off + 6); + hour = digit2(str, off + 9); + minute = digit2(str, off + 11); + second = digit2(str, off + 13); + } else if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c12 == ':' && c14 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit1(str, off + 11); + minute = digit1(str, off + 13); + second = digit1(str, off + 15); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':') { + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { + // d MMM yyyy H:m:ss + // 6 DEC 2020 2:3:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit1(str, off + 13); + second = digit1(str, off + 15); + } else if (c4 == -27 && c5 == -71 && c6 == -76 // 年 + && c8 == -26 && c9 == -100 && c10 == -120 // 月 + && c13 == -26 && c14 == -105 && c15 == -91 // 日 ) { - dom = (d0 - '0') * 10 + (d1 - '0'); + year = digit4(str, off); + month = digit1(str, off + 7); + dom = digit2(str, off + 11); + hour = 0; + minute = 0; + } else if (c4 == -27 && c5 == -71 && c6 == -76 // 年 + && c9 == -26 && c10 == -100 && c11 == -120 // 月 + && c13 == -26 && c14 == -105 && c15 == -91 // 日 + ) { + year = digit4(str, off); + month = digit2(str, off + 7); + dom = digit1(str, off + 12); + hour = 0; + minute = 0; } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); + return null; } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - String input = new String(str, off, 18); + return (year | month | dom | hour | minute | second) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); + } + + /** + * yyyy-MM-ddTHH:mmZ + * yyyy-MM-dd HH:mmZ + * yyyy-M-dTHH:mm:ss + * yyyy-M-d HH:mm:ss + */ + public static LocalDateTime parseLocalDateTime17(char[] str, int off) { + if (off + 17 > str.length) { + String input = new String(str, off, str.length - off); throw new DateTimeParseException("illegal input " + input, input, 0); } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); + char c1 = str[off + 1]; + char c2 = str[off + 2]; + char c3 = str[off + 3]; + char c4 = str[off + 4]; + char c5 = str[off + 5]; + char c6 = str[off + 6]; + char c7 = str[off + 7]; + char c8 = str[off + 8]; + char c10 = str[off + 10]; + char c11 = str[off + 11]; + char c12 = str[off + 12]; + char c13 = str[off + 13]; + char c14 = str[off + 14]; + char c15 = str[off + 15]; + char c16 = str[off + 16]; + + int year, month, dom, hour, minute, second = 0, nanoOfSecond = 0; + if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':' && c16 == 'Z') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = 0; + } else if (c4 == '-' && c6 == '-' && (c8 == ' ' || c8 == 'T') && c11 == ':' && c14 == ':') { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit1(str, off + 7); + hour = digit2(str, off + 9); + minute = digit2(str, off + 12); + second = digit2(str, off + 15); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':') { + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit2(str, off + 12); + minute = digit2(str, off + 15); + second = 0; + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { + // d MMM yyyy H:m:ss + // 6 DEC 2020 1:3:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit1(str, off + 13); + second = digit2(str, off + 15); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { + // d MMM yyyy H:mm:s + // 6 DEC 2020 1:13:4 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit2(str, off + 13); + second = digit1(str, off + 16); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { + // d MMM yyyy HH:m:s + // 6 DEC 2020 11:3:4 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit1(str, off + 14); + second = digit1(str, off + 16); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { + // dd MMM yyyy H:m:s + // 16 DEC 2020 1:3:4 + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit1(str, off + 12); + minute = digit1(str, off + 14); + second = digit1(str, off + 16); } else { - String input = new String(str, off, 18); + year = digit4(str, off); + month = digit2(str, off + 4); + dom = digit2(str, off + 6); + hour = digit2(str, off + 8); + minute = digit2(str, off + 10); + second = digit2(str, off + 12); + nanoOfSecond = readNanos(str, 3, off + 14); + } + + return (year | month | dom | hour | minute | second | nanoOfSecond) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second, nanoOfSecond); + } + + /** + * yyyy-MM-ddTHH:mmZ + * yyyy-MM-dd HH:mmZ + * yyyy-M-dTHH:mm:ss + * yyyy-M-d HH:mm:ss + */ + public static LocalDateTime parseLocalDateTime17(byte[] str, int off) { + if (off + 17 > str.length) { + String input = new String(str, off, str.length - off); throw new DateTimeParseException("illegal input " + input, input, 0); } - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' + byte c1 = str[off + 1]; + byte c2 = str[off + 2]; + byte c3 = str[off + 3]; + byte c4 = str[off + 4]; + byte c5 = str[off + 5]; + byte c6 = str[off + 6]; + byte c7 = str[off + 7]; + byte c8 = str[off + 8]; + byte c9 = str[off + 9]; + byte c10 = str[off + 10]; + byte c11 = str[off + 11]; + byte c12 = str[off + 12]; + byte c13 = str[off + 13]; + byte c14 = str[off + 14]; + byte c15 = str[off + 15]; + byte c16 = str[off + 16]; + + int year, month, dom, hour, minute, second = 0, nanoOfSecond = 0; + if (c4 == '-' && c7 == '-' && (c10 == 'T' || c10 == ' ') && c13 == ':' && c16 == 'Z') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = 0; + } else if (c4 == '-' && c6 == '-' && (c8 == ' ' || c8 == 'T') && c11 == ':' && c14 == ':') { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit1(str, off + 7); + hour = digit2(str, off + 9); + minute = digit2(str, off + 12); + second = digit2(str, off + 15); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':') { + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit2(str, off + 12); + minute = digit2(str, off + 15); + second = 0; + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c14 == ':') { + // d MMM yyyy H:m:ss + // 6 DEC 2020 1:3:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit1(str, off + 13); + second = digit2(str, off + 15); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { + // d MMM yyyy H:mm:s + // 6 DEC 2020 1:13:4 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit2(str, off + 13); + second = digit1(str, off + 16); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { + // d MMM yyyy HH:m:s + // 6 DEC 2020 11:3:4 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit1(str, off + 14); + second = digit1(str, off + 16); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { + // dd MMM yyyy H:m:s + // 16 DEC 2020 1:3:4 + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit1(str, off + 12); + minute = digit1(str, off + 14); + second = digit1(str, off + 16); + } else if (c4 == -27 && c5 == -71 && c6 == -76 // 年 + && c9 == -26 && c10 == -100 && c11 == -120 // 月 + && c14 == -26 && c15 == -105 && c16 == -91 // 日 ) { - second = (s0 - '0') * 10 + (s1 - '0'); + year = digit4(str, off); + month = digit2(str, off + 7); + dom = digit2(str, off + 12); + hour = 0; + minute = 0; } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); + year = digit4(str, off); + month = digit2(str, off + 4); + dom = digit2(str, off + 6); + hour = digit2(str, off + 8); + minute = digit2(str, off + 10); + second = digit2(str, off + 12); + nanoOfSecond = readNanos(str, 3, off + 14); } - return LocalDateTime.of(year, month, dom, hour, minute, second); + return (year | month | dom | hour | minute | second | nanoOfSecond) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second, nanoOfSecond); } /** @@ -4274,368 +1901,260 @@ public static LocalDateTime parseLocalDateTime18(char[] str, int off) { * yyyy-MM-ddTHH:mm:s * yyyy-MM-dd HH:mm:s */ - public static LocalDateTime parseLocalDateTime18(byte[] str, int off) { + public static LocalDateTime parseLocalDateTime18(char[] str, int off) { if (off + 18 > str.length) { String input = new String(str, off, str.length - off); throw new DateTimeParseException("illegal input " + input, input, 0); } - char c0 = (char) str[off]; - char c1 = (char) str[off + 1]; - char c2 = (char) str[off + 2]; - char c3 = (char) str[off + 3]; - char c4 = (char) str[off + 4]; - char c5 = (char) str[off + 5]; - char c6 = (char) str[off + 6]; - char c7 = (char) str[off + 7]; - char c8 = (char) str[off + 8]; - char c9 = (char) str[off + 9]; - char c10 = (char) str[off + 10]; - char c11 = (char) str[off + 11]; - char c12 = (char) str[off + 12]; - char c13 = (char) str[off + 13]; - char c14 = (char) str[off + 14]; - char c15 = (char) str[off + 15]; - char c16 = (char) str[off + 16]; - char c17 = (char) str[off + 17]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1; - if (c4 == '-' && c6 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = '0'; - m1 = c5; - - d0 = c7; - d1 = c8; - - h0 = c10; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = '0'; - d1 = c8; - - h0 = c10; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c12 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = '0'; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c15 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = '0'; - i1 = c14; - - s0 = c16; - s1 = c17; - } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; + char c1 = str[off + 1]; + char c2 = str[off + 2]; + char c3 = str[off + 3]; + char c4 = str[off + 4]; + char c5 = str[off + 5]; + char c6 = str[off + 6]; + char c7 = str[off + 7]; + char c9 = str[off + 9]; + char c10 = str[off + 10]; + char c11 = str[off + 11]; + char c12 = str[off + 12]; + char c13 = str[off + 13]; + char c14 = str[off + 14]; + char c15 = str[off + 15]; + char c16 = str[off + 16]; - s0 = '0'; - s1 = c17; + int year, month, dom, hour, minute, second; + if (c4 == '-' && c6 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit2(str, off + 7); + hour = digit2(str, off + 10); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit1(str, off + 8); + hour = digit2(str, off + 10); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c12 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit1(str, off + 11); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit1(str, off + 14); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit1(str, off + 17); } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { // d MMM yyyy H:mm:ss // 6 DEC 2020 2:13:14 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = '0'; - h1 = c11; - - i0 = c13; - i1 = c14; - - s0 = c16; - s1 = c17; + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { // d MMM yyyy HH:m:ss // 6 DEC 2020 12:3:14 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = c11; - h1 = c12; - - i0 = '0'; - i1 = c14; - - s0 = c16; - s1 = c17; + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit1(str, off + 14); + second = digit2(str, off + 16); } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c16 == ':') { // d MMM yyyy HH:m:ss // 6 DEC 2020 12:3:14 - d0 = '0'; - d1 = c0; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = '0'; - s1 = c17; + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit1(str, off + 17); } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':' && c16 == ':') { // dd MMM yyyy HH:m:s // 16 DEC 2020 12:3:4 - d0 = c0; - d1 = c1; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; - - h0 = c12; - h1 = c13; - - i0 = '0'; - i1 = c15; - - s0 = '0'; - s1 = c17; + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit2(str, off + 12); + minute = digit1(str, off + 15); + second = digit1(str, off + 17); } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c16 == ':') { // dd MMM yyyy H:mm:s // 16 DEC 2020 1:13:4 - d0 = c0; - d1 = c1; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; - - h0 = '0'; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = '0'; - s1 = c17; + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit1(str, off + 12); + minute = digit2(str, off + 14); + second = digit1(str, off + 17); } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { // dd MMM yyyy H:mm:s // 16 DEC 2020 1:13:4 - d0 = c0; - d1 = c1; - - int month = DateUtils.month(c3, c4, c5); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - y0 = c7; - y1 = c8; - y2 = c9; - y3 = c10; - - h0 = '0'; - h1 = c12; - - i0 = '0'; - i1 = c14; - - s0 = c16; - s1 = c17; - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - int year; - if (y0 >= '0' && y0 <= '9' - && y1 >= '0' && y1 <= '9' - && y2 >= '0' && y2 <= '9' - && y3 >= '0' && y3 <= '9' - ) { - year = (y0 - '0') * 1000 + (y1 - '0') * 100 + (y2 - '0') * 10 + (y3 - '0'); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } - - int month; - if (m0 >= '0' && m0 <= '9' - && m1 >= '0' && m1 <= '9' - ) { - month = (m0 - '0') * 10 + (m1 - '0'); + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit1(str, off + 12); + minute = digit1(str, off + 14); + second = digit2(str, off + 16); } else { String input = new String(str, off, 18); throw new DateTimeParseException("illegal input " + input, input, 0); } - int dom; - if (d0 >= '0' && d0 <= '9' - && d1 >= '0' && d1 <= '9' - ) { - dom = (d0 - '0') * 10 + (d1 - '0'); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + return (year | month | dom | hour | minute | second) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); + } - int hour; - if (h0 >= '0' && h0 <= '9' - && h1 >= '0' && h1 <= '9' - ) { - hour = (h0 - '0') * 10 + (h1 - '0'); - } else { - String input = new String(str, off, 18); + /** + * yyyy-M-ddTHH:mm:ss + * yyyy-M-dd HH:mm:ss + * yyyy-MM-dTHH:mm:ss + * yyyy-MM-d HH:mm:ss + * yyyy-MM-ddTH:mm:ss + * yyyy-MM-dd H:mm:ss + * yyyy-MM-ddTHH:m:ss + * yyyy-MM-dd HH:m:ss + * yyyy-MM-ddTHH:mm:s + * yyyy-MM-dd HH:mm:s + */ + public static LocalDateTime parseLocalDateTime18(byte[] str, int off) { + if (off + 18 > str.length) { + String input = new String(str, off, str.length - off); throw new DateTimeParseException("illegal input " + input, input, 0); } - int minute; - if (i0 >= '0' && i0 <= '9' - && i1 >= '0' && i1 <= '9' - ) { - minute = (i0 - '0') * 10 + (i1 - '0'); - } else { - String input = new String(str, off, 18); - throw new DateTimeParseException("illegal input " + input, input, 0); - } + byte c1 = str[off + 1]; + byte c2 = str[off + 2]; + byte c3 = str[off + 3]; + byte c4 = str[off + 4]; + byte c5 = str[off + 5]; + byte c6 = str[off + 6]; + byte c7 = str[off + 7]; + byte c9 = str[off + 9]; + byte c10 = str[off + 10]; + byte c11 = str[off + 11]; + byte c12 = str[off + 12]; + byte c13 = str[off + 13]; + byte c14 = str[off + 14]; + byte c15 = str[off + 15]; + byte c16 = str[off + 16]; - int second; - if (s0 >= '0' && s0 <= '9' - && s1 >= '0' && s1 <= '9' - ) { - second = (s0 - '0') * 10 + (s1 - '0'); + int year, month, dom, hour, minute, second; + if (c4 == '-' && c6 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit1(str, off + 5); + dom = digit2(str, off + 7); + hour = digit2(str, off + 10); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c9 == ' ' || c9 == 'T') && c12 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit1(str, off + 8); + hour = digit2(str, off + 10); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c12 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit1(str, off + 11); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c15 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit1(str, off + 14); + second = digit2(str, off + 16); + } else if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit1(str, off + 17); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c12 == ':' && c15 == ':') { + // d MMM yyyy H:mm:ss + // 6 DEC 2020 2:13:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit1(str, off + 11); + minute = digit2(str, off + 13); + second = digit2(str, off + 16); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c15 == ':') { + // d MMM yyyy HH:m:ss + // 6 DEC 2020 12:3:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit1(str, off + 14); + second = digit2(str, off + 16); + } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c16 == ':') { + // d MMM yyyy HH:m:ss + // 6 DEC 2020 12:3:14 + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit1(str, off + 17); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c14 == ':' && c16 == ':') { + // dd MMM yyyy HH:m:s + // 16 DEC 2020 12:3:4 + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit2(str, off + 12); + minute = digit1(str, off + 15); + second = digit1(str, off + 17); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c16 == ':') { + // dd MMM yyyy H:mm:s + // 16 DEC 2020 1:13:4 + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit1(str, off + 12); + minute = digit2(str, off + 14); + second = digit1(str, off + 17); + } else if (c2 == ' ' && c6 == ' ' && c11 == ' ' && c13 == ':' && c15 == ':') { + // dd MMM yyyy H:mm:s + // 16 DEC 2020 1:13:4 + dom = digit2(str, off); + month = DateUtils.month(c3, c4, c5); + year = digit4(str, off + 7); + hour = digit1(str, off + 12); + minute = digit1(str, off + 14); + second = digit2(str, off + 16); } else { String input = new String(str, off, 18); throw new DateTimeParseException("illegal input " + input, input, 0); } - return LocalDateTime.of(year, month, dom, hour, minute, second); + return (year | month | dom | hour | minute | second) < 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); } /** @@ -4649,118 +2168,48 @@ public static LocalDateTime parseLocalDateTime19(char[] str, int off) { return null; } - char c0 = str[off]; char c1 = str[off + 1]; char c2 = str[off + 2]; char c3 = str[off + 3]; char c4 = str[off + 4]; char c5 = str[off + 5]; - char c6 = str[off + 6]; char c7 = str[off + 7]; - char c8 = str[off + 8]; - char c9 = str[off + 9]; char c10 = str[off + 10]; - char c11 = str[off + 11]; - char c12 = str[off + 12]; char c13 = str[off + 13]; - char c14 = str[off + 14]; - char c15 = str[off + 15]; char c16 = str[off + 16]; - char c17 = str[off + 17]; - char c18 = str[off + 18]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1; - if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; - } else if (c4 == '/' && c7 == '/' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; + int year, month, dom, hour, minute, second; + if (((c4 == '-' && c7 == '-') || (c4 == '/' && c7 == '/')) + && (c10 == ' ' || c10 == 'T') + && c13 == ':' && c16 == ':' + ) { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit2(str, off + 17); } else if (c2 == '/' && c5 == '/' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - d0 = c0; - d1 = c1; - - m0 = c3; - m1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; + dom = digit2(str, off); + month = digit2(str, off + 3); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit2(str, off + 17); } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c16 == ':') { - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - m0 = '0'; - m1 = '0'; - } - - d0 = '0'; - d1 = c0; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit2(str, off + 17); } else { return null; } - return localDateTime(y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1); + return (year | month | dom | hour | minute | second) <= 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); } public static LocalDateTime parseLocalDateTime19(String str, int off) { @@ -4794,118 +2243,48 @@ public static LocalDateTime parseLocalDateTime19(byte[] str, int off) { return null; } - char c0 = (char) str[off]; - char c1 = (char) str[off + 1]; - char c2 = (char) str[off + 2]; - char c3 = (char) str[off + 3]; - char c4 = (char) str[off + 4]; - char c5 = (char) str[off + 5]; - char c6 = (char) str[off + 6]; - char c7 = (char) str[off + 7]; - char c8 = (char) str[off + 8]; - char c9 = (char) str[off + 9]; - char c10 = (char) str[off + 10]; - char c11 = (char) str[off + 11]; - char c12 = (char) str[off + 12]; - char c13 = (char) str[off + 13]; - char c14 = (char) str[off + 14]; - char c15 = (char) str[off + 15]; - char c16 = (char) str[off + 16]; - char c17 = (char) str[off + 17]; - char c18 = (char) str[off + 18]; - - char y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1; - if (c4 == '-' && c7 == '-' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; - } else if (c4 == '/' && c7 == '/' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - y0 = c0; - y1 = c1; - y2 = c2; - y3 = c3; - - m0 = c5; - m1 = c6; - - d0 = c8; - d1 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; + byte c1 = str[off + 1]; + byte c2 = str[off + 2]; + byte c3 = str[off + 3]; + byte c4 = str[off + 4]; + byte c5 = str[off + 5]; + byte c7 = str[off + 7]; + byte c10 = str[off + 10]; + byte c13 = str[off + 13]; + byte c16 = str[off + 16]; - s0 = c17; - s1 = c18; + int year, month, dom, hour, minute, second; + if (((c4 == '-' && c7 == '-') || (c4 == '/' && c7 == '/')) + && (c10 == ' ' || c10 == 'T') + && c13 == ':' && c16 == ':' + ) { + year = digit4(str, off); + month = digit2(str, off + 5); + dom = digit2(str, off + 8); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit2(str, off + 17); } else if (c2 == '/' && c5 == '/' && (c10 == ' ' || c10 == 'T') && c13 == ':' && c16 == ':') { - d0 = c0; - d1 = c1; - - m0 = c3; - m1 = c4; - - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; + dom = digit2(str, off); + month = digit2(str, off + 3); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit2(str, off + 17); } else if (c1 == ' ' && c5 == ' ' && c10 == ' ' && c13 == ':' && c16 == ':') { - y0 = c6; - y1 = c7; - y2 = c8; - y3 = c9; - - int month = DateUtils.month(c2, c3, c4); - if (month > 0) { - m0 = (char) ('0' + month / 10); - m1 = (char) ('0' + (month % 10)); - } else { - m0 = '0'; - m1 = '0'; - } - - d0 = '0'; - d1 = c0; - - h0 = c11; - h1 = c12; - - i0 = c14; - i1 = c15; - - s0 = c17; - s1 = c18; + dom = digit1(str, off); + month = DateUtils.month(c2, c3, c4); + year = digit4(str, off + 6); + hour = digit2(str, off + 11); + minute = digit2(str, off + 14); + second = digit2(str, off + 17); } else { return null; } - return localDateTime(y0, y1, y2, y3, m0, m1, d0, d1, h0, h1, i0, i1, s0, s1); + return (year | month | dom | hour | minute | second) <= 0 + ? null + : LocalDateTime.of(year, month, dom, hour, minute, second); } public static LocalDateTime parseLocalDateTime20(char[] str, int off) { @@ -11559,6 +8938,10 @@ public static String toString(long timeMillis, boolean timeZone, ZoneId zoneId) return new String(bytes, 0, bytes.length, StandardCharsets.ISO_8859_1); } + private static int month(byte c0, byte c1, byte c2) { + return month((char) c0, (char) c1, (char) c2); + } + public static int month(char c0, char c1, char c2) { switch (c0) { case 'J': diff --git a/core/src/main/java/com/alibaba/fastjson2/util/IOUtils.java b/core/src/main/java/com/alibaba/fastjson2/util/IOUtils.java index ee74116ad..4b6ae3097 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/IOUtils.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/IOUtils.java @@ -1430,16 +1430,15 @@ public static int digit4(char[] chars, int off) { if (BIG_ENDIAN) { x = Long.reverseBytes(x); } - if ((x & 0xF000F000F000F0L) != 0x30003000300030L) { - return -1; - } - long d = x & 0x0F000F000F000FL; - if (((d + 0x06000600060006L) & 0xF000F000F000F0L) != 0) { + long d; + if ((x & 0xF000F000F000F0L) != 0x30003000300030L + || (((d = x & 0x0F000F000F000FL) + 0x06000600060006L) & 0xF000F000F000F0L) != 0 + ) { return -1; } - return (int) (((d & 0xF) << 10) + ((d & 0xF) << 3) - ((d & 0xF) << 5) - + ((d & 0xF0000) >> 10) + ((d & 0xF0000) >> 11) + ((d & 0xF0000) >> 14) - + ((d & 0xF00000000L) >> 29) + ((d & 0xF00000000L) >> 31) + return (int) (((d & 0xF) << 10) + ((d & 0xF) << 3) - ((d & 0xF) << 5) // (d & 0xF) * 1000 + + ((d & 0xF0000) >> 10) + ((d & 0xF0000) >> 11) + ((d & 0xF0000) >> 14) // (d & 0xF0000) * 100 + + ((d & 0xF00000000L) >> 29) + ((d & 0xF00000000L) >> 31) // (d & 0xF00000000L) * 10 + (d >> 48)); } @@ -1448,17 +1447,53 @@ public static int digit4(byte[] bytes, int off) { if (BIG_ENDIAN) { x = Integer.reverseBytes(x); } - if ((x & 0xF0F0F0F0) != 0x30303030) { + int d; + if ((x & 0xF0F0F0F0) != 0x30303030 + || (((d = x & 0x0F0F0F0F) + 0x06060606) & 0xF0F0F0F0) != 0 + ) { return -1; } - int d = x & 0x0F0F0F0F; - if (((d + 0x06060606) & 0xF0F0F0F0) != 0) { + return ((d & 0xF) << 10) + ((d & 0xF) << 3) - ((d & 0xF) << 5) // (d & 0xF) * 1000 + + ((d & 0xF00) >> 2) + ((d & 0xF00) >> 3) + ((d & 0xF00) >> 6) // (d & 0xF00) * 100 + + ((d & 0xF0000) >> 13) + ((d & 0xF0000) >> 15) // (d & 0xF0000) * 10 + + (d >> 24); + } + + public static int digit3(char[] chars, int off) { + long address = ARRAY_CHAR_BASE_OFFSET + ((long) off << 1); + int i = UNSAFE.getInt(chars, address); + short s = UNSAFE.getShort(chars, address + 4); + if (BIG_ENDIAN) { + i = Integer.reverseBytes(i); + s = Short.reverseBytes(s); + } + long x = (((long) s) << 32) | i; // reuse + long d; + if ((x & 0xF000F000F0L) != 0x3000300030L + || (((d = x & 0x0F000F000FL) + 0x0600060006L) & 0xF000F000F0L) != 0 + ) { return -1; } - return ((d & 0xF) << 10) + ((d & 0xF) << 3) - ((d & 0xF) << 5) - + ((d & 0xF00) >> 2) + ((d & 0xF00) >> 3) + ((d & 0xF00) >> 6) - + ((d & 0xF0000) >> 13) + ((d & 0xF0000) >> 15) - + (d >> 24); + return (int) (((d & 0xF) << 6) + ((d & 0xF) << 5) + ((d & 0xF) << 2) // (d & 0xF) * 100 + + ((d & 0xF0000L) >> 13) + ((d & 0xF0000L) >> 15) // ((d & 0xF0000) >> 16) * 10 + + (d >> 32)); + } + + public static int digit3(byte[] bytes, int off) { + int x = UNSAFE.getShort(bytes, ARRAY_BYTE_BASE_OFFSET + off); + if (BIG_ENDIAN) { + x = Short.reverseBytes((short) x); + } + x |= UNSAFE.getByte(bytes, ARRAY_BYTE_BASE_OFFSET + off + 2) << 16; + int d; + if ((x & 0xF0F0F0) != 0x303030 + || (((d = x & 0x0F0F0F) + 0x060606) & 0xF0F0F0) != 0 + ) { + return -1; + } + return ((d & 0xF) << 6) + ((d & 0xF) << 5) + ((d & 0xF) << 2) // (d & 0xff) * 100 + + ((d & 0xF00) >> 5) + ((d & 0xF00) >> 7) // ((d & 0xF00) >> 8) * 10 + + (d >> 16); } public static int digit2(char[] chars, int off) { @@ -1466,14 +1501,13 @@ public static int digit2(char[] chars, int off) { if (BIG_ENDIAN) { x = Integer.reverseBytes(x); } - if ((x & 0xF000F0) != 0x300030) { - return -1; - } - int d = x & 0x0F000F; - if (((d + 0x060006) & 0xF000F0) != 0) { + int d; + if ((x & 0xF000F0) != 0x300030 + || (((d = x & 0x0F000F) + 0x060006) & 0xF000F0) != 0 + ) { return -1; } - return ((d & 0xF) << 3) + ((d & 0xF) << 1) + return ((d & 0xF) << 3) + ((d & 0xF) << 1) // (d & 0xF) * 10 + (d >> 16); } @@ -1482,14 +1516,14 @@ public static int digit2(byte[] bytes, int off) { if (BIG_ENDIAN) { x = Short.reverseBytes(x); } - if ((x & 0xF0F0) != 0x3030) { - return -1; - } - int d = x & 0x0F0F; - if (((d + 0x0606) & 0xF0F0) != 0) { + int d; + if ((x & 0xF0F0) != 0x3030 + || (((d = x & 0x0F0F) + 0x0606) & 0xF0F0) != 0 + ) { return -1; } - return ((d & 0xF) << 3) + ((d & 0xF) << 1) + (d >> 8); + return ((d & 0xF) << 3) + ((d & 0xF) << 1) // (d & 0xF) * 10 + + (d >> 8); } public static int digit1(char[] chars, int off) { diff --git a/core/src/test/java/com/alibaba/fastjson2/util/DateUtilsTest.java b/core/src/test/java/com/alibaba/fastjson2/util/DateUtilsTest.java index 26bcd7632..41a9f9414 100644 --- a/core/src/test/java/com/alibaba/fastjson2/util/DateUtilsTest.java +++ b/core/src/test/java/com/alibaba/fastjson2/util/DateUtilsTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.nio.charset.StandardCharsets; import java.time.*; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; @@ -2037,14 +2038,31 @@ public void parseLocalDateTime16_1() { @Test public void parseLocalDateTime16_2() { + LocalDateTime expected = LocalDateTime.of(2021, 7, 8, 4, 5, 6); assertEquals( - LocalDateTime.of(2021, 7, 8, 4, 5, 6), + expected, DateUtils.parseLocalDateTime("2021-07-08T4:5:6", 0, 16) ); assertEquals( - LocalDateTime.of(2021, 7, 8, 4, 5, 6), + expected, + DateUtils.parseLocalDateTime("2021-07-08T4:5:6".getBytes(StandardCharsets.UTF_8), 0, 16) + ); + assertEquals( + expected, + DateUtils.parseLocalDateTime("2021-07-08T4:5:6".toCharArray(), 0, 16) + ); + assertEquals( + expected, DateUtils.parseLocalDateTime("2021-07-08 4:5:6", 0, 16) ); + assertEquals( + expected, + DateUtils.parseLocalDateTime("2021-07-08 4:5:6".toCharArray(), 0, 16) + ); + assertEquals( + expected, + DateUtils.parseLocalDateTime("2021-07-08 4:5:6".getBytes(StandardCharsets.UTF_8), 0, 16) + ); } @Test diff --git a/core/src/test/java/com/alibaba/fastjson2/util/IOUtilsTest.java b/core/src/test/java/com/alibaba/fastjson2/util/IOUtilsTest.java index 97ae83ef0..5b812d2d6 100644 --- a/core/src/test/java/com/alibaba/fastjson2/util/IOUtilsTest.java +++ b/core/src/test/java/com/alibaba/fastjson2/util/IOUtilsTest.java @@ -198,6 +198,58 @@ public void digit4_chars() { } } + @Test + public void digit3_chars() { + assertEquals(197, + IOUtils.digit3( + "1972".toCharArray(), 0)); + + char[] chars = new char[4]; + for (int x0 = -1; x0 <= 10; x0++) { + chars[0] = (char) (x0 + '0'); + for (int x1 = -1; x1 <= 10; x1++) { + chars[1] = (char) (x1 + '0'); + for (int x2 = -1; x2 <= 10; x2++) { + chars[2] = (char) (x2 + '0'); + int d3 = IOUtils.digit3(chars, 0); + int expect; + if (x0 < 0 || x0 > 9 || x1 < 0 || x1 > 9 || x2 < 0 || x2 > 9) { + expect = -1; + } else { + expect = x0 * 100 + x1 * 10 + x2; + } + assertEquals(expect, d3); + } + } + } + } + + @Test + public void digit3() { + assertEquals(197, + IOUtils.digit3( + "1972".getBytes(StandardCharsets.UTF_8), 0)); + + byte[] bytes = new byte[4]; + for (int x0 = -1; x0 <= 10; x0++) { + bytes[0] = (byte) (x0 + '0'); + for (int x1 = -1; x1 <= 10; x1++) { + bytes[1] = (byte) (x1 + '0'); + for (int x2 = -1; x2 <= 10; x2++) { + bytes[2] = (byte) (x2 + '0'); + int d3 = IOUtils.digit3(bytes, 0); + int expect; + if (x0 < 0 || x0 > 9 || x1 < 0 || x1 > 9 || x2 < 0 || x2 > 9) { + expect = -1; + } else { + expect = x0 * 100 + x1 * 10 + x2; + } + assertEquals(expect, d3); + } + } + } + } + @Test public void digit2() { byte[] bytes = new byte[2];