|
1 | 1 | /*
|
2 |
| - * Copyright 2012-2019 the original author or authors. |
| 2 | + * Copyright 2012-2020 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
17 | 17 | package org.springframework.boot.loader.jar;
|
18 | 18 |
|
19 | 19 | import java.io.IOException;
|
20 |
| -import java.time.LocalDateTime; |
21 | 20 | import java.time.ZoneId;
|
| 21 | +import java.time.ZonedDateTime; |
| 22 | +import java.time.temporal.ChronoField; |
| 23 | +import java.time.temporal.ChronoUnit; |
| 24 | +import java.time.temporal.ValueRange; |
22 | 25 |
|
23 | 26 | import org.springframework.boot.loader.data.RandomAccessData;
|
24 | 27 |
|
|
27 | 30 | *
|
28 | 31 | * @author Phillip Webb
|
29 | 32 | * @author Andy Wilkinson
|
| 33 | + * @author Dmytro Nosan |
30 | 34 | * @see <a href="https://en.wikipedia.org/wiki/Zip_%28file_format%29">Zip File Format</a>
|
31 | 35 | */
|
32 | 36 |
|
@@ -124,10 +128,14 @@ public long getTime() {
|
124 | 128 | * @return the date and time as milliseconds since the epoch
|
125 | 129 | */
|
126 | 130 | private long decodeMsDosFormatDateTime(long datetime) {
|
127 |
| - LocalDateTime localDateTime = LocalDateTime.of((int) (((datetime >> 25) & 0x7f) + 1980), |
128 |
| - (int) ((datetime >> 21) & 0x0f), (int) ((datetime >> 16) & 0x1f), (int) ((datetime >> 11) & 0x1f), |
129 |
| - (int) ((datetime >> 5) & 0x3f), (int) ((datetime << 1) & 0x3e)); |
130 |
| - return localDateTime.toEpochSecond(ZoneId.systemDefault().getRules().getOffset(localDateTime)) * 1000; |
| 131 | + int year = getChronoValue(((datetime >> 25) & 0x7f) + 1980, ChronoField.YEAR); |
| 132 | + int month = getChronoValue((datetime >> 21) & 0x0f, ChronoField.MONTH_OF_YEAR); |
| 133 | + int day = getChronoValue((datetime >> 16) & 0x1f, ChronoField.DAY_OF_MONTH); |
| 134 | + int hour = getChronoValue((datetime >> 11) & 0x1f, ChronoField.HOUR_OF_DAY); |
| 135 | + int minute = getChronoValue((datetime >> 5) & 0x3f, ChronoField.MINUTE_OF_HOUR); |
| 136 | + int second = getChronoValue((datetime << 1) & 0x3e, ChronoField.SECOND_OF_MINUTE); |
| 137 | + return ZonedDateTime.of(year, month, day, hour, minute, second, 0, ZoneId.systemDefault()).toInstant() |
| 138 | + .truncatedTo(ChronoUnit.SECONDS).toEpochMilli(); |
131 | 139 | }
|
132 | 140 |
|
133 | 141 | public long getCrc() {
|
@@ -172,4 +180,9 @@ public static CentralDirectoryFileHeader fromRandomAccessData(RandomAccessData d
|
172 | 180 | return fileHeader;
|
173 | 181 | }
|
174 | 182 |
|
| 183 | + private static int getChronoValue(long value, ChronoField field) { |
| 184 | + ValueRange range = field.range(); |
| 185 | + return Math.toIntExact(Math.min(Math.max(value, range.getMinimum()), range.getMaximum())); |
| 186 | + } |
| 187 | + |
175 | 188 | }
|
0 commit comments