Compare commits

...

10 Commits

Author SHA1 Message Date
wenshao
f2eeda18ce optimize writeFloat 2025-01-23 22:33:16 +08:00
wenshao
98d301cfa2 optimize lines 2025-01-23 21:28:44 +08:00
wenshao
5813a23e41 optimize parseTime 2025-01-23 21:18:24 +08:00
wenshao
6bbf68667e formatComplex 2025-01-23 20:12:54 +08:00
wenshao
9568872710 ymd 2025-01-23 19:55:39 +08:00
wenshao
65fa966428 check style 2025-01-23 19:04:41 +08:00
wenshao
f273465d47 bug fix 2025-01-23 18:51:26 +08:00
wenshao
a0483ecc66 optimize parseDate 2025-01-23 17:41:15 +08:00
wenshao
a5c2fe23fc fail fast 2025-01-23 08:44:47 +08:00
wenshao
14dbd1076d fail fast 2025-01-23 08:43:52 +08:00
8 changed files with 211 additions and 158 deletions

View File

@ -40,7 +40,7 @@ public class ClientsWriteCNBytesTest {
long millis = System.currentTimeMillis() - start;
System.out.println("ClientsWriteUTF8Bytes-fastjson2 millis : " + millis);
// zulu8.70.0.23 :
// zulu17.40.19 : 1027
// zulu17.40.19 : 1027 970
// zulu17.40.19_vec :
// zulu17.40.19_reflect :
}

View File

@ -3906,6 +3906,7 @@ public abstract class JSONReader
public static final class Context {
String dateFormat;
boolean formatComplex;
boolean formatyyyyMMddhhmmss19;
boolean formatyyyyMMddhhmmssT19;
boolean yyyyMMddhhmm16;
@ -4240,6 +4241,7 @@ public abstract class JSONReader
break;
}
this.formatComplex = !(formatyyyyMMddhhmmss19 | formatyyyyMMddhhmmssT19 | formatyyyyMMdd8 | formatISO8601);
// this.yyyyMMddhhmm16 = "yyyy-MM-dd HH:mm".equals(format);
}

View File

@ -4506,13 +4506,7 @@ class JSONReaderUTF16
final char[] chars = this.chars;
int offset = this.offset;
if (ch == '"' || ch == '\'') {
Context context = this.context;
if (context.dateFormat == null
|| context.formatyyyyMMddhhmmss19
|| context.formatyyyyMMddhhmmssT19
|| context.formatyyyyMMdd8
|| context.formatISO8601
) {
if (!context.formatComplex) {
char quote = ch;
int c10 = offset + 10;
if (c10 < chars.length
@ -4576,14 +4570,8 @@ class JSONReaderUTF16
public final OffsetDateTime readOffsetDateTime() {
final char[] chars = this.chars;
final int offset = this.offset;
final Context context = this.context;
if (this.ch == '"' || this.ch == '\'') {
if (context.dateFormat == null
|| context.formatyyyyMMddhhmmss19
|| context.formatyyyyMMddhhmmssT19
|| context.formatyyyyMMdd8
|| context.formatISO8601
) {
if (!context.formatComplex) {
char quote = this.ch;
char c10;
int off21 = offset + 19;

View File

@ -13,6 +13,7 @@ import java.util.*;
import static com.alibaba.fastjson2.JSONFactory.*;
import static com.alibaba.fastjson2.JSONReaderJSONB.check3;
import static com.alibaba.fastjson2.util.DateUtils.*;
import static com.alibaba.fastjson2.util.IOUtils.*;
import static com.alibaba.fastjson2.util.JDKUtils.*;
import static java.lang.Long.MIN_VALUE;
@ -5711,29 +5712,21 @@ class JSONReaderUTF8
public final LocalDate readLocalDate() {
final byte[] bytes = this.bytes;
int offset = this.offset;
if (ch == '"' || ch == '\'') {
Context context = this.context;
if (context.dateFormat == null
|| context.formatyyyyMMddhhmmss19
|| context.formatyyyyMMddhhmmssT19
|| context.formatyyyyMMdd8
|| context.formatISO8601
) {
char quote = ch;
char quote = ch;
if (quote == '"' || quote == '\'') {
if (!this.context.formatComplex) {
int yy;
long ymd;
int c10 = offset + 10;
if (c10 < bytes.length
&& c10 < end
&& bytes[offset + 4] == '-'
&& bytes[offset + 7] == '-'
&& (yy = yy(bytes, offset)) != -1
&& ((ymd = ymd(bytes, offset + 2))) != -1L
&& bytes[offset + 10] == quote
) {
int year = IOUtils.digit4(bytes, offset);
int month = IOUtils.digit2(bytes, offset + 5);
int dom = IOUtils.digit2(bytes, offset + 8);
if ((year | month | dom) < 0) {
throw new JSONException(info("read date error"));
}
int year = yy + ((int) ymd & 0xFF);
int month = (int) (ymd >> 24) & 0xFF;
int dom = (int) (ymd >> 48) & 0xFF;
LocalDate ldt;
try {
@ -5782,35 +5775,26 @@ class JSONReaderUTF8
public final OffsetDateTime readOffsetDateTime() {
final byte[] bytes = this.bytes;
final int offset = this.offset;
final Context context = this.context;
if (this.ch == '"' || this.ch == '\'') {
if (context.dateFormat == null
|| context.formatyyyyMMddhhmmss19
|| context.formatyyyyMMddhhmmssT19
|| context.formatyyyyMMdd8
|| context.formatISO8601
) {
char quote = this.ch;
char quote = this.ch;
if (quote == '"' || quote == '\'') {
if (!this.context.formatComplex) {
byte c10;
int off21 = offset + 19;
int yy;
long ymd, hms;
if (off21 < bytes.length
&& off21 < end
&& bytes[offset + 4] == '-'
&& bytes[offset + 7] == '-'
&& (yy = yy(bytes, offset)) != -1
&& ((ymd = ymd(bytes, offset + 2))) != -1L
&& ((c10 = bytes[offset + 10]) == ' ' || c10 == 'T')
&& bytes[offset + 13] == ':'
&& bytes[offset + 16] == ':'
&& ((hms = hms(bytes, offset + 11))) != -1L
) {
int year = IOUtils.digit4(bytes, offset);
int month = IOUtils.digit2(bytes, offset + 5);
int dom = IOUtils.digit2(bytes, offset + 8);
int hour = IOUtils.digit2(bytes, offset + 11);
int minute = IOUtils.digit2(bytes, offset + 14);
int second = IOUtils.digit2(bytes, offset + 17);
if ((year | month | dom | minute | second) < 0) {
ZonedDateTime zdt = readZonedDateTime();
return zdt == null ? null : zdt.toOffsetDateTime();
}
int year = yy + ((int) ymd & 0xFF);
int month = (int) (ymd >> 24) & 0xFF;
int dom = (int) (ymd >> 48) & 0xFF;
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
LocalDate localDate;
try {

View File

@ -1058,7 +1058,7 @@ final class JSONWriterJSONB
bytes = grow(minCapacity);
}
int i = (int) value;
if (i == value && value >= BC_INT32_NUM_MIN && value <= BC_INT32_NUM_MAX) {
if (i == value && i >= BC_INT32_NUM_MIN && i <= BC_INT32_NUM_MAX) {
putShortLE(bytes, off, (short) ((BC_FLOAT_INT & 0xFF) | (i << 8)));
off += 2;
} else {

View File

@ -2250,41 +2250,35 @@ public class DateUtils {
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];
int year, month, dom, hour, minute, second;
int year, month, dom;
if (((c4 == '-' && c7 == '-') || (c4 == '/' && c7 == '/'))
&& (c10 == ' ' || c10 == 'T')
&& c13 == ':' && c16 == ':'
) {
&& (c10 == ' ' || c10 == 'T')) {
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 == ':') {
} else if (c2 == '/' && c5 == '/' && (c10 == ' ' || c10 == 'T')) {
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 == ':') {
} else if (c1 == ' ' && c5 == ' ' && c10 == ' ') {
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 (year | month | dom | hour | minute | second) <= 0
? null
: LocalDateTime.of(year, month, dom, hour, minute, second);
long hms = hms(str, off + 11);
if ((year | month | dom | hms) <= 0) {
return null;
}
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
return LocalDateTime.of(year, month, dom, hour, minute, second);
}
public static LocalDateTime parseLocalDateTime20(char[] str, int off) {
@ -2311,12 +2305,12 @@ public class DateUtils {
}
public static LocalDateTime parseLocalDateTime20(byte[] str, int off) {
long hms;
if (off + 19 > str.length
|| str[off + 2] != ' '
|| str[off + 6] != ' '
|| str[off + 11] != ' '
|| str[off + 14] != ':'
|| str[off + 17] != ':'
|| (hms = hms(str, off + 12)) == -1L
) {
return null;
}
@ -2324,9 +2318,9 @@ public class DateUtils {
int dom = digit2(str, off);
int month = DateUtils.month(str[off + 3], str[off + 4], str[off + 5]);
int year = digit4(str, off + 7);
int hour = digit2(str, off + 12);
int minute = digit2(str, off + 15);
int second = digit2(str, off + 18);
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
return (year | month | dom | hour | minute | second) <= 0 || hour > 24 || minute > 59 || second > 60
? null
@ -2334,13 +2328,13 @@ public class DateUtils {
}
public static LocalDateTime parseLocalDateTime26(byte[] str, int off) {
long hms;
byte c10;
if (off + 26 > str.length
|| str[off + 4] != '-'
|| str[off + 7] != '-'
|| ((c10 = str[off + 10]) != ' ' && c10 != 'T')
|| str[off + 13] != ':'
|| str[off + 16] != ':'
|| (hms = hms(str, off + 11)) == -1L
|| str[off + 19] != '.'
) {
return null;
@ -2349,9 +2343,9 @@ public class DateUtils {
int year = digit4(str, off);
int month = digit2(str, off + 5);
int dom = digit2(str, off + 8);
int hour = digit2(str, off + 11);
int minute = digit2(str, off + 14);
int second = digit2(str, off + 17);
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
int nano = readNanos(str, 6, off + 20);
return (year | month | dom | hour | minute | second | nano) <= 0 || hour > 24 || minute > 59 || second > 60
@ -2386,13 +2380,13 @@ public class DateUtils {
}
public static LocalDateTime parseLocalDateTime27(byte[] str, int off) {
long hms;
byte c10;
if (off + 27 > str.length
|| str[off + 4] != '-'
|| str[off + 7] != '-'
|| ((c10 = str[off + 10]) != ' ' && c10 != 'T')
|| str[off + 13] != ':'
|| str[off + 16] != ':'
|| (hms = hms(str, off + 11)) == -1L
|| str[off + 19] != '.'
) {
return null;
@ -2401,9 +2395,9 @@ public class DateUtils {
int year = digit4(str, off);
int month = digit2(str, off + 5);
int dom = digit2(str, off + 8);
int hour = digit2(str, off + 11);
int minute = digit2(str, off + 14);
int second = digit2(str, off + 17);
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
int nano = readNanos(str, 7, off + 20);
return (year | month | dom | hour | minute | second | nano) <= 0 || hour > 24 || minute > 59 || second > 60
@ -2464,13 +2458,13 @@ public class DateUtils {
}
public static LocalDateTime parseLocalDateTime28(byte[] str, int off) {
long hms;
byte c10;
if (off + 28 > str.length
|| str[off + 4] != '-'
|| str[off + 7] != '-'
|| ((c10 = str[off + 10]) != ' ' && c10 != 'T')
|| str[off + 13] != ':'
|| str[off + 16] != ':'
|| (hms = hms(str, off + 11)) == -1L
|| str[off + 19] != '.'
) {
return null;
@ -2479,9 +2473,9 @@ public class DateUtils {
int year = digit4(str, off);
int month = digit2(str, off + 5);
int dom = digit2(str, off + 8);
int hour = digit2(str, off + 11);
int minute = digit2(str, off + 14);
int second = digit2(str, off + 17);
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
int nano = readNanos(str, 8, off + 20);
return (year | month | dom | hour | minute | second | nano) <= 0 || hour > 24 || minute > 59 || second > 60
@ -2490,13 +2484,13 @@ public class DateUtils {
}
public static LocalDateTime parseLocalDateTime29(byte[] str, int off) {
long hms;
byte c10;
if (off + 29 > str.length
|| str[off + 4] != '-'
|| str[off + 7] != '-'
|| ((c10 = str[off + 10]) != ' ' && c10 != 'T')
|| str[off + 13] != ':'
|| str[off + 16] != ':'
|| (hms = hms(str, off + 11)) == -1L
|| str[off + 19] != '.'
) {
return null;
@ -2505,9 +2499,9 @@ public class DateUtils {
int year = digit4(str, off);
int month = digit2(str, off + 5);
int dom = digit2(str, off + 8);
int hour = digit2(str, off + 11);
int minute = digit2(str, off + 14);
int second = digit2(str, off + 17);
int hour = (int) hms & 0xFF;
int minute = (int) (hms >> 24) & 0xFF;
int second = (int) (hms >> 48) & 0xFF;
int nano = readNanos(str, 9, off + 20);
return (year | month | dom | hour | minute | second | nano) <= 0 || hour > 24 || minute > 59 || second > 60
@ -9202,4 +9196,34 @@ public class DateUtils {
0,
0,
};
public static long hms(byte[] bytes, int off) {
long v = getLongLE(bytes, off);
long d;
if ((((v & 0xF0F0F0F0_F0F0F0F0L) - 0x30303030_30303030L) | (((d = v & 0x0F0F0F0F_0F0F0F0FL) + 0x06060006_06000606L) & 0xF0F000F0_F000F0F0L)) != 0
|| (d & 0x00000F00_000F0000L) != 0x00000a00_000a0000L) { // 00:00:00
return -1;
}
return ((d & 0x00F_0000_0F00_000FL) << 3) + ((d & 0x00F_0000_0F00_000FL) << 1) + ((d & 0xF00_000F_0000_0F00L) >> 8);
}
public static long ymd(byte[] bytes, int off) {
long v = getLongLE(bytes, off);
long d;
if (((v & 0x0000FF00_00FF0000L) != 0x00002d00_002d0000L) // yy-mm-dd
|| (((v & 0xF0F000F0_F000F0F0L) - 0x30300030_30003030L) | (((d = v & 0x0F0F000F_0F000F0FL) + 0x06060006_06000606L) & 0xF0F000F0_F000F0F0L)) != 0) {
return -1;
}
return ((d & 0x00F_0000_0F00_000FL) << 3) + ((d & 0x00F_0000_0F00_000FL) << 1) + ((d & 0xF00_000F_0000_0F00L) >> 8);
}
public static int yy(byte[] bytes, int off) {
int x = getShortLE(bytes, off);
int d;
if ((((x & 0xF0F0) - 0x3030) | (((d = x & 0x0F0F) + 0x0606) & 0xF0F0)) != 0
) {
return -1;
}
return (d & 0xF) * 1000 + (d >> 8) * 100;
}
}

View File

@ -93,15 +93,6 @@ public class IOUtils {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1
};
if (BIG_ENDIAN) {
for (int i = 0; i < shorts.length; i++) {
shorts[i] = Short.reverseBytes(shorts[i]);
}
for (int i = 0; i < digits.length; i++) {
digits[i] = Integer.reverseBytes(digits[i] << 8);
}
}
PACKED_DIGITS = shorts;
PACKED_DIGITS_UTF16 = digits;
@ -112,24 +103,25 @@ public class IOUtils {
int c3 = i % 10 + '0';
DIGITS_K_32[i] = c0 + (c1 << 8) + (c2 << 16) + (c3 << 24);
long v = (c1 << 16) + (((long) c2) << 32) + (((long) c3) << 48);
if (BIG_ENDIAN) {
v <<= 8;
}
DIGITS_K_64[i] = c0 + v;
}
ZERO_DOT_LATIN1 = UNSAFE.getShort(new byte[] {'0', '.'}, ARRAY_BYTE_BASE_OFFSET);
ZERO_DOT_UTF16 = UNSAFE.getInt(new char[] {'0', '.'}, ARRAY_CHAR_BASE_OFFSET);
}
private static short digitPair(int value) {
return PACKED_DIGITS[value & 0x7f];
}
public static void writeDigitPair(byte[] buf, int charPos, int value) {
putShortUnaligned(
putShortLE(
buf,
charPos,
PACKED_DIGITS[value & 0x7f]);
}
public static void writeDigitPair(char[] buf, int charPos, int value) {
putIntUnaligned(
putIntLE(
buf,
charPos,
PACKED_DIGITS_UTF16[value & 0x7f]);
@ -743,7 +735,14 @@ public class IOUtils {
if (len == -1) {
break;
}
for (int i = 0; i < len; i++) {
int i = 0;
long address = ARRAY_BYTE_BASE_OFFSET;
int upperBound = (len & ~7);
while (i < upperBound && notContains(UNSAFE.getLong(buf, address), 0x0A0A0A0A0A0A0A0AL)) {
i += 8;
address += 8;
}
for (; i < len; i++) {
byte b = buf[i];
if (b == '\n') {
lines++;
@ -754,23 +753,29 @@ public class IOUtils {
}
public static int writeLocalDate(byte[] bytes, int off, int year, int month, int dayOfMonth) {
if (year >= 0 && year < 10000) {
int y01 = year / 100;
writeDigitPair(bytes, off, y01);
putLongLE(
bytes,
off + 2,
0x2d00002d0000L
| digitPair(year - y01 * 100)
| ((long) digitPair(month) << 24)
| ((long) digitPair(dayOfMonth) << 48));
return off + 10;
}
return writeLocalDate0(bytes, off, year, month, dayOfMonth);
}
private static int writeLocalDate0(byte[] bytes, int off, int year, int month, int dayOfMonth) {
if (year < 0) {
putByte(bytes, off++, (byte) '-');
year = -year;
} else if (year > 9999) {
putByte(bytes, off++, (byte) '+');
}
if (year < 10000) {
int y01 = year / 100;
int y23 = year - y01 * 100;
writeDigitPair(bytes, off, y01);
writeDigitPair(bytes, off + 2, y23);
off += 4;
} else {
off = IOUtils.writeInt32(bytes, off, year);
}
off = IOUtils.writeInt32(bytes, off, year);
putByte(bytes, off, (byte) '-');
writeDigitPair(bytes, off + 1, month);
putByte(bytes, off + 3, (byte) '-');
@ -779,23 +784,29 @@ public class IOUtils {
}
public static int writeLocalDate(char[] chars, int off, int year, int month, int dayOfMonth) {
if (year >= 0 && year < 10000) {
int y01 = year / 100;
int y23 = year - y01 * 100;
writeDigitPair(chars, off, y01);
writeDigitPair(chars, off + 2, y23);
putChar(chars, off + 4, '-');
writeDigitPair(chars, off + 5, month);
putChar(chars, off + 7, '-');
writeDigitPair(chars, off + 8, dayOfMonth);
return off + 10;
}
return writeLocalDate0(chars, off, year, month, dayOfMonth);
}
public static int writeLocalDate0(char[] chars, int off, int year, int month, int dayOfMonth) {
if (year < 0) {
putChar(chars, off++, '-');
year = -year;
} else if (year > 9999) {
putChar(chars, off++, '+');
}
if (year < 10000) {
int y01 = year / 100;
int y23 = year - y01 * 100;
writeDigitPair(chars, off, y01);
writeDigitPair(chars, off + 2, y23);
off += 4;
} else {
off = IOUtils.writeInt32(chars, off, year);
}
off = IOUtils.writeInt32(chars, off, year);
putChar(chars, off, '-');
writeDigitPair(chars, off + 1, month);
putChar(chars, off + 3, '-');
@ -804,17 +815,18 @@ public class IOUtils {
}
public static void writeLocalTime(byte[] bytes, int off, int hour, int minute, int second) {
writeDigitPair(bytes, off, hour);
putByte(bytes, off + 2, (byte) ':');
writeDigitPair(bytes, off + 3, minute);
putByte(bytes, off + 5, (byte) ':');
writeDigitPair(bytes, off + 6, second);
putLongLE(
bytes,
off,
0x3a00003a0000L
| digitPair(hour)
| ((long) digitPair(minute) << 24)
| ((long) digitPair(second) << 48));
}
public static int writeLocalTime(byte[] bytes, int off, LocalTime time) {
writeLocalTime(bytes, off, time.getHour(), time.getMinute(), time.getSecond());
off += 8;
int nano = time.getNano();
return nano != 0 ? writeNano(bytes, off, nano) : off;
}
@ -1859,35 +1871,38 @@ public class IOUtils {
}
public static boolean isLatin1(char[] chars, int off, int len) {
int upperBound = off + (len & ~7);
int end = off + len;
int upperBound = off + (len & ~7);
long address = ARRAY_CHAR_BASE_OFFSET + off;
long value = 0;
while (off < upperBound) {
value |= UNSAFE.getLong(chars, address) | UNSAFE.getLong(chars, address + 8);
while (off < upperBound
&& (convEndian(false, (UNSAFE.getLong(chars, address) | UNSAFE.getLong(chars, address + 8))) & 0xFF00FF00FF00FF00L) == 0
) {
address += 16;
off += 8;
}
while (off++ < end) {
value |= UNSAFE.getShort(chars, address);
if ((convEndian(false, UNSAFE.getShort(chars, address)) & 0xFF00) != 0) {
return false;
}
address += 2;
}
return (convEndian(false, value) & 0xFF00FF00FF00FF00L) == 0;
return true;
}
public static boolean isASCII(byte[] bytes, int off, int len) {
int upperBound = off + (len & ~7);
int end = off + len;
int upperBound = off + (len & ~7);
long address = ARRAY_BYTE_BASE_OFFSET + off;
long value = 0;
while (off < upperBound) {
value |= UNSAFE.getLong(bytes, address);
while (off < upperBound && (UNSAFE.getLong(bytes, address) & 0x8080808080808080L) == 0) {
address += 8;
off += 8;
}
while (off < end) {
value |= bytes[off++];
while (off++ < end) {
if ((UNSAFE.getByte(bytes, address++) & 0x80) != 0) {
return false;
}
}
return (value & 0x8080808080808080L) == 0;
return true;
}
}

View File

@ -2877,4 +2877,44 @@ public class DateUtilsTest {
assertNull(DateUtils.parseLocalDateTime(bytes, 0, bytes.length));
assertNull(DateUtils.parseLocalDateTime(chars, 0, bytes.length));
}
static long timeV(long x) {
long d;
if ((((x & 0xF0F0F0F0_F0F0F0F0L) - 0x30303030_30303030L) | (((d = x & 0x0F0F0F0F_0F0F0F0FL) + 0x06060006_06000606L) & 0xF0F000F0_F000F0F0L)) != 0
|| (d & 0x00000F00_000F0000L) != 0x00000a00_000a0000L
) {
return -1;
}
// return ((d & 0xF) << 3) + ((d & 0xF) << 1) // (d & 0xF) * 10
// + (d >> 8);
return ((d & 0x00F_0000_0F00_000FL) << 3) + ((d & 0x00F_0000_0F00_000FL) << 1) + ((d & 0xF00_000F_0000_0F00L) >> 8);
}
static long MonthDay(long timeV) {
long d;
if (((timeV & 0x0000FF00_00FF0000L) != 0x00002d00_002d0000L)
|| (((timeV & 0xF0F000F0_F000F0F0L) - 0x30300030_30003030L) | (((d = timeV & 0x0F0F000F_0F000F0FL) + 0x06060006_06000606L) & 0xF0F000F0_F000F0F0L)) != 0) {
return -1;
}
return ((d & 0x00F_0000_0F00_000FL) << 3) + ((d & 0x00F_0000_0F00_000FL) << 1) + ((d & 0xF00_000F_0000_0F00L) >> 8);
}
@Test
public void timeV() {
// byte[] bytes = new byte[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':'};
// for (byte b : bytes) {
// System.out.println((char) b + "\t" + b + "\t" + Integer.toHexString(b) + "\t" + Integer.toBinaryString(b));
// }
// long x = 0;
//
// System.out.println(Integer.toHexString(0b11_0000));
byte[] bytes = "1978-12-13".getBytes();
long x = IOUtils.getLongLE(bytes, 2);
long t = MonthDay(x);
System.out.println(Long.toHexString(t));
System.out.println(t & 0xFF);
System.out.println((t >> 24) & 0xFF);
System.out.println((t >> 48) & 0xFF);
// System.out.println(Integer.toString('-') + "\t" + Integer.toBinaryString('-'));
}
}