DateUtils.java

/*
 * Copyright © 2024-2025 The CTAN Team and individual authors
 *
 * This file is distributed under the 3-clause BSD license.
 * See file LICENSE for details.
 */
package org.ctan.site.services;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * The class <code>DateUtils</code> contains the utilities for dates.
 */
public final class DateUtils {

    /**
     * The field <code>LOCAL_DATE_TIME_FORMATTER</code> contains the formatter
     * for {@link LocalDateTime}.
     */
    public static final DateTimeFormatter LOCAL_DATE_TIME_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * The field <code>LOCAL_DATE_TIME_FORMATTER</code> contains the formatter
     * for {@link LocalDateTime}.
     */
    public static final DateTimeFormatter DATE_TIME_FORMATTER =
        DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss 'Z'");

    /**
     * The field <code>LOCAL_DATE_TIME_FORMATTER_RFC_3339</code> contains the
     * formatter for {@link LocalDateTime} according to RFC3339.
     */
    public static final DateTimeFormatter LOCAL_DATE_TIME_FORMATTER_RFC_3339 =
        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");

    /**
     * The field <code>LOCAL_DATE_FORMATTER</code> contains the formatter for
     * {@link LocalDateTime}.
     */
    public static final DateTimeFormatter LOCAL_DATE_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd");

    /**
     * The field <code>LOCAL_DATE_FORMATTER_YYYY_MM</code> contains the
     * formatter for {@link LocalDateTime} printing year and month.
     */
    public static final DateTimeFormatter LOCAL_DATE_FORMATTER_YYYY_MM =
        DateTimeFormatter.ofPattern("yyyy-MM");

    /**
     * The method <code>formatDate</code> provides means to format a date
     * according to contains the ISO date format without the time.
     *
     * @param date the date
     * @return the formatted date
     */
    public static String formatDate(Instant date) {

        return date == null
            ? null
            : date.toString().substring(0, 10);
    }

    /**
     * The method <code>formatDate</code> provides means to format a date
     * according to contains the ISO date format without the time.
     *
     * @param date the date
     * @return the formatted date
     */
    public static String formatDate(LocalDateTime date) {

        return date == null
            ? null
            : LOCAL_DATE_FORMATTER.format(date);
    }

    /**
     * The method <code>formatDateTime</code> provides means to format a date
     * according to contains the ISO date format including the time.
     *
     * @param date the date
     * @return the formatted date
     */
    public static String formatDateTime(Instant date) {

        return date == null
            ? null
            : date.toString().replace('T', ' ').substring(0, 10);
    }

    /**
     * The method <code>formatDateTime</code> provides means to format a date
     * according to contains the ISO date format including the time.
     *
     * @param date the date
     * @return the formatted date
     */
    public static String formatDateTime(LocalDateTime date) {

        return date == null
            ? null
            : LOCAL_DATE_TIME_FORMATTER.format(date);
    }

    /**
     * The method <code>formatDateTime</code> provides means to format a date
     * according to contains the ISO date format including the time.
     *
     * @param date the date
     * @return the formatted date
     */
    public static String formatDateTime(long date) {

        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
            .format(new Date(date));
    }

    /**
     * The method <code>formatFullDateTime</code> provides means to format a
     * date according to contains the full ISO date format including the time.
     *
     * @param instant the date
     * @return the formatted date
     */
    public static String formatFullDateTime(Instant instant) {

        return instant == null
            ? null
            : DATE_TIME_FORMATTER
                .format(LocalDateTime.ofInstant(instant, ZoneOffset.UTC));
    }

    /**
     * The method <code>formatRfc3339</code> provides means to format a date
     * according to contains the ISO date format including the time.
     *
     * @param date the date
     * @return the formatted date
     */
    public static String formatRfc3339(Instant date) {

        return date == null
            ? null
            : date.toString();
    }

    /**
     * This is the constructor for <code>DateUtils</code>.
     */
    private DateUtils() {

    }
}