Skip to content

Commit d5898c1

Browse files
committed
Add FileTimes.isUnixTime(FileTime)
- Add FileTimes.isUnixTime(long) - Add FileTimes.toUnixTime(FileTime)
1 parent cae58ff commit d5898c1

3 files changed

Lines changed: 79 additions & 2 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ The <action> type attribute can be add,update,fix,remove.
8686
<action dev="ggregory" type="add" due-to="Gary Gregory">Add BoundedInputStream.getRemaining().</action>
8787
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FileTimes.toNtfsTime(long).</action>
8888
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FileTimes.fromUnixTime(long).</action>
89+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FileTimes.isUnixTime(FileTime).</action>
90+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FileTimes.isUnixTime(long).</action>
91+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FileTimes.toUnixTime(FileTime).</action>
8992
<!-- UPDATE -->
9093
<action dev="ggregory" type="fix" due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.14.10 to 1.14.11 #534.</action>
9194
</release>

src/main/java/org/apache/commons/io/file/attribute/FileTimes.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,32 @@ public static FileTime fromUnixTime(final long time) {
7272
return FileTime.from(time, TimeUnit.SECONDS);
7373
}
7474

75+
/**
76+
* Tests whether a FileTime can be safely represented in the standard UNIX time.
77+
* <p>
78+
* If the FileTime is null, this method returns true.
79+
* </p>
80+
*
81+
* @param time the FileTime to evaluate, can be null.
82+
* @return true if the time exceeds the minimum or maximum UNIX time, false otherwise.
83+
* @since 2.16.0
84+
*/
85+
public static boolean isUnixTime(final FileTime time) {
86+
return isUnixTime(toUnixTime(time));
87+
}
88+
89+
/**
90+
* Tests whether a given number of seconds (since Epoch) can be safely represented in the standard UNIX time.
91+
*
92+
* @param seconds the number of seconds (since Epoch) to evaluate.
93+
* @return true if the time can be represented in the standard UNIX time, false otherwise.
94+
* @since 2.16.0
95+
*/
96+
public static boolean isUnixTime(final long seconds) {
97+
return Integer.MIN_VALUE <= seconds && seconds <= Integer.MAX_VALUE;
98+
}
99+
100+
75101
/**
76102
* Subtracts milliseconds from a source FileTime.
77103
*
@@ -243,6 +269,21 @@ public static long toNtfsTime(final long javaTime) {
243269
return Math.subtractExact(javaHundredNanos, WINDOWS_EPOCH_OFFSET);
244270
}
245271

272+
/**
273+
* Converts {@link FileTime} to standard UNIX time in seconds.
274+
* <p>
275+
* The returned seconds value may lie out of bounds of UNIX time. Check with {@link FileTimes#isUnixTime(long)}.
276+
* </p>
277+
*
278+
* @param fileTime the original FileTime.
279+
* @return the UNIX timestamp or 0 if the input is null.
280+
* @see #isUnixTime(long)
281+
* @since 2.16.0
282+
*/
283+
public static long toUnixTime(final FileTime fileTime) {
284+
return fileTime != null ? fileTime.to(TimeUnit.SECONDS) : 0;
285+
}
286+
246287
private FileTimes() {
247288
// No instances.
248289
}

src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.junit.jupiter.api.Assertions.assertEquals;
2121
import static org.junit.jupiter.api.Assertions.assertNull;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
2223

2324
import java.nio.file.attribute.FileTime;
2425
import java.time.Instant;
@@ -76,6 +77,18 @@ public static Stream<Arguments> fileTimeToNtfsProvider() {
7677
// @formatter:on
7778
}
7879

80+
public static Stream<Arguments> isUnixFileTimeProvider() {
81+
// @formatter:off
82+
return Stream.of(
83+
Arguments.of("2022-12-27T12:45:22Z", true),
84+
Arguments.of("2038-01-19T03:14:07Z", true),
85+
Arguments.of("1901-12-13T23:14:08Z", true),
86+
Arguments.of("1901-12-13T03:14:08Z", false),
87+
Arguments.of("2038-01-19T03:14:08Z", false),
88+
Arguments.of("2099-06-30T12:31:42Z", false));
89+
// @formatter:on
90+
}
91+
7992
@ParameterizedTest
8093
@MethodSource("dateToNtfsProvider")
8194
public void testDateToFileTime(final String instant, final long ignored) {
@@ -115,15 +128,35 @@ public void testFileTimeToNtfsTime(final String instant, final long ntfsTime) {
115128
assertEquals(ntfsTime, FileTimes.toNtfsTime(parsed));
116129
}
117130

118-
//
119-
120131
@ParameterizedTest
121132
@MethodSource("dateToNtfsProvider")
122133
public void testFromUnixTime(final String instant, final long ntfsTime) {
123134
final long epochSecond = Instant.parse(instant).getEpochSecond();
124135
assertEquals(epochSecond, FileTimes.fromUnixTime(epochSecond).to(TimeUnit.SECONDS));
125136
}
126137

138+
@ParameterizedTest
139+
@MethodSource("isUnixFileTimeProvider")
140+
public void testIsUnixTime(final String instant, final boolean isUnixTime) {
141+
assertEquals(isUnixTime, FileTimes.isUnixTime(FileTime.from(Instant.parse(instant))));
142+
}
143+
144+
@ParameterizedTest
145+
@MethodSource("isUnixFileTimeProvider")
146+
public void testIsUnixTimeLong(final String instant, final boolean isUnixTime) {
147+
assertEquals(isUnixTime, FileTimes.isUnixTime(Instant.parse(instant).getEpochSecond()));
148+
}
149+
150+
@ParameterizedTest
151+
@MethodSource("isUnixFileTimeProvider")
152+
public void testToUnixTime(final String instant, final boolean isUnixTime) {
153+
assertEquals(isUnixTime, FileTimes.isUnixTime(FileTimes.toUnixTime(FileTime.from(Instant.parse(instant)))));
154+
}
155+
156+
public void testIsUnixTimeFileTimeNull() {
157+
assertTrue(FileTimes.isUnixTime(null));
158+
}
159+
127160
@Test
128161
public void testMinusMillis() {
129162
final int millis = 2;

0 commit comments

Comments
 (0)