blob: 3d73734c7c6a98631883068dcde5fec1783014a2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.compress.utils;
import static org.apache.commons.compress.utils.TimeUtils.HUNDRED_NANOS_PER_MILLISECOND;
import static org.apache.commons.compress.utils.TimeUtils.WINDOWS_EPOCH_OFFSET;
import static org.apache.commons.compress.utils.TimeUtils.ntfsTimeToDate;
import static org.apache.commons.compress.utils.TimeUtils.ntfsTimeToFileTime;
import static org.apache.commons.compress.utils.TimeUtils.toDate;
import static org.apache.commons.compress.utils.TimeUtils.toFileTime;
import static org.apache.commons.compress.utils.TimeUtils.toNtfsTime;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.Date;
import java.util.stream.Stream;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class TimeUtilsTest {
public static Stream<Arguments> dateToNtfsProvider() {
return Stream.of(Arguments.of("1601-01-01T00:00:00.000Z", 0), Arguments.of("1601-01-01T00:00:00.000Z", 1), Arguments.of("1600-12-31T23:59:59.999Z", -1),
Arguments.of("1601-01-01T00:00:00.001Z", HUNDRED_NANOS_PER_MILLISECOND),
Arguments.of("1601-01-01T00:00:00.001Z", HUNDRED_NANOS_PER_MILLISECOND + 1),
Arguments.of("1601-01-01T00:00:00.000Z", HUNDRED_NANOS_PER_MILLISECOND - 1),
Arguments.of("1600-12-31T23:59:59.999Z", -HUNDRED_NANOS_PER_MILLISECOND),
Arguments.of("1600-12-31T23:59:59.999Z", -HUNDRED_NANOS_PER_MILLISECOND + 1),
Arguments.of("1600-12-31T23:59:59.998Z", -HUNDRED_NANOS_PER_MILLISECOND - 1), Arguments.of("1970-01-01T00:00:00.000Z", -WINDOWS_EPOCH_OFFSET),
Arguments.of("1970-01-01T00:00:00.000Z", -WINDOWS_EPOCH_OFFSET + 1),
Arguments.of("1970-01-01T00:00:00.001Z", -WINDOWS_EPOCH_OFFSET + HUNDRED_NANOS_PER_MILLISECOND),
Arguments.of("1969-12-31T23:59:59.999Z", -WINDOWS_EPOCH_OFFSET - 1),
Arguments.of("1969-12-31T23:59:59.999Z", -WINDOWS_EPOCH_OFFSET - HUNDRED_NANOS_PER_MILLISECOND));
}
public static Stream<Arguments> fileTimeToNtfsProvider() {
return Stream.of(Arguments.of("1601-01-01T00:00:00.0000000Z", 0), Arguments.of("1601-01-01T00:00:00.0000001Z", 1),
Arguments.of("1600-12-31T23:59:59.9999999Z", -1), Arguments.of("1601-01-01T00:00:00.0010000Z", HUNDRED_NANOS_PER_MILLISECOND),
Arguments.of("1601-01-01T00:00:00.0010001Z", HUNDRED_NANOS_PER_MILLISECOND + 1),
Arguments.of("1601-01-01T00:00:00.0009999Z", HUNDRED_NANOS_PER_MILLISECOND - 1),
Arguments.of("1600-12-31T23:59:59.9990000Z", -HUNDRED_NANOS_PER_MILLISECOND),
Arguments.of("1600-12-31T23:59:59.9990001Z", -HUNDRED_NANOS_PER_MILLISECOND + 1),
Arguments.of("1600-12-31T23:59:59.9989999Z", -HUNDRED_NANOS_PER_MILLISECOND - 1),
Arguments.of("1970-01-01T00:00:00.0000000Z", -WINDOWS_EPOCH_OFFSET), Arguments.of("1970-01-01T00:00:00.0000001Z", -WINDOWS_EPOCH_OFFSET + 1),
Arguments.of("1970-01-01T00:00:00.0010000Z", -WINDOWS_EPOCH_OFFSET + HUNDRED_NANOS_PER_MILLISECOND),
Arguments.of("1969-12-31T23:59:59.9999999Z", -WINDOWS_EPOCH_OFFSET - 1),
Arguments.of("1969-12-31T23:59:59.9990000Z", -WINDOWS_EPOCH_OFFSET - HUNDRED_NANOS_PER_MILLISECOND));
}
public static Stream<Arguments> fileTimeToUnixTimeArguments() {
return Stream.of(Arguments.of(0L, "1970-01-01T00:00:00Z"), Arguments.of(1672141989L, "2022-12-27T11:53:09Z"),
Arguments.of(Integer.MAX_VALUE, "2038-01-19T03:14:07Z"));
}
public static Stream<Arguments> truncateFileTimeProvider() {
return Stream.of(Arguments.of("2022-05-10T18:25:33.123456789Z", "2022-05-10T18:25:33.1234567Z"),
Arguments.of("1970-01-01T00:00:00.000000001Z", "1970-01-01T00:00:00.0000000Z"),
Arguments.of("1970-01-01T00:00:00.000000010Z", "1970-01-01T00:00:00.0000000Z"),
Arguments.of("1970-01-01T00:00:00.000000199Z", "1970-01-01T00:00:00.0000001Z"),
Arguments.of("1969-12-31T23:59:59.999999999Z", "1969-12-31T23:59:59.9999999Z"),
Arguments.of("1969-12-31T23:59:59.000000001Z", "1969-12-31T23:59:59.0000000Z"),
Arguments.of("1969-12-31T23:59:59.000000010Z", "1969-12-31T23:59:59.0000000Z"),
Arguments.of("1969-12-31T23:59:59.000000199Z", "1969-12-31T23:59:59.0000001Z"));
}
@Test
public void testIsUnixTime() {
assertTrue(TimeUtils.isUnixTime(null));
assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2022-12-27T12:45:22Z"))));
assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:07Z"))));
assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T23:14:08Z"))));
assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T03:14:08Z"))));
assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:08Z"))));
assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2099-06-30T12:31:42Z"))));
}
@ParameterizedTest
@MethodSource("dateToNtfsProvider")
public void testJavaTimeToNtfsTime(final String instant, final long ntfsTime) {
final long ntfsMillis = Math.floorDiv(ntfsTime, HUNDRED_NANOS_PER_MILLISECOND) * HUNDRED_NANOS_PER_MILLISECOND;
final Date parsed = Date.from(Instant.parse(instant));
final long converted = toNtfsTime(parsed);
assertEquals(ntfsMillis, converted);
// ensuring the deprecated method still works
assertEquals(converted, SevenZArchiveEntry.javaTimeToNtfsTime(parsed));
}
@ParameterizedTest
@MethodSource("fileTimeToNtfsProvider")
public void testNtfsTimeToFileTime(final String instant, final long ntfsTime) {
final FileTime parsed = FileTime.from(Instant.parse(instant));
assertEquals(parsed, ntfsTimeToFileTime(ntfsTime));
}
@ParameterizedTest
@MethodSource("dateToNtfsProvider")
public void testNtfsTimeToJavaTime(final String instant, final long ntfsTime) {
final Date converted = ntfsTimeToDate(ntfsTime);
assertEquals(Instant.parse(instant), converted.toInstant());
// ensuring the deprecated method still works
assertEquals(converted, SevenZArchiveEntry.ntfsTimeToJavaTime(ntfsTime));
}
@ParameterizedTest
@MethodSource("fileTimeToNtfsProvider")
public void testToDate(final String instant, final long ignored) {
final Instant parsedInstant = Instant.parse(instant);
final FileTime parsedFileTime = FileTime.from(parsedInstant);
final Date parsedDate = Date.from(parsedInstant);
assertEquals(parsedDate, toDate(parsedFileTime));
}
@Test
public void testToDateNull() {
assertNull(toDate(null));
}
@ParameterizedTest
@MethodSource("dateToNtfsProvider")
public void testToFileTime(final String instant, final long ignored) {
final Instant parsedInstant = Instant.parse(instant);
final FileTime parsedFileTime = FileTime.from(parsedInstant);
final Date parsedDate = Date.from(parsedInstant);
assertEquals(parsedFileTime, toFileTime(parsedDate));
}
@Test
public void testToFileTimeNull() {
assertNull(toFileTime(null));
}
@ParameterizedTest
@MethodSource("fileTimeToNtfsProvider")
public void testToNtfsTime(final String instant, final long ntfsTime) {
final FileTime parsed = FileTime.from(Instant.parse(instant));
assertEquals(ntfsTime, toNtfsTime(parsed));
}
@ParameterizedTest
@MethodSource("fileTimeToUnixTimeArguments")
public void testToUnixTime(final long expectedUnixTime, final String instant) {
assertEquals(expectedUnixTime, TimeUtils.toUnixTime(FileTime.from(Instant.parse(instant))));
}
@ParameterizedTest
@MethodSource("truncateFileTimeProvider")
public void testTruncateToHundredNanos(final String original, final String truncated) {
final FileTime originalTime = FileTime.from(Instant.parse(original));
final FileTime truncatedTime = FileTime.from(Instant.parse(truncated));
assertEquals(truncatedTime, TimeUtils.truncateToHundredNanos(originalTime));
}
@ParameterizedTest
@MethodSource("fileTimeToUnixTimeArguments")
public void testUnixTimeToFileTime(final long unixTime, final String expectedInstant) {
assertEquals(Instant.parse(expectedInstant), TimeUtils.unixTimeToFileTime(unixTime).toInstant());
}
}