1 /* 2 * Copyright (C) 2019, Thomas Wolf <thomas.wolf@paranor.ch> and others 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0 which is available at 6 * https://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 package org.eclipse.jgit.treewalk; 11 12 import java.time.Instant; 13 import java.util.Comparator; 14 15 /** 16 * Specialized comparator for {@link Instant}s. If either timestamp has a zero 17 * fraction, compares only seconds. If either timestamp has no time fraction 18 * smaller than a millisecond, compares only milliseconds. If either timestamp 19 * has no fraction smaller than a microsecond, compares only microseconds. 20 */ 21 class InstantComparator implements Comparator<Instant> { 22 23 @Override 24 public int compare(Instant a, Instant b) { 25 return compare(a, b, false); 26 } 27 28 /** 29 * Compares two {@link Instant}s to the lower resolution of the two 30 * instants. See {@link InstantComparator}. 31 * 32 * @param a 33 * first {@link Instant} to compare 34 * @param b 35 * second {@link Instant} to compare 36 * @param forceSecondsOnly 37 * whether to omit all fraction comparison 38 * @return a value < 0 if a < b, a value > 0 if a > b, and 0 if 39 * a == b 40 */ 41 public int compare(Instant a, Instant b, boolean forceSecondsOnly) { 42 long aSeconds = a.getEpochSecond(); 43 long bSeconds = b.getEpochSecond(); 44 int result = Long.compare(aSeconds, bSeconds); 45 if (result != 0) { 46 return result; 47 } 48 int aSubSecond = a.getNano(); 49 int bSubSecond = b.getNano(); 50 if (forceSecondsOnly || (aSubSecond == 0) 51 || (bSubSecond == 0)) { 52 // Don't check the subseconds part. 53 return 0; 54 } else if (aSubSecond != bSubSecond) { 55 // If either has nothing smaller than a millisecond, compare only 56 // milliseconds. 57 int aSubMillis = aSubSecond % 1_000_000; 58 int bSubMillis = bSubSecond % 1_000_000; 59 if (aSubMillis == 0) { 60 bSubSecond -= bSubMillis; 61 } else if (bSubMillis == 0) { 62 aSubSecond -= aSubMillis; 63 } else { 64 // Same again, but for microsecond resolution. NTFS has 100ns 65 // resolution, but WindowsFileAttributes may provide only 66 // microseconds (1000ns). Similar for some Unix file systems. 67 int aSubMicros = aSubSecond % 1000; 68 int bSubMicros = bSubSecond % 1000; 69 if (aSubMicros == 0) { 70 bSubSecond -= bSubMicros; 71 } else if (bSubMicros == 0) { 72 aSubSecond -= aSubMicros; 73 } 74 } 75 } 76 return Integer.compare(aSubSecond, bSubSecond); 77 } 78 79 }