| /* |
| * 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()); |
| } |
| } |