View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.io.file.attribute;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.nio.file.attribute.FileTime;
25  import java.time.Instant;
26  import java.util.Date;
27  import java.util.concurrent.TimeUnit;
28  import java.util.stream.Stream;
29  
30  import org.junit.jupiter.api.Test;
31  import org.junit.jupiter.params.ParameterizedTest;
32  import org.junit.jupiter.params.provider.Arguments;
33  import org.junit.jupiter.params.provider.MethodSource;
34  
35  /**
36   * Tests {@link FileTimes}.
37   */
38  public class FileTimesTest {
39  
40      public static Stream<Arguments> dateToNtfsProvider() {
41          // @formatter:off
42          return Stream.of(
43              Arguments.of("1601-01-01T00:00:00.000Z", 0),
44              Arguments.of("1601-01-01T00:00:00.000Z", 1),
45              Arguments.of("1600-12-31T23:59:59.999Z", -1),
46              Arguments.of("1601-01-01T00:00:00.001Z", FileTimes.HUNDRED_NANOS_PER_MILLISECOND),
47              Arguments.of("1601-01-01T00:00:00.001Z", FileTimes.HUNDRED_NANOS_PER_MILLISECOND + 1),
48              Arguments.of("1601-01-01T00:00:00.000Z", FileTimes.HUNDRED_NANOS_PER_MILLISECOND - 1),
49              Arguments.of("1600-12-31T23:59:59.999Z", -FileTimes.HUNDRED_NANOS_PER_MILLISECOND),
50              Arguments.of("1600-12-31T23:59:59.999Z", -FileTimes.HUNDRED_NANOS_PER_MILLISECOND + 1),
51              Arguments.of("1600-12-31T23:59:59.998Z", -FileTimes.HUNDRED_NANOS_PER_MILLISECOND - 1),
52              Arguments.of("1970-01-01T00:00:00.000Z", -FileTimes.WINDOWS_EPOCH_OFFSET),
53              Arguments.of("1970-01-01T00:00:00.000Z", -FileTimes.WINDOWS_EPOCH_OFFSET + 1),
54              Arguments.of("1970-01-01T00:00:00.001Z", -FileTimes.WINDOWS_EPOCH_OFFSET + FileTimes.HUNDRED_NANOS_PER_MILLISECOND),
55              Arguments.of("1969-12-31T23:59:59.999Z", -FileTimes.WINDOWS_EPOCH_OFFSET - 1),
56              Arguments.of("1969-12-31T23:59:59.999Z", -FileTimes.WINDOWS_EPOCH_OFFSET - FileTimes.HUNDRED_NANOS_PER_MILLISECOND));
57          // @formatter:on
58      }
59  
60      public static Stream<Arguments> fileTimeToNtfsProvider() {
61          // @formatter:off
62          return Stream.of(
63              Arguments.of("1601-01-01T00:00:00.0000000Z", 0),
64              Arguments.of("1601-01-01T00:00:00.0000001Z", 1),
65              Arguments.of("1600-12-31T23:59:59.9999999Z", -1),
66              Arguments.of("1601-01-01T00:00:00.0010000Z", FileTimes.HUNDRED_NANOS_PER_MILLISECOND),
67              Arguments.of("1601-01-01T00:00:00.0010001Z", FileTimes.HUNDRED_NANOS_PER_MILLISECOND + 1),
68              Arguments.of("1601-01-01T00:00:00.0009999Z", FileTimes.HUNDRED_NANOS_PER_MILLISECOND - 1),
69              Arguments.of("1600-12-31T23:59:59.9990000Z", -FileTimes.HUNDRED_NANOS_PER_MILLISECOND),
70              Arguments.of("1600-12-31T23:59:59.9990001Z", -FileTimes.HUNDRED_NANOS_PER_MILLISECOND + 1),
71              Arguments.of("1600-12-31T23:59:59.9989999Z", -FileTimes.HUNDRED_NANOS_PER_MILLISECOND - 1),
72              Arguments.of("1970-01-01T00:00:00.0000000Z", -FileTimes.WINDOWS_EPOCH_OFFSET),
73              Arguments.of("1970-01-01T00:00:00.0000001Z", -FileTimes.WINDOWS_EPOCH_OFFSET + 1),
74              Arguments.of("1970-01-01T00:00:00.0010000Z", -FileTimes.WINDOWS_EPOCH_OFFSET + FileTimes.HUNDRED_NANOS_PER_MILLISECOND),
75              Arguments.of("1969-12-31T23:59:59.9999999Z", -FileTimes.WINDOWS_EPOCH_OFFSET - 1),
76              Arguments.of("1969-12-31T23:59:59.9990000Z", -FileTimes.WINDOWS_EPOCH_OFFSET - FileTimes.HUNDRED_NANOS_PER_MILLISECOND));
77          // @formatter:on
78      }
79  
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  
92      @ParameterizedTest
93      @MethodSource("dateToNtfsProvider")
94      public void testDateToFileTime(final String instant, final long ignored) {
95          final Instant parsedInstant = Instant.parse(instant);
96          final FileTime parsedFileTime = FileTime.from(parsedInstant);
97          final Date parsedDate = Date.from(parsedInstant);
98          assertEquals(parsedFileTime, FileTimes.toFileTime(parsedDate));
99      }
100 
101     @ParameterizedTest
102     @MethodSource("dateToNtfsProvider")
103     public void testDateToNtfsTime(final String instant, final long ntfsTime) {
104         final long ntfsMillis = Math.floorDiv(ntfsTime, FileTimes.HUNDRED_NANOS_PER_MILLISECOND) * FileTimes.HUNDRED_NANOS_PER_MILLISECOND;
105         final Date parsed = Date.from(Instant.parse(instant));
106         assertEquals(ntfsMillis, FileTimes.toNtfsTime(parsed));
107         assertEquals(ntfsMillis, FileTimes.toNtfsTime(parsed.getTime()));
108     }
109 
110     @Test
111     public void testEpoch() {
112         assertEquals(0, FileTimes.EPOCH.toMillis());
113     }
114 
115     @ParameterizedTest
116     @MethodSource("fileTimeToNtfsProvider")
117     public void testFileTimeToDate(final String instant, final long ignored) {
118         final Instant parsedInstant = Instant.parse(instant);
119         final FileTime parsedFileTime = FileTime.from(parsedInstant);
120         final Date parsedDate = Date.from(parsedInstant);
121         assertEquals(parsedDate, FileTimes.toDate(parsedFileTime));
122     }
123 
124     @ParameterizedTest
125     @MethodSource("fileTimeToNtfsProvider")
126     public void testFileTimeToNtfsTime(final String instant, final long ntfsTime) {
127         final FileTime parsed = FileTime.from(Instant.parse(instant));
128         assertEquals(ntfsTime, FileTimes.toNtfsTime(parsed));
129     }
130 
131     @ParameterizedTest
132     @MethodSource("dateToNtfsProvider")
133     public void testFromUnixTime(final String instant, final long ntfsTime) {
134         final long epochSecond = Instant.parse(instant).getEpochSecond();
135         assertEquals(epochSecond, FileTimes.fromUnixTime(epochSecond).to(TimeUnit.SECONDS));
136     }
137 
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     public void testIsUnixTimeFileTimeNull() {
145         assertTrue(FileTimes.isUnixTime(null));
146     }
147 
148     @ParameterizedTest
149     @MethodSource("isUnixFileTimeProvider")
150     public void testIsUnixTimeLong(final String instant, final boolean isUnixTime) {
151         assertEquals(isUnixTime, FileTimes.isUnixTime(Instant.parse(instant).getEpochSecond()));
152     }
153 
154     @Test
155     public void testMinusMillis() {
156         final int millis = 2;
157         assertEquals(Instant.EPOCH.minusMillis(millis), FileTimes.minusMillis(FileTimes.EPOCH, millis).toInstant());
158         assertEquals(Instant.EPOCH, FileTimes.minusMillis(FileTimes.EPOCH, 0).toInstant());
159     }
160 
161     @Test
162     public void testMinusNanos() {
163         final int millis = 2;
164         assertEquals(Instant.EPOCH.minusNanos(millis), FileTimes.minusNanos(FileTimes.EPOCH, millis).toInstant());
165         assertEquals(Instant.EPOCH, FileTimes.minusNanos(FileTimes.EPOCH, 0).toInstant());
166     }
167 
168     @Test
169     public void testMinusSeconds() {
170         final int seconds = 2;
171         assertEquals(Instant.EPOCH.minusSeconds(seconds), FileTimes.minusSeconds(FileTimes.EPOCH, seconds).toInstant());
172         assertEquals(Instant.EPOCH, FileTimes.minusSeconds(FileTimes.EPOCH, 0).toInstant());
173     }
174 
175     @ParameterizedTest
176     @MethodSource("dateToNtfsProvider")
177     public void testNtfsTimeToDate(final String instant, final long ntfsTime) {
178         assertEquals(Instant.parse(instant), FileTimes.ntfsTimeToDate(ntfsTime).toInstant());
179     }
180 
181     @ParameterizedTest
182     @MethodSource("fileTimeToNtfsProvider")
183     public void testNtfsTimeToFileTime(final String instant, final long ntfsTime) {
184         final FileTime parsed = FileTime.from(Instant.parse(instant));
185         assertEquals(parsed, FileTimes.ntfsTimeToFileTime(ntfsTime));
186     }
187 
188     @Test
189     public void testNullDateToNullFileTime() {
190         assertNull(FileTimes.toFileTime(null));
191     }
192 
193     @Test
194     public void testNullFileTimeToNullDate() {
195         assertNull(FileTimes.toDate(null));
196     }
197 
198     @Test
199     public void testPlusMinusMillis() {
200         final int millis = 2;
201         assertEquals(Instant.EPOCH.plusMillis(millis), FileTimes.plusMillis(FileTimes.EPOCH, millis).toInstant());
202         assertEquals(Instant.EPOCH, FileTimes.plusMillis(FileTimes.EPOCH, 0).toInstant());
203     }
204 
205     @Test
206     public void testPlusNanos() {
207         final int millis = 2;
208         assertEquals(Instant.EPOCH.plusNanos(millis), FileTimes.plusNanos(FileTimes.EPOCH, millis).toInstant());
209         assertEquals(Instant.EPOCH, FileTimes.plusNanos(FileTimes.EPOCH, 0).toInstant());
210     }
211 
212     @Test
213     public void testPlusSeconds() {
214         final int seconds = 2;
215         assertEquals(Instant.EPOCH.plusSeconds(seconds), FileTimes.plusSeconds(FileTimes.EPOCH, seconds).toInstant());
216         assertEquals(Instant.EPOCH, FileTimes.plusSeconds(FileTimes.EPOCH, 0).toInstant());
217     }
218 
219     @ParameterizedTest
220     @MethodSource("isUnixFileTimeProvider")
221     public void testToUnixTime(final String instant, final boolean isUnixTime) {
222         assertEquals(isUnixTime, FileTimes.isUnixTime(FileTimes.toUnixTime(FileTime.from(Instant.parse(instant)))));
223     }
224 }