package jdk.test; import org.openjdk.jmh.annotations.*; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Date; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; /* Original: Benchmark Mode Samples Score Score error Units j.t.ZipUtilsTest.dosToJavaTime_Date avgt 15 95.644 4.241 ns/op j.t.ZipUtilsTest.dosToJavaTime_LDT avgt 15 118.155 2.980 ns/op j.t.ZipUtilsTest.dosToJavaTime_ZDT avgt 15 131.456 3.586 ns/op j.t.ZipUtilsTest.javaToDosTime_Date avgt 15 74.692 1.709 ns/op j.t.ZipUtilsTest.javaToDosTime_LDT avgt 15 134.116 4.396 ns/op j.t.ZipUtilsTest.javaToDosTime_ZDT avgt 15 141.987 8.697 ns/op Patched TimeZone: Benchmark Mode Samples Score Score error Units j.t.ZipUtilsTest.dosToJavaTime_Date avgt 15 95.590 2.354 ns/op j.t.ZipUtilsTest.dosToJavaTime_LDT avgt 15 79.682 3.572 ns/op j.t.ZipUtilsTest.dosToJavaTime_ZDT avgt 15 86.801 2.081 ns/op j.t.ZipUtilsTest.javaToDosTime_Date avgt 15 75.096 1.178 ns/op j.t.ZipUtilsTest.javaToDosTime_LDT avgt 15 91.919 2.191 ns/op j.t.ZipUtilsTest.javaToDosTime_ZDT avgt 15 92.037 2.054 ns/op Patched TimeZone & ZoneOffsetTransition: Benchmark Mode Samples Score Score error Units j.t.ZipUtilsTest.dosToJavaTime_Date avgt 15 92.291 2.903 ns/op j.t.ZipUtilsTest.dosToJavaTime_LDT avgt 15 79.765 3.106 ns/op j.t.ZipUtilsTest.dosToJavaTime_ZDT avgt 15 87.282 2.967 ns/op j.t.ZipUtilsTest.javaToDosTime_Date avgt 15 76.235 2.651 ns/op j.t.ZipUtilsTest.javaToDosTime_LDT avgt 15 73.115 2.567 ns/op j.t.ZipUtilsTest.javaToDosTime_ZDT avgt 15 75.701 2.226 ns/op */ @BenchmarkMode(Mode.AverageTime) @Fork(3) @Warmup(iterations = 5) @Measurement(iterations = 5) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) public class ZipUtilsTest { static final int LEN = 1 << 10; long[] dosTimes, javaTimes; @Setup public void setup() { dosTimes = new long[LEN]; javaTimes = new long[LEN]; for (int i = 0; i < LEN; i++) { javaTimes[i] = System.currentTimeMillis() - ThreadLocalRandom.current().nextLong(5L * 365L * 24L * 60L * 60L * 1000L); dosTimes[i] = javaToDosTime0(javaTimes[i]); } } int i; @Benchmark public long javaToDosTime_Date() { return javaToDosTime0(javaTimes[(i++) & (LEN - 1)]); } @Benchmark public long dosToJavaTime_Date() { return dosToJavaTime0(dosTimes[(i++) & (LEN - 1)]); } @Benchmark public long javaToDosTime_ZDT() { return javaToDosTime1(javaTimes[(i++) & (LEN - 1)]); } @Benchmark public long dosToJavaTime_ZDT() { return dosToJavaTime1(dosTimes[(i++) & (LEN - 1)]); } @Benchmark public long javaToDosTime_LDT() { return javaToDosTime2(javaTimes[(i++) & (LEN - 1)]); } @Benchmark public long dosToJavaTime_LDT() { return dosToJavaTime2(dosTimes[(i++) & (LEN - 1)]); } /** * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime0(long dtime) { @SuppressWarnings("deprecation") Date d = new Date( (int) (((dtime >> 25) & 0x7f) + 80), (int) (((dtime >> 21) & 0x0f) - 1), (int) ((dtime >> 16) & 0x1f), (int) ((dtime >> 11) & 0x1f), (int) ((dtime >> 5) & 0x3f), (int) ((dtime << 1) & 0x3e) ); return d.getTime(); } /** * Converts Java time to DOS time. */ @SuppressWarnings("deprecation") public static long javaToDosTime0(long time) { Date d = new Date(time); int year = d.getYear() + 1900; if (year < 1980) { return (1 << 21) | (1 << 16); } return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | d.getSeconds() >> 1; } // variants using new java.time API /** * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime1(long dtime) { ZonedDateTime zdt = ZonedDateTime.of( (int) (((dtime >> 25) & 0x7f) + 1980), (int) ((dtime >> 21) & 0x0f), (int) ((dtime >> 16) & 0x1f), (int) ((dtime >> 11) & 0x1f), (int) ((dtime >> 5) & 0x3f), (int) ((dtime << 1) & 0x3e), 0, ZoneId.systemDefault() ); return zdt.toInstant().toEpochMilli(); } /** * Converts Java time to DOS time. */ public static long javaToDosTime1(long time) { ZonedDateTime zdt = ZonedDateTime.ofInstant( Instant.ofEpochMilli(time), ZoneId.systemDefault() ); int year = zdt.getYear() - 1980; if (year < 0) { return (1 << 21) | (1 << 16); } return year << 25 | zdt.getMonthValue() << 21 | zdt.getDayOfMonth() << 16 | zdt.getHour() << 11 | zdt.getMinute() << 5 | Math.min(59, zdt.getSecond()) >> 1; } /** * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime2(long dtime) { LocalDateTime ldt = LocalDateTime.of( (int) (((dtime >> 25) & 0x7f) + 1980), (int) ((dtime >> 21) & 0x0f), (int) ((dtime >> 16) & 0x1f), (int) ((dtime >> 11) & 0x1f), (int) ((dtime >> 5) & 0x3f), (int) ((dtime << 1) & 0x3e) ); return ldt.toEpochSecond( ZoneId.systemDefault().getRules().getOffset(ldt)) * 1000L; } /** * Converts Java time to DOS time. */ public static long javaToDosTime2(long time) { Instant instant = Instant.ofEpochMilli(time); LocalDateTime ldt = LocalDateTime.ofInstant( instant, ZoneId.systemDefault()); int year = ldt.getYear() - 1980; if (year < 0) { return (1 << 21) | (1 << 16); } return year << 25 | ldt.getMonthValue() << 21 | ldt.getDayOfMonth() << 16 | ldt.getHour() << 11 | ldt.getMinute() << 5 | ldt.getSecond() >> 1; } }