001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.api.util;
015
016import java.time.OffsetDateTime;
017import java.time.temporal.ChronoUnit;
018
019/**
020 * Utility class for null-safe OffsetDateTime operations.
021 */
022public class OffsetDateTimeUtils {
023
024  private OffsetDateTimeUtils() {}
025
026  /**
027   * Compares two OffsetDateTime values in a null-safe manner.
028   * Null values are considered to be greater than non-null values (sorted to the end).
029   *
030   * @param dt1 first OffsetDateTime to compare
031   * @param dt2 second OffsetDateTime to compare
032   * @return a negative integer, zero, or a positive integer as the first argument
033   *         is less than, equal to, or greater than the second
034   */
035  public static int compareOffsetDateTime(OffsetDateTime dt1, OffsetDateTime dt2) {
036    if (dt1 == dt2) return 0;
037    if (dt1 == null) return 1;
038    if (dt2 == null) return -1;
039    return dt1.toInstant().truncatedTo(ChronoUnit.MICROS).compareTo(dt2.toInstant().truncatedTo(ChronoUnit.MICROS));
040  }
041
042  /**
043   * Checks if two OffsetDateTime values are equal in a null-safe manner.
044   *
045   * @param dt1 first OffsetDateTime to compare
046   * @param dt2 second OffsetDateTime to compare
047   * @return true if both are null or both are equal, false otherwise
048   */
049  public static boolean isEqualOffsetDateTime(OffsetDateTime dt1, OffsetDateTime dt2) {
050    if (dt1 == dt2) return true;
051    if (dt1 == null || dt2 == null) return false;
052    return dt1.toInstant().truncatedTo(ChronoUnit.MICROS).equals(dt2.toInstant().truncatedTo(ChronoUnit.MICROS));
053  }
054}
055