All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.landawn.abacus.util.Dates Maven / Gradle / Ivy

Go to download

A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.

The newest version!
/*
 * Copyright (C) 2018 HaiYang Li
 *
 * Licensed 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
 *
 * https://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 com.landawn.abacus.util;

import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.nio.CharBuffer;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.Queue;
import java.util.TimeZone;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.LongFunction;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.MayReturnNull;
import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.exception.UncheckedIOException;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;

/**
 * 

* Note: This class includes codes copied from Apache Commons Lang, Google Guava and other open source projects under the Apache License 2.0. * The methods copied from other libraries/frameworks/projects may be modified in this class. *

* @see DateTimeFormatter * @see ISO8601Util */ @SuppressWarnings({ "java:S1694", "java:S2143" }) public abstract sealed class Dates permits Dates.DateUtil { private static final Logger logger = LoggerFactory.getLogger(Dates.class); private static final String FAILED_TO_PARSE_TO_LONG = "Failed to parse: {} to Long"; // ... /** * Default {@code TimeZone} of the Java virtual machine */ public static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getDefault(); /** * UTC, or Coordinated Universal Time, is the time standard that the world uses to regulate clocks and time. * It does not change with the seasons (i.e., it doesn't observe Daylight Saving Time) and is the same everywhere. * It's often used as a reference point for time zones around the world. */ public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC"); /** * GMT, or Greenwich Mean Time, is a time zone used as a reference point for time keeping around the world. * It is located at the prime meridian (0 degrees longitude) and does not observe daylight-saving time. * GMT is often used in various contexts, including aviation, computing, and international communications. * In many regions, GMT is replaced by Coordinated Universal Time (UTC), which is similar but more precise. * When comparing other time zones, you can express them as offsets from GMT/UTC, such as GMT+2 or GMT-5 */ public static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT"); /** * Default {@code ZoneId} of the Java virtual machine */ public static final ZoneId DEFAULT_ZONE_ID = ZoneId.systemDefault(); /** * {@code ZionId} of UTC time zone. * @see #UTC_TIME_ZONE * @see TimeZone#toZoneId() */ public static final ZoneId UTC_ZONE_ID = UTC_TIME_ZONE.toZoneId(); /** * {@code ZionId} of GMT time zone. * @see #GMT_TIME_ZONE * @see TimeZone#toZoneId() */ public static final ZoneId GMT_ZONE_ID = GMT_TIME_ZONE.toZoneId(); /** * Date/Time format: {@code yyyy} */ public static final String LOCAL_YEAR_FORMAT = "yyyy"; /** * Date/Time format: {@code MM-dd} */ public static final String LOCAL_MONTH_DAY_FORMAT = "MM-dd"; // static final String LOCAL_MONTH_DAY_FORMAT_SLASH = "MM/dd"; /** * Date/Time format: {@code yyyy-MM-dd} */ public static final String LOCAL_DATE_FORMAT = "yyyy-MM-dd"; // static final String LOCAL_DATE_FORMAT_SLASH = "yyyy/MM/dd"; /** * Date/Time format: {@code HH:mm:ss} */ public static final String LOCAL_TIME_FORMAT = "HH:mm:ss"; /** * Date/Time format: {@code yyyy-MM-dd HH:mm:ss} */ public static final String LOCAL_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; // static final String LOCAL_DATE_TIME_FORMAT_SLASH = "yyyy/MM/dd HH:mm:ss"; // /** // * Date/Time format: {@code yyyy-MM-dd HH:mm:ss.SSS} // * @deprecated use {@link #ISO_8601_TIMESTAMP_FORMAT} // */ // @Deprecated // public static final String LOCAL_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; // static final String LOCAL_TIMESTAMP_FORMAT_SLASH = "yyyy/MM/dd HH:mm:ss.SSS"; /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ss} * @see {@link DateTimeFormatter#ISO_LOCAL_DATE_TIME} */ public static final String ISO_LOCAL_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ssXXX} * @see {@link DateTimeFormatter#ISO_OFFSET_DATE_TIME} */ public static final String ISO_OFFSET_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX"; /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ss'Z'}. * It's the default date/time format. */ public static final String ISO_8601_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; // static final String ISO_8601_DATE_TIME_FORMAT_SLASH = "yyyy/MM/dd'T'HH:mm:ss'Z'"; /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}. * * It's default timestamp format. */ public static final String ISO_8601_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; // static final String ISO_8601_TIMESTAMP_FORMAT_SLASH = "yyyy/MM/dd'T'HH:mm:ss.SSS'Z'"; /** * This constant defines the date format specified by * RFC 1123 / RFC 822. Used for parsing via SimpleDateFormat as well as * error messages. */ public static final String RFC_1123_DATE_TIME_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz"; /** * This is half a month, so this represents whether a date is in the top or bottom half of the month. * @see CalendarField */ public static final int SEMI_MONTH = 1001; private static final int[][] fields = { { Calendar.MILLISECOND }, { Calendar.SECOND }, { Calendar.MINUTE }, { Calendar.HOUR_OF_DAY, Calendar.HOUR }, { Calendar.DATE, Calendar.DAY_OF_MONTH, Calendar.AM_PM /* Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK, Calendar.DAY_OF_WEEK_IN_MONTH */ }, { Calendar.MONTH, SEMI_MONTH }, { Calendar.YEAR }, { Calendar.ERA } }; @SuppressWarnings("deprecation") private static final int POOL_SIZE = InternalUtil.POOL_SIZE; private static final Map> dfPool = new ObjectPool<>(64); private static final Map> calendarPool = new ObjectPool<>(64); private static final Queue utcTimestampDFPool = new ArrayBlockingQueue<>(POOL_SIZE); private static final Queue utcDateTimeDFPool = new ArrayBlockingQueue<>(POOL_SIZE); private static final Queue utcCalendarPool = new ArrayBlockingQueue<>(POOL_SIZE); // ... private static final Queue utcTimestampFormatCharsPool = new ArrayBlockingQueue<>(POOL_SIZE); private static final DatatypeFactory dataTypeFactory; static { DatatypeFactory temp = null; try { temp = DatatypeFactory.newInstance(); } catch (final Exception e) { // ignore. // logger.error("Failed to initialize XMLGregorianCalendarType: " + // e.getMessage(), e); } dataTypeFactory = temp; } // ... private static final char[][][] cbufOfSTDInt = new char[5][][]; static { for (int i = 0, j = 1; i < 5; i++, j = j * 10) { cbufOfSTDInt[i] = new char[j][]; for (int k = 0; k < j; k++) { if (i == 1) { cbufOfSTDInt[i][k] = String.valueOf(k).toCharArray(); } else if (i == 2) { if (k < 10) { cbufOfSTDInt[i][k] = ("0" + k).toCharArray(); } else { cbufOfSTDInt[i][k] = String.valueOf(k).toCharArray(); } } else if (i == 3) { if (k < 10) { cbufOfSTDInt[i][k] = ("00" + k).toCharArray(); } else if (k < 100) { cbufOfSTDInt[i][k] = ("0" + k).toCharArray(); } else { cbufOfSTDInt[i][k] = String.valueOf(k).toCharArray(); } } else if (i == 4) { if (k < 10) { cbufOfSTDInt[i][k] = ("000" + k).toCharArray(); } else if (k < 100) { cbufOfSTDInt[i][k] = ("00" + k).toCharArray(); } else if (k < 1000) { cbufOfSTDInt[i][k] = ("0" + k).toCharArray(); } else { cbufOfSTDInt[i][k] = String.valueOf(k).toCharArray(); } } } } } static final Map dtfPool = ImmutableMap. builder() .put("uuuu-MM-dd", DateTimeFormatter.ISO_LOCAL_DATE) .build(); static final Map, LongFunction> dateCreatorPool = new ConcurrentHashMap<>(); static { dateCreatorPool.put(java.util.Date.class, java.util.Date::new); dateCreatorPool.put(java.sql.Date.class, java.sql.Date::new); dateCreatorPool.put(Time.class, Time::new); dateCreatorPool.put(Timestamp.class, Timestamp::new); } static final Map, BiFunction> calendarCreatorPool = new ConcurrentHashMap<>(); static { calendarCreatorPool.put(java.util.Calendar.class, (millis, c) -> { final Calendar ret = Calendar.getInstance(); ret.setTimeInMillis(millis); if (N.equals(ret.getTimeZone(), c.getTimeZone()) && c.getTimeZone() != null) { ret.setTimeZone(c.getTimeZone()); } return ret; }); calendarCreatorPool.put(java.util.GregorianCalendar.class, (millis, c) -> { final Calendar ret = GregorianCalendar.getInstance(); ret.setTimeInMillis(millis); if (N.equals(ret.getTimeZone(), c.getTimeZone()) && c.getTimeZone() != null) { ret.setTimeZone(c.getTimeZone()); } return ret; }); } Dates() { // singleton } /** * Registers a custom date creator for a specific date class. * * @param the type of the date * @param dateClass the class of the date to register the creator for * @param dateCreator the function that creates instances of the date class. The function takes one argument: the time in milliseconds. * @return {@code true} if the date creator was successfully registered, {@code false} otherwise */ public static boolean registerDateCreator(final Class dateClass, final LongFunction dateCreator) { if (dateCreatorPool.containsKey(dateClass) && !Strings.startsWithAny(ClassUtil.getPackageName(dateClass), "java.", "javax.", "com.landawn.abacus")) { return false; } dateCreatorPool.put(dateClass, dateCreator); return true; } /** * Registers a custom calendar creator for a specific calendar class. * * @param the type of the calendar * @param calendarClass the class of the calendar to register the creator for * @param dateCreator the function that creates instances of the calendar class. The function takes two arguments: the time in milliseconds and the calendar to use as a template. * @return {@code true} if the calendar creator was successfully registered, {@code false} otherwise */ public static boolean registerCalendarCreator(final Class calendarClass, final BiFunction dateCreator) { if (calendarCreatorPool.containsKey(calendarClass) && !Strings.startsWithAny(ClassUtil.getPackageName(calendarClass), "java.", "javax.", "com.landawn.abacus")) { return false; } calendarCreatorPool.put(calendarClass, dateCreator); return true; } /** * Returns the current time in milliseconds. * * @return The current time in milliseconds since the epoch (01-01-1970). */ @Beta public static long currentTimeMillis() { return System.currentTimeMillis(); } /** * Returns a new instance of {@code java.sql.Time} based on the current time in the default time zone with the default locale. * * @return */ public static Time currentTime() { return new Time(System.currentTimeMillis()); } /** * Returns a new instance of {@code java.sql.Date} based on the current time in the default time zone with the default locale. * * @return */ public static Date currentDate() { return new Date(System.currentTimeMillis()); } /** * Returns a new instance of {@code java.sql.Timestamp} based on the current time in the default time zone with the default locale. * * @return */ public static Timestamp currentTimestamp() { return new Timestamp(System.currentTimeMillis()); } /** * Returns a new instance of {@code java.util.Date} based on the current time in the default time zone with the default locale. * * @return */ public static java.util.Date currentJUDate() { return new java.util.Date(); } /** * Returns a new instance of {@code java.util.Calendar} based on the current time in the default time zone with the default locale. * * @return a Calendar. */ public static Calendar currentCalendar() { return Calendar.getInstance(); } /** * Returns a new instance of {@code GregorianCalendar} based on the current time in the default time zone with the default locale. * * @return A new GregorianCalendar object representing the current date and time. */ public static GregorianCalendar currentGregorianCalendar() { return new GregorianCalendar(); } /** * Returns a new instance of {@code XMLGregorianCalendar} instance based on the current Gregorian Calendar. * * @return XMLGregorianCalendar instance representing the current date and time. */ public static XMLGregorianCalendar currentXMLGregorianCalendar() { return dataTypeFactory.newXMLGregorianCalendar(currentGregorianCalendar()); } /** * Adds or subtracts the specified amount of time with the given time unit to current {@code java.sql.Time} * * @param amount * @param unit * @return * @return a new {@code Time} by Adding or subtracting the specified amount of time to current {@code java.sql.Time}. */ @Beta static long currentTimeMillisRolled(final long amount, final TimeUnit unit) { return System.currentTimeMillis() + unit.toMillis(amount); } /** * Adds or subtracts the specified amount of time with the given time unit to current {@code java.sql.Time} * * @param amount * @param unit * @return a new {@code Time} by Adding or subtracting the specified amount of time to current {@code java.sql.Time}. */ @Beta public static Time currentTimeRolled(final long amount, final TimeUnit unit) { return new Time(currentTimeMillisRolled(amount, unit)); } /** * Adds or subtracts the specified amount of time with the given time unit to current {@code java.sql.Date} * * @param amount * @param unit * @return a new {@code Date} by Adding or subtracting the specified amount of time to current {@code java.sql.Date}. */ @Beta public static Date currentDateRolled(final long amount, final TimeUnit unit) { return new Date(currentTimeMillisRolled(amount, unit)); } /** * Adds or subtracts the specified amount of time with the given time unit to current {@code java.sql.Timestamp} * * @param amount * @param unit * @return a new {@code Timestamp} by Adding or subtracting the specified amount of time to current {@code java.sql.Timestamp}. */ @Beta public static Timestamp currentTimestampRolled(final long amount, final TimeUnit unit) { return new Timestamp(currentTimeMillisRolled(amount, unit)); } /** * Adds or subtracts the specified amount of time with the given time unit to current {@code java.util.Date} * * * @param amount * @param unit * @return a new {@code Date} by Adding or subtracting the specified amount of time to current {@code java.util.Date}. */ @Beta public static java.util.Date currentJUDateRolled(final long amount, final TimeUnit unit) { return new java.util.Date(currentTimeMillisRolled(amount, unit)); } /** * Adds or subtracts the specified amount of time with the given time unit to current {@code java.util.Calendar}. * * * @param amount * @param unit * @return a new {@code Calendar} by Adding or subtracting the specified amount of time to current {@code java.util.Calendar}. */ @Beta public static Calendar currentCalendarRolled(final long amount, final TimeUnit unit) { final Calendar ret = Calendar.getInstance(); ret.setTimeInMillis(currentTimeMillisRolled(amount, unit)); return ret; } /** * Creates a new instance of {@code java.util.Date} based on the time value represented by the {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the Date object. * @return A new Date object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static java.util.Date createJUDate(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createJUDate(calendar.getTimeInMillis()); } /** * Creates a new instance of {@code java.util.Date} based on the time value represented by the Date object. * * @param date The Date object used to create the new Date object. * @return A new Date object representing the same point in time as the provided Date object. * @throws IllegalArgumentException if the provided date object is {@code null}. */ public static java.util.Date createJUDate(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createJUDate(date.getTime()); } /** * Creates a new instance of {@code java.util.Date} based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new Date object representing the same point in time as the provided time in milliseconds. */ public static java.util.Date createJUDate(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } return new java.util.Date(timeInMillis); } /** * Creates a new instance of {@code java.sql.Date} based on the time value represented by the {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the Date object. * @return A new Date object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static Date createDate(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createDate(calendar.getTimeInMillis()); } /** * Creates a new instance of {@code java.sql.Date} based on the time value represented by the {@code java.util.Date} object. * * @param date The {@code java.util.Date} object used to create the new java.sql.Date object. * @return A new java.sql.Date object representing the same point in time as the provided {@code java.util.Date} object. * @throws IllegalArgumentException if the provided {@code java.util.Date} object is {@code null}. */ public static Date createDate(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createDate(date.getTime()); } /** * Creates a new instance of {@code java.sql.Date} based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new Date object representing the same point in time as the provided time in milliseconds. */ public static Date createDate(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } return new Date(timeInMillis); } /** * Creates a new instance of java.sql.Time based on the time value represented by the {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the Time object. * @return A new Time object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static Time createTime(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createTime(calendar.getTimeInMillis()); } /** * Creates a new instance of java.sql.Time based on the time value represented by the {@code java.util.Date} object. * * @param date The {@code java.util.Date} object used to create the new java.sql.Time object. * @return A new java.sql.Time object representing the same point in time as the provided {@code java.util.Date} object. * @throws IllegalArgumentException if the provided {@code java.util.Date} object is {@code null}. */ public static Time createTime(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createTime(date.getTime()); } /** * Creates a new instance of java.sql.Time based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new Time object representing the same point in time as the provided time in milliseconds. */ public static Time createTime(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } return new Time(timeInMillis); } /** * Creates a new instance of java.sql.Timestamp based on the time value represented by the {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the Timestamp object. * @return A new Timestamp object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static Timestamp createTimestamp(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createTimestamp(calendar.getTimeInMillis()); } /** * Creates a new instance of java.sql.Timestamp based on the time value represented by the {@code java.util.Date} object. * * @param date The {@code java.util.Date} object used to create the new java.sql.Timestamp object. * @return A new java.sql.Timestamp object representing the same point in time as the provided {@code java.util.Date} object. * @throws IllegalArgumentException if the provided {@code java.util.Date} object is {@code null}. */ public static Timestamp createTimestamp(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createTimestamp(date.getTime()); } /** * Creates a new instance of java.sql.Timestamp based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new Timestamp object representing the same point in time as the provided time in milliseconds. */ public static Timestamp createTimestamp(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } return new Timestamp(timeInMillis); } /** * Creates a new instance of {@code java.util.Calendar} based on the time value represented by the provided {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the new {@code Calendar} object. * @return A new {@code Calendar} object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static Calendar createCalendar(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createCalendar(calendar.getTimeInMillis()); } /** * Creates a new instance of {@code java.util.Calendar} based on the time value represented by the {@code java.util.Date} object. * * @param date The {@code java.util.Date} object used to create the new java.util.Calendar object. * @return A new java.util.Calendar object representing the same point in time as the provided {@code java.util.Date} object. * @throws IllegalArgumentException if the provided {@code java.util.Date} object is {@code null}. */ public static Calendar createCalendar(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createCalendar(date.getTime()); } /** * Creates a new instance of {@code java.util.Calendar} based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new java.util.Calendar object representing the same point in time as the provided time in milliseconds. */ public static Calendar createCalendar(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } final Calendar c = Calendar.getInstance(); c.setTimeInMillis(timeInMillis); return c; } /** * Creates a new instance of {@code java.util.Calendar} based on the provided time in milliseconds and the specified TimeZone. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @param tz The TimeZone to be used for the new {@code Calendar} object. * @return A new java.util.Calendar object representing the same point in time as the provided time in milliseconds, using the specified TimeZone. * @throws IllegalArgumentException if the provided TimeZone object is {@code null}. */ public static Calendar createCalendar(final long timeInMillis, final TimeZone tz) throws IllegalArgumentException { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } final Calendar c = tz == null ? Calendar.getInstance() : Calendar.getInstance(tz); c.setTimeInMillis(timeInMillis); return c; } /** * Creates a new instance of {@code java.util.GregorianCalendar} based on the time value represented by the provided {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the new GregorianCalendar object. * @return A new GregorianCalendar object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static GregorianCalendar createGregorianCalendar(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createGregorianCalendar(calendar.getTimeInMillis()); } /** * Creates a new instance of {@code java.util.GregorianCalendar} based on the time value represented by the provided {@code java.util.Date} object. * * @param date The {@code java.util.Date} object used to create the new GregorianCalendar object. * @return A new GregorianCalendar object representing the same point in time as the provided {@code java.util.Date} object. * @throws IllegalArgumentException if the provided {@code java.util.Date} object is {@code null}. */ public static GregorianCalendar createGregorianCalendar(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createGregorianCalendar(date.getTime()); } /** * Creates a new instance of {@code java.util.GregorianCalendar} based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new java.util.GregorianCalendar object representing the same point in time as the provided time in milliseconds. */ public static GregorianCalendar createGregorianCalendar(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } final GregorianCalendar c = new GregorianCalendar(); c.setTimeInMillis(timeInMillis); return c; } /** * Creates a new instance of {@code java.util.GregorianCalendar} based on the provided time in milliseconds and the specified TimeZone. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @param tz The TimeZone to be used for the new GregorianCalendar object. * @return A new java.util.GregorianCalendar object representing the same point in time as the provided time in milliseconds, using the specified TimeZone. */ public static GregorianCalendar createGregorianCalendar(final long timeInMillis, final TimeZone tz) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } final GregorianCalendar c = tz == null ? new GregorianCalendar() : new GregorianCalendar(tz); c.setTimeInMillis(timeInMillis); return c; } /** * Creates a new instance of {@code XMLGregorianCalendar} based on the time value represented by the provided {@code Calendar} object. * * @param calendar The {@code Calendar} object used to create the XMLGregorianCalendar object. * @return A new XMLGregorianCalendar object representing the same point in time as the provided {@code Calendar} object. * @throws IllegalArgumentException if the provided {@code Calendar} object is {@code null}. */ public static XMLGregorianCalendar createXMLGregorianCalendar(final Calendar calendar) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); return createXMLGregorianCalendar(calendar.getTimeInMillis()); } /** * Creates a new instance of {@code XMLGregorianCalendar} based on the time value represented by the provided {@code java.util.Date} object. * * @param date The {@code java.util.Date} object used to create the new XMLGregorianCalendar object. * @return A new XMLGregorianCalendar object representing the same point in time as the provided {@code java.util.Date} object. * @throws IllegalArgumentException if the provided {@code java.util.Date} object is {@code null}. */ public static XMLGregorianCalendar createXMLGregorianCalendar(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createXMLGregorianCalendar(date.getTime()); } /** * Creates a new instance of {@code XMLGregorianCalendar} based on the provided time in milliseconds. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @return A new XMLGregorianCalendar object representing the same point in time as the provided time in milliseconds. */ public static XMLGregorianCalendar createXMLGregorianCalendar(final long timeInMillis) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } return dataTypeFactory.newXMLGregorianCalendar(createGregorianCalendar(timeInMillis)); } /** * Creates a new instance of {@code XMLGregorianCalendar} based on the provided time in milliseconds and the specified TimeZone. * * @param timeInMillis The time in milliseconds since the epoch (01-01-1970). * @param tz The TimeZone to be used for the new XMLGregorianCalendar object. * @return A new XMLGregorianCalendar object representing the same point in time as the provided time in milliseconds, using the specified TimeZone. */ public static XMLGregorianCalendar createXMLGregorianCalendar(final long timeInMillis, final TimeZone tz) { // N.checkArgPositive(timeInMillis, "timeInMillis"); // // if (timeInMillis == 0) { // return null; // } return dataTypeFactory.newXMLGregorianCalendar(createGregorianCalendar(timeInMillis, tz)); } /** * Parses a string representation of a date into a {@code java.util.Date} object. * * @param date The string representation of the date to be parsed. * @return The parsed {@code java.util.Date} object or {@code null} if the provided date string is {@code null} or empty or "null". */ public static java.util.Date parseJUDate(final String date) { return parseJUDate(date, null); } /** * Parses a string representation of a date into a {@code java.util.Date} object. * * @param date The string representation of the date to be parsed. * @param format The format of the date string. If {@code null}, the method will try to parse the date using common date formats. * @return The parsed {@code java.util.Date} object or {@code null} if the provided date string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided date string cannot be parsed. */ public static java.util.Date parseJUDate(final String date, final String format) { return parseJUDate(date, format, null); } /** * Parses a string representation of a date into a {@code java.util.Date} object. * * @param date The string representation of the date to be parsed. * @param format The format of the date string. If {@code null}, the method will try to parse the date using common date formats. * @param timeZone The TimeZone to be used for parsing the date string. If {@code null}, the method will use the default TimeZone. * @return The parsed {@code java.util.Date} object or {@code null} if the provided date string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided date string cannot be parsed. */ @MayReturnNull public static java.util.Date parseJUDate(final String date, final String format, final TimeZone timeZone) { if (isNullDateTime(date)) { return null; } // return createJUDate(parse(date, format, timeZone)); if ((format == null) && isPossibleLong(date)) { try { return createJUDate(Long.parseLong(date)); } catch (final NumberFormatException e) { // ignore. if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, date); } } } final String formatToUse = checkDateFormat(date, format); // use ISO8601Util.parse for better performance. if (Strings.isEmpty(formatToUse) || ISO_8601_DATE_TIME_FORMAT.equals(formatToUse) || ISO_8601_TIMESTAMP_FORMAT.equals(formatToUse)) { if (timeZone == null || timeZone.equals(ISO8601Util.TIMEZONE_Z)) { return ISO8601Util.parse(date); } else { throw new RuntimeException("Unsupported date format: " + formatToUse + " with time zone: " + timeZone); } } final TimeZone timeZoneToUse = checkTimeZone(date, formatToUse, timeZone); final long timeInMillis = fastDateParse(date, formatToUse, timeZoneToUse); if (timeInMillis != 0) { return createJUDate(timeInMillis); } final DateFormat sdf = getSDF(formatToUse, timeZoneToUse); try { return sdf.parse(date); } catch (final ParseException e) { throw new IllegalArgumentException(e); } finally { recycleSDF(formatToUse, timeZoneToUse, sdf); } } /** * Parses a string representation of a date into a java.sql.Date object. * * @param date The string representation of the date to be parsed. * @return The parsed java.sql.Date object or {@code null} if the provided date string is {@code null} or empty or "null". */ public static Date parseDate(final String date) { return parseDate(date, null); } /** * Parses a string representation of a date into a java.sql.Date object. * * @param date The string representation of the date to be parsed. * @param format The format of the date string. If {@code null}, the method will try to parse the date using common date formats. * @return The parsed java.sql.Date object or {@code null} if the provided date string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided date string cannot be parsed. */ public static Date parseDate(final String date, final String format) { return parseDate(date, format, null); } /** * Parses a string representation of a date into a java.sql.Date object. * * @param date The string representation of the date to be parsed. * @param format The format of the date string. If {@code null}, the method will try to parse the date using common date formats. * @param timeZone The TimeZone to be used for parsing the date string. If {@code null}, the method will use the default TimeZone. * @return The parsed java.sql.Date object or {@code null} if the provided date string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided date string cannot be parsed. */ @MayReturnNull public static Date parseDate(final String date, final String format, final TimeZone timeZone) { if (isNullDateTime(date)) { return null; } return createDate(parse(date, format, timeZone)); } /** * Parses a string representation of a time into a java.sql.Time object. * * @param date The string representation of the time to be parsed. * @return The parsed java.sql.Time object or {@code null} if the provided date string is {@code null} or empty or "null". */ public static Time parseTime(final String date) { return parseTime(date, null); } /** * Parses a string representation of a time into a java.sql.Time object. * * @param date The string representation of the time to be parsed. * @param format The format of the time string. If {@code null}, the method will try to parse the time using common time formats. * @return The parsed java.sql.Time object or {@code null} if the provided date string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided time string cannot be parsed. */ public static Time parseTime(final String date, final String format) { return parseTime(date, format, null); } /** * Parses a string representation of a time into a java.sql.Time object. * * @param date The string representation of the time to be parsed. * @param format The format of the time string. If {@code null}, the method will try to parse the time using common time formats. * @param timeZone The TimeZone to be used for parsing the time string. If {@code null}, the method will use the default TimeZone. * @return The parsed java.sql.Time object or {@code null} if the provided date string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided time string cannot be parsed. */ @MayReturnNull public static Time parseTime(final String date, final String format, final TimeZone timeZone) { if (isNullDateTime(date)) { return null; } return createTime(parse(date, format, timeZone)); } /** * Parses a string representation of a timestamp into a java.sql.Timestamp object. * * @param date The string representation of the timestamp to be parsed. * @return The parsed java.sql.Timestamp object or {@code null} if the provided timestamp string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided timestamp string cannot be parsed. */ public static Timestamp parseTimestamp(final String date) { return parseTimestamp(date, null); } /** * Parses a string representation of a timestamp into a java.sql.Timestamp object. * * @param date The string representation of the timestamp to be parsed. * @param format The format of the timestamp string. If {@code null}, the method will try to parse the timestamp using common timestamp formats. * @return The parsed java.sql.Timestamp object or {@code null} if the provided timestamp string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided timestamp string cannot be parsed. */ public static Timestamp parseTimestamp(final String date, final String format) { return parseTimestamp(date, format, null); } /** * Parses a string representation of a timestamp into a java.sql.Timestamp object. * * @param date The string representation of the timestamp to be parsed. * @param format The format of the timestamp string. If {@code null}, the method will try to parse the timestamp using common timestamp formats. * @param timeZone The TimeZone to be used for parsing the timestamp string. If {@code null}, the method will use the default TimeZone. * @return The parsed java.sql.Timestamp object or {@code null} if the provided timestamp string is {@code null} or empty or "null". * @throws IllegalArgumentException if the provided timestamp string cannot be parsed. */ @MayReturnNull public static Timestamp parseTimestamp(final String date, final String format, final TimeZone timeZone) { if (isNullDateTime(date)) { return null; } return createTimestamp(parse(date, format, timeZone)); } /** * Parses a string representation of a calendar into a java.util.Calendar object. * * @param calendar The string representation of the calendar to be parsed. * @return The parsed java.util.Calendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @Beta public static Calendar parseCalendar(final String calendar) { return parseCalendar(calendar, null); } /** * Parses a string representation of a calendar into a java.util.Calendar object. * * @param calendar The string representation of the calendar to be parsed. * @param format The format of the calendar string. If {@code null}, the method will try to parse the calendar using common calendar formats. * @return The parsed java.util.Calendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @Beta public static Calendar parseCalendar(final String calendar, final String format) { return parseCalendar(calendar, format, null); } /** * Parses a string representation of a calendar into a java.util.Calendar object. * * @param calendar The string representation of the calendar to be parsed. * @param format The format of the calendar string. If {@code null}, the method will try to parse the calendar using common calendar formats. * @param timeZone The TimeZone to be used for parsing the calendar string. If {@code null}, the method will use the default TimeZone. * @return The parsed java.util.Calendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @MayReturnNull @Beta public static Calendar parseCalendar(final String calendar, final String format, final TimeZone timeZone) { if (isNullDateTime(calendar)) { return null; } return createCalendar(parse(calendar, format, timeZone), timeZone); } /** * Parses a string representation of a Gregorian calendar into a java.util.GregorianCalendar object. * * @param calendar The string representation of the Gregorian calendar to be parsed. * @return The parsed java.util.GregorianCalendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @Beta public static GregorianCalendar parseGregorianCalendar(final String calendar) { return parseGregorianCalendar(calendar, null); } /** * Parses a string representation of a Gregorian calendar into a java.util.GregorianCalendar object. * * @param calendar The string representation of the Gregorian calendar to be parsed. * @param format The format of the calendar string. If {@code null}, the method will try to parse the calendar using common calendar formats. * @return The parsed java.util.GregorianCalendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @Beta public static GregorianCalendar parseGregorianCalendar(final String calendar, final String format) { return parseGregorianCalendar(calendar, format, null); } /** * Parses a string representation of a Gregorian calendar into a java.util.GregorianCalendar object. * * @param calendar The string representation of the Gregorian calendar to be parsed. * @param format The format of the calendar string. If {@code null}, the method will try to parse the calendar using common calendar formats. * @param timeZone The TimeZone to be used for parsing the calendar string. If {@code null}, the method will use the default TimeZone. * @return The parsed java.util.GregorianCalendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @MayReturnNull @Beta public static GregorianCalendar parseGregorianCalendar(final String calendar, final String format, final TimeZone timeZone) { if (isNullDateTime(calendar)) { return null; } return createGregorianCalendar(parse(calendar, format, timeZone), timeZone); } /** * Parses a string representation of an XML Gregorian calendar into a javax.xml.datatype.XMLGregorianCalendar object. * * @param calendar The string representation of the XML Gregorian calendar to be parsed. * @return The parsed javax.xml.datatype.XMLGregorianCalendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @Beta public static XMLGregorianCalendar parseXMLGregorianCalendar(final String calendar) { return parseXMLGregorianCalendar(calendar, null); } /** * Parses a string representation of an XML Gregorian calendar into a javax.xml.datatype.XMLGregorianCalendar object. * * @param calendar The string representation of the XML Gregorian calendar to be parsed. * @param format The format of the calendar string. If {@code null}, the method will try to parse the calendar using common calendar formats. * @return The parsed javax.xml.datatype.XMLGregorianCalendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @Beta public static XMLGregorianCalendar parseXMLGregorianCalendar(final String calendar, final String format) { return parseXMLGregorianCalendar(calendar, format, null); } /** * Parses a string representation of an XML Gregorian calendar into a javax.xml.datatype.XMLGregorianCalendar object. * * @param calendar The string representation of the XML Gregorian calendar to be parsed. * @param format The format of the calendar string. If {@code null}, the method will try to parse the calendar using common calendar formats. * @param timeZone The TimeZone to be used for parsing the calendar string. If {@code null}, the method will use the default TimeZone. * @return The parsed javax.xml.datatype.XMLGregorianCalendar object or {@code null} if the provided calendar string is {@code null} or empty or "null". */ @MayReturnNull @Beta public static XMLGregorianCalendar parseXMLGregorianCalendar(final String calendar, final String format, final TimeZone timeZone) { if (isNullDateTime(calendar)) { return null; } return createXMLGregorianCalendar(parse(calendar, format, timeZone), timeZone); } private static boolean isNullDateTime(final String date) { return Strings.isEmpty(date) || (date.length() == 4 && "null".equalsIgnoreCase(date)); } private static boolean isPossibleLong(final CharSequence dateTime) { if (dateTime.length() > 4) { char ch = dateTime.charAt(2); if (ch >= '0' && ch <= '9') { ch = dateTime.charAt(4); return ch >= '0' && ch <= '9'; } } return false; } private static long parse(final String dateTime, final String format, final TimeZone timezone) { if ((format == null) && isPossibleLong(dateTime)) { try { return Long.parseLong(dateTime); } catch (final NumberFormatException e) { // ignore. if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, dateTime); } } } final String formatToUse = checkDateFormat(dateTime, format); // use ISO8601Util.parse for better performance. if (Strings.isEmpty(formatToUse) || ISO_8601_DATE_TIME_FORMAT.equals(formatToUse) || ISO_8601_TIMESTAMP_FORMAT.equals(formatToUse)) { if (timezone == null || timezone.equals(ISO8601Util.TIMEZONE_Z)) { return ISO8601Util.parse(dateTime).getTime(); } else { throw new RuntimeException("Unsupported date format: " + formatToUse + " with time zone: " + timezone); } } final TimeZone timeZoneToUse = checkTimeZone(dateTime, formatToUse, timezone); final long timeInMillis = fastDateParse(dateTime, formatToUse, timeZoneToUse); if (timeInMillis != 0) { return timeInMillis; } final DateFormat sdf = getSDF(formatToUse, timeZoneToUse); try { return sdf.parse(dateTime).getTime(); } catch (final ParseException e) { throw new IllegalArgumentException(e); } finally { recycleSDF(formatToUse, timeZoneToUse, sdf); } } // /** // * Parses the ZonedDateTime. // * // * @param dateTime // * @return // */ // public static ZonedDateTime parseZonedDateTime(final String dateTime) { // return parseZonedDateTime(dateTime, null); // } // // /** // * Parses the ZonedDateTime. // * // * @param dateTime // * @param format // * @return // */ // public static ZonedDateTime parseZonedDateTime(final String dateTime, final String format) { // return parseZonedDateTime(dateTime, format, null); // } // // /** // * Converts the specified date with the specified {@code format} to a new instance of ZonedDateTime. // * null is returned if the specified date is null or empty. // * // * @param dateTime // * @param format // * @param timeZone // * @return // */ // public static ZonedDateTime parseZonedDateTime(final String dateTime, String format, TimeZone timeZone) { // if (N.isEmpty(dateTime) || (dateTime.length() == 4 && "null".equalsIgnoreCase(dateTime))) { // return null; // } // // if ((format == null) && dateTime.length() > 4 && (dateTime.charAt(2) >= '0' && dateTime.charAt(2) <= '9' && dateTime.charAt(4) >= '0' && dateTime.charAt(4) <= '9') // && Strings.isAsciiDigitalInteger(dateTime)) { // // if (timeZone == null) { // timeZone = LOCAL_TIME_ZONE; // } // // return Instant.ofEpochMilli(Numbers.toLong(dateTime)).atZone(timeZone.toZoneId()); // } // // format = checkDateFormat(dateTime, format); // // if (N.isEmpty(format)) { // if (dateTime.charAt(dateTime.length() - 1) == ']' && dateTime.lastIndexOf('[') > 0) { // ZonedDateTime ret = ZonedDateTime.parse(dateTime); // // if (!(timeZone == null || timeZone.toZoneId().equals(ret.getZone()))) { // ret = ret.withZoneSameInstant(timeZone.toZoneId()); // } // // return ret; // } else { // if (timeZone == null) { // timeZone = LOCAL_TIME_ZONE; // } // // return ISO8601Util.parse(dateTime).toInstant().atZone(timeZone.toZoneId()); // } // } // // timeZone = checkTimeZone(format, timeZone); // // final DateTimeFormatter dtf = getDateTimeFormatter(format, timeZone.toZoneId()); // // return ZonedDateTime.parse(dateTime, dtf); // } // // private static final Map> dateTimeFormatterMap = new ConcurrentHashMap<>(); // // private static DateTimeFormatter getDateTimeFormatter(final String format, final ZoneId zoneId) { // DateTimeFormatter dtf = null; // Map tzdftMap = dateTimeFormatterMap.get(format); // // if (tzdftMap == null) { // tzdftMap = new ConcurrentHashMap<>(); // dateTimeFormatterMap.put(format, tzdftMap); // } else { // dtf = tzdftMap.get(zoneId); // } // // if (dtf == null) { // dtf = DateTimeFormatter.ofPattern(format).withZone(zoneId); // tzdftMap.put(zoneId, dtf); // } // // return dtf; // } /** * Formats current LocalDate with format {@code yyyy-MM-dd}. * * @return A string representation of the current LocalDate. */ @Beta public static String formatLocalDate() { return format(currentDate(), LOCAL_DATE_FORMAT); } /** * Formats current LocalDateTime with format with specified {@code yyyy-MM-dd HH:mm:ss}. * * @return A string representation of the current LocalDateTime. */ @Beta public static String formatLocalDateTime() { return format(currentDate(), LOCAL_DATE_TIME_FORMAT); } /** * Formats current DateTime with format with specified {@code yyyy-MM-dd'T'HH:mm:ss'Z'}. * * @return A string representation of the current DateTime. */ public static String formatCurrentDateTime() { return format(currentDate(), ISO_8601_DATE_TIME_FORMAT); } /** * Formats current Timestamp with format with specified {@code yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}. * * @return A string representation of the current Timestamp. */ public static String formatCurrentTimestamp() { return format(currentTimestamp(), ISO_8601_TIMESTAMP_FORMAT); } /** * Formats specified {@code date} with format {@code yyyy-MM-dd'T'HH:mm:ss.SSS'Z'} if it's a {@code Timestamp}, otherwise format it with format {@code yyyy-MM-dd'T'HH:mm:ss'Z'}. * * @param date The java.util.Date instance to be formatted. * @return A string representation of the specified date. */ public static String format(final java.util.Date date) { return format(date, null, null); } /** * Formats the provided java.util.Date instance into a string representation according to the provided format. * If no format is provided, a default format is used. * * @param date The java.util.Date instance to be formatted. * @param format The format to be used for formatting the java.util.Date instance. If {@code null}, a default format is used. * @return A string representation of the java.util.Date instance. */ public static String format(final java.util.Date date, final String format) { return format(date, format, null); } /** * Formats the provided java.util.Date instance into a string representation according to the provided format and timezone. * If no format is provided, a default format is used. * If no timezone is provided, the default timezone of the system is used. * * @param date The java.util.Date instance to be formatted. * @param format The format to be used for formatting the java.util.Date instance. If {@code null}, a default format is used. * @param timeZone The timezone to be used for formatting the java.util.Date instance. If {@code null}, the system's default timezone is used. * @return A string representation of the java.util.Date instance. */ public static String format(final java.util.Date date, final String format, final TimeZone timeZone) { return formatDate(null, date, format, timeZone); } /** * Formats specified {@code calendar} with format {@code yyyy-MM-dd'T'HH:mm:ss'Z'}. * * @param calendar The Calendar instance to be formatted. * @return A string representation of the Calendar instance. */ public static String format(final Calendar calendar) { return format(calendar, null, null); } /** * Formats the provided Calendar instance into a string representation according to the provided format. * If no format is provided, a default format is used. * * @param calendar The Calendar instance to be formatted. * @param format The format to be used for formatting the Calendar instance. If {@code null}, a default format is used. * @return A string representation of the Calendar instance. */ public static String format(final Calendar calendar, final String format) { return format(calendar, format, null); } /** * Formats the provided Calendar instance into a string representation according to the provided format and timezone. * If no format is provided, a default format is used. * If no timezone is provided, the default timezone of the system is used. * * @param calendar The Calendar instance to be formatted. * @param format The format to be used for formatting the Calendar instance. If {@code null}, a default format is used. * @param timeZone The timezone to be used for formatting the Calendar instance. If {@code null}, the system's default timezone is used. * @return A string representation of the Calendar instance. */ public static String format(final Calendar calendar, final String format, final TimeZone timeZone) { if ((format == null) && (timeZone == null)) { final StringBuilder sb = Objectory.createStringBuilder(); fastDateFormat(sb, null, calendar.getTimeInMillis(), false); final String str = sb.toString(); Objectory.recycle(sb); return str; } return format(createJUDate(calendar), format, timeZone); } /** * Formats specified {@code XMLGregorianCalendar} with format {@code yyyy-MM-dd'T'HH:mm:ss'Z'}. * * @param calendar The XMLGregorianCalendar instance to be formatted. * @return A string representation of the XMLGregorianCalendar instance. * @see #format(Calendar) */ public static String format(final XMLGregorianCalendar calendar) { return format(calendar, null, null); } /** * Formats the provided XMLGregorianCalendar instance into a string representation according to the provided format. * If no format is provided, a default format is used. * * @param calendar The XMLGregorianCalendar instance to be formatted. * @param format The format to be used for formatting the XMLGregorianCalendar instance. * @return A string representation of the XMLGregorianCalendar instance. * @see #format(Calendar, String) */ public static String format(final XMLGregorianCalendar calendar, final String format) { return format(calendar, format, null); } /** * Formats the provided XMLGregorianCalendar instance into a string representation according to the provided format and timezone. * If no format is provided, a default format is used. * If no timezone is provided, the default timezone of the system is used. * * @param calendar The XMLGregorianCalendar instance to be formatted. * @param format The format to be used for formatting the XMLGregorianCalendar instance. * @param timeZone The timezone to be used for formatting the XMLGregorianCalendar instance. * @return A string representation of the XMLGregorianCalendar instance. * @see #format(Calendar, String, TimeZone) */ public static String format(final XMLGregorianCalendar calendar, final String format, final TimeZone timeZone) { if ((format == null) && (timeZone == null)) { final StringBuilder sb = Objectory.createStringBuilder(); fastDateFormat(sb, null, calendar.toGregorianCalendar().getTimeInMillis(), false); final String str = sb.toString(); Objectory.recycle(sb); return str; } return format(createJUDate(calendar.toGregorianCalendar()), format, timeZone); } /** * Formats the provided java.util.Date instance into a string representation and appends it to the provided Appendable. * @param date The java.util.Date instance to be formatted. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(java.util.Date) */ public static void formatTo(final java.util.Date date, final Appendable appendable) { formatTo(date, null, null, appendable); } /** * Formats the provided java.util.Date instance into a string representation according to the provided format. * The string representation is appended to the provided Appendable instance. * @param date The java.util.Date instance to be formatted. * @param format The format to be used for formatting the java.util.Date instance. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(java.util.Date, String) */ public static void formatTo(final java.util.Date date, final String format, final Appendable appendable) { formatTo(date, format, null, appendable); } /** * Formats the provided java.util.Date instance into a string representation according to the provided format and timezone. * @param date The java.util.Date instance to be formatted. * @param format The format to be used for formatting the java.util.Date instance. * @param timeZone The timezone to be used for formatting the java.util.Date instance. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(java.util.Date, String, TimeZone) */ public static void formatTo(final java.util.Date date, final String format, final TimeZone timeZone, final Appendable appendable) { if (date == null) { formatToForNull(appendable); } formatDate(appendable, date, format, timeZone); } /** * Formats the provided java.util.Calendar instance into a string representation and appends it to the provided Appendable. * @param calendar The java.util.Calendar instance to be formatted. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(java.util.Calendar) */ public static void formatTo(final Calendar calendar, final Appendable appendable) { formatTo(calendar, null, null, appendable); } /** * Formats the provided java.util.Calendar instance into a string representation according to the provided format. * @param calendar The java.util.Calendar instance to be formatted. * @param format The format to be used for formatting the java.util.Calendar instance. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(java.util.Calendar, String) */ public static void formatTo(final Calendar calendar, final String format, final Appendable appendable) { formatTo(calendar, format, null, appendable); } /** * Formats the provided java.util.Calendar instance into a string representation according to the provided format and timezone. * The string representation is appended to the provided Appendable instance. * @param calendar The java.util.Calendar instance to be formatted. * @param format The format to be used for formatting the java.util.Calendar instance. * @param timeZone The timezone to be used for formatting the java.util.Calendar instance. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(java.util.Calendar, String, TimeZone) */ public static void formatTo(final Calendar calendar, final String format, final TimeZone timeZone, final Appendable appendable) { if (calendar == null) { formatToForNull(appendable); return; } if ((format == null) && (timeZone == null)) { fastDateFormat(null, appendable, calendar.getTimeInMillis(), false); } else { formatTo(createJUDate(calendar), format, timeZone, appendable); } } /** * Formats the provided XMLGregorianCalendar instance into a string representation and appends it to the provided Appendable. * The default format is used for formatting the XMLGregorianCalendar instance. * @param calendar The XMLGregorianCalendar instance to be formatted. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(XMLGregorianCalendar) */ public static void formatTo(final XMLGregorianCalendar calendar, final Appendable appendable) { formatTo(calendar, null, null, appendable); } /** * Formats the provided XMLGregorianCalendar instance into a string representation according to the provided format. * @param calendar The XMLGregorianCalendar instance to be formatted. * @param format The format to be used for formatting the XMLGregorianCalendar instance. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(XMLGregorianCalendar, String) */ public static void formatTo(final XMLGregorianCalendar calendar, final String format, final Appendable appendable) { formatTo(calendar, format, null, appendable); } /** * Formats the provided XMLGregorianCalendar instance into a string representation according to the provided format and timezone. * @param calendar The XMLGregorianCalendar instance to be formatted. * @param format The format to be used for formatting the XMLGregorianCalendar instance. * @param timeZone The timezone to be used for formatting the XMLGregorianCalendar instance. * @param appendable The Appendable to which the formatted date string is to be appended. * * @see #format(XMLGregorianCalendar, String, TimeZone) */ public static void formatTo(final XMLGregorianCalendar calendar, final String format, final TimeZone timeZone, final Appendable appendable) { if (calendar == null) { formatToForNull(appendable); return; } if ((format == null) && (timeZone == null)) { fastDateFormat(null, appendable, calendar.toGregorianCalendar().getTimeInMillis(), false); } else { formatTo(createJUDate(calendar.toGregorianCalendar()), format, timeZone, appendable); } } private static String formatDate(final Appendable appendable, final java.util.Date date, String format, TimeZone timeZone) { final boolean isTimestamp = date instanceof Timestamp; if ((format == null) && (timeZone == null)) { if (appendable == null) { final StringBuilder sb = Objectory.createStringBuilder(); fastDateFormat(sb, null, date.getTime(), isTimestamp); final String str = sb.toString(); Objectory.recycle(sb); return str; } else { fastDateFormat(null, appendable, date.getTime(), isTimestamp); return null; } } if (format == null) { format = isTimestamp ? ISO_8601_TIMESTAMP_FORMAT : ISO_8601_DATE_TIME_FORMAT; } timeZone = checkTimeZone(null, format, timeZone); final DateFormat sdf = getSDF(format, timeZone); try { final String str = sdf.format(date); if (appendable != null) { try { appendable.append(str); } catch (final IOException e) { throw new UncheckedIOException(e); } } return str; } finally { recycleSDF(format, timeZone, sdf); } } private static void fastDateFormat(final StringBuilder sb, final Appendable appendable, final long timeInMillis, final boolean isTimestamp) { Calendar c = utcCalendarPool.poll(); if (c == null) { c = Calendar.getInstance(UTC_TIME_ZONE); } c.setTimeInMillis(timeInMillis); final int year = c.get(Calendar.YEAR); final int month = c.get(Calendar.MONTH) + 1; final int day = c.get(Calendar.DAY_OF_MONTH); final int hour = c.get(Calendar.HOUR_OF_DAY); final int minute = c.get(Calendar.MINUTE); final int second = c.get(Calendar.SECOND); char[] utcTimestamp = utcTimestampFormatCharsPool.poll(); if (utcTimestamp == null) { utcTimestamp = new char[24]; utcTimestamp[4] = '-'; utcTimestamp[7] = '-'; utcTimestamp[10] = 'T'; utcTimestamp[13] = ':'; utcTimestamp[16] = ':'; utcTimestamp[19] = '.'; utcTimestamp[23] = 'Z'; } // // copy(cbufOfSTDInt[4][year], 0, utcTimestamp, 0, 4); // copy(cbufOfSTDInt[2][month], 0, utcTimestamp, 5, 2); // copy(cbufOfSTDInt[2][day], 0, utcTimestamp, 8, 2); // copy(cbufOfSTDInt[2][hour], 0, utcTimestamp, 11, 2); // copy(cbufOfSTDInt[2][minute], 0, utcTimestamp, 14, 2); // copy(cbufOfSTDInt[2][second], 0, utcTimestamp, 17, 2); // utcTimestamp[0] = cbufOfSTDInt[4][year][0]; utcTimestamp[1] = cbufOfSTDInt[4][year][1]; utcTimestamp[2] = cbufOfSTDInt[4][year][2]; utcTimestamp[3] = cbufOfSTDInt[4][year][3]; utcTimestamp[5] = cbufOfSTDInt[2][month][0]; utcTimestamp[6] = cbufOfSTDInt[2][month][1]; utcTimestamp[8] = cbufOfSTDInt[2][day][0]; utcTimestamp[9] = cbufOfSTDInt[2][day][1]; utcTimestamp[11] = cbufOfSTDInt[2][hour][0]; utcTimestamp[12] = cbufOfSTDInt[2][hour][1]; utcTimestamp[14] = cbufOfSTDInt[2][minute][0]; utcTimestamp[15] = cbufOfSTDInt[2][minute][1]; utcTimestamp[17] = cbufOfSTDInt[2][second][0]; utcTimestamp[18] = cbufOfSTDInt[2][second][1]; if (isTimestamp) { utcTimestamp[19] = '.'; final int milliSecond = c.get(Calendar.MILLISECOND); // copy(cbufOfSTDInt[3][milliSecond], 0, utcTimestamp, // 20, 3); utcTimestamp[20] = cbufOfSTDInt[3][milliSecond][0]; utcTimestamp[21] = cbufOfSTDInt[3][milliSecond][1]; utcTimestamp[22] = cbufOfSTDInt[3][milliSecond][2]; } else { utcTimestamp[19] = 'Z'; } try { if (isTimestamp) { if (sb == null) { if (appendable instanceof Writer) { ((Writer) appendable).write(utcTimestamp); } else { appendable.append(String.valueOf(utcTimestamp)); } } else { sb.append(utcTimestamp); } } else { if (sb == null) { if (appendable instanceof Writer) { ((Writer) appendable).write(utcTimestamp, 0, 20); } else { appendable.append(CharBuffer.wrap(utcTimestamp), 0, 20); } } else { sb.append(utcTimestamp, 0, 20); } } } catch (final IOException e) { throw new UncheckedIOException(e); } finally { utcCalendarPool.add(c); utcTimestampFormatCharsPool.add(utcTimestamp); } } // // https://stackoverflow.com/questions/47698046/datetimeformatter-iso-local-date-vs-datetimeformatter-ofpatternyyyy-mm-dd-in // /** // * // * @param temporal // * @param pattern // * @return // */ // public static String format(final TemporalAccessor temporal, String pattern) { // DateTimeFormatter dtf = dtfPool.get(pattern); // // if (dtf == null) { // dtf = DateTimeFormatter.ofPattern(pattern); // } // // return dtf.format(temporal); // } // // /** // * // * @param temporal // * @param pattern // * @param appendable // * @return // */ // public static void formatTo(final TemporalAccessor temporal, String pattern, final Appendable appendable) { // DateTimeFormatter dtf = dtfPool.get(pattern); // // if (dtf == null) { // dtf = DateTimeFormatter.ofPattern(pattern); // } // // dtf.formatTo(temporal, appendable); // } // /** // * // * @param zonedDateTime // * @return // */ // public static String format(final ZonedDateTime zonedDateTime) { // return format(zonedDateTime, null, null); // } // // /** // * // * @param zonedDateTime // * @param format // * @return // */ // public static String format(final ZonedDateTime zonedDateTime, final String format) { // return format(zonedDateTime, format, null); // } // // /** // * // * @param zonedDateTime // * @param format // * @param timeZone // * @return // */ // public static String format(final ZonedDateTime zonedDateTime, final String format, final TimeZone timeZone) { // return formatZonedDateTime(null, zonedDateTime, format, timeZone); // } // // /** // * // * @param appendable // * @param zonedDateTime // */ // public static void formatTo(final Appendable appendable, final ZonedDateTime zonedDateTime) { // format(appendable, zonedDateTime, null, null); // } // // /** // * // * @param appendable // * @param zonedDateTime // * @param format // */ // public static void formatTo(final Appendable appendable, final ZonedDateTime zonedDateTime, final String format) { // formatZonedDateTime(appendable, zonedDateTime, format, null); // } // // /** // * // * @param appendable // * @param zonedDateTime // * @param format // * @param timeZone // */ // public static void formatTo(final Appendable appendable, final ZonedDateTime zonedDateTime, final String format, final TimeZone timeZone) { // formatZonedDateTime(appendable, zonedDateTime, format, timeZone); // } // // /** // * // * @param appendable // * @param date // * @param format // * @param timeZone // * @return // */ // private static String formatZonedDateTime(final Appendable appendable, final ZonedDateTime zonedDateTime, String format, TimeZone timeZone) { // String ret = null; // // if (format == null) { // final ZoneId zoneId = timeZone == null ? zonedDateTime.getZone() : timeZone.toZoneId(); // ret = zonedDateTime.getZone().equals(zoneId) ? zonedDateTime.toString() : zonedDateTime.withZoneSameInstant(zoneId).toString(); // } else { // final ZoneId zoneId = timeZone == null ? (format.endsWith("'Z'") ? UTC_TIME_ZONE.toZoneId() : zonedDateTime.getZone()) : timeZone.toZoneId(); // final DateTimeFormatter dtf = getDateTimeFormatter(format, zoneId); // // ret = zonedDateTime.format(dtf); // } // // if (writer != null) { // try { // writer.write(ret); // } catch (IOException e) { // throw new UncheckedIOException(e); // } // } // // return ret; // } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the years field to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setYears(final T date, final int amount) { return set(date, Calendar.YEAR, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the months field to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setMonths(final T date, final int amount) { return set(date, Calendar.MONTH, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the day of month field to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setDays(final T date, final int amount) { return set(date, Calendar.DAY_OF_MONTH, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the hours field to a date returning a new object. * Hours range from 0-23. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setHours(final T date, final int amount) { return set(date, Calendar.HOUR_OF_DAY, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the minute field to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setMinutes(final T date, final int amount) { return set(date, Calendar.MINUTE, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the seconds field to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setSeconds(final T date, final int amount) { return set(date, Calendar.SECOND, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the milliseconds field to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ public static T setMilliseconds(final T date, final int amount) { return set(date, Calendar.MILLISECOND, amount); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* * Sets the specified field to a date returning a new object. * This does not use a lenient calendar. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param calendarField the {@code Calendar} field to set the amount to * @param amount the amount to set * @return a new {@code Date} set with the specified value * @throws IllegalArgumentException if the date is null */ private static T set(final T date, final int calendarField, final int amount) { N.checkArgNotNull(date, cs.date); // getInstance() returns a new object, so this method is thread safe. final Calendar c = Calendar.getInstance(); c.setLenient(false); c.setTime(date); //noinspection MagicConstant c.set(calendarField, amount); return createDate(c.getTimeInMillis(), date.getClass()); } /** * Adds or subtracts the specified amount of time to the given time unit, * based on the calendar's rules. For example, to subtract 5 days from the * current time of the calendar, you can achieve it by calling: *

* N.roll(date, -5, TimeUnit.DAYS). * * @param * @param date * @param amount * @param unit * @return a new instance of Date with the specified amount rolled. * @throws IllegalArgumentException */ @Beta public static T roll(final T date, final long amount, final TimeUnit unit) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); return createDate(date.getTime() + unit.toMillis(amount), date.getClass()); } /** * Adds or subtracts the specified amount of time to the given calendar * unit, based on the calendar's rules. For example, to subtract 5 days from * the current time of the calendar, you can achieve it by calling: *

* N.roll(date, -5, CalendarUnit.DAY). * * @param * @param date * @param amount * @param unit * @return a new instance of Date with the specified amount rolled. * @throws IllegalArgumentException */ @Beta public static T roll(final T date, final int amount, final CalendarField unit) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); N.checkArgNotNull(unit, cs.CalendarField); // if (amount > Integer.MAX_VALUE || amount < Integer.MIN_VALUE) { // throw new IllegalArgumentException("The amount :" + amount + " is too big for unit: " + unit); // } if (unit == CalendarField.MONTH || unit == CalendarField.YEAR) { final Calendar c = createCalendar(date); //noinspection MagicConstant c.add(unit.value(), amount); return createDate(c.getTimeInMillis(), date.getClass()); } else { return createDate(date.getTime() + toMillis(unit, amount), date.getClass()); } } /** * Adds or subtracts the specified amount of time to the given time unit, * based on the calendar's rules. For example, to subtract 5 days from the * current time of the calendar, you can achieve it by calling: *

* N.roll(c, -5, TimeUnit.DAYS). * * @param * @param calendar * @param amount * @param unit * @return a new instance of Calendar with the specified amount rolled. * @throws IllegalArgumentException */ @Beta public static T roll(final T calendar, final long amount, final TimeUnit unit) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); //NOSONAR N.checkArgNotNull(unit, cs.CalendarField); return createCalendar(calendar, calendar.getTimeInMillis() + unit.toMillis(amount)); } /** * Adds or subtracts the specified amount of time to the given calendar * unit, based on the calendar's rules. For example, to subtract 5 days from * the current time of the calendar, you can achieve it by calling: *

* N.roll(c, -5, CalendarUnit.DAY). * * @param * @param calendar * @param amount * @param unit * @return a new instance of Calendar with the specified amount rolled. * @throws IllegalArgumentException */ @Beta public static T roll(final T calendar, final int amount, final CalendarField unit) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); N.checkArgNotNull(unit, cs.CalendarField); // if (amount > Integer.MAX_VALUE || amount < Integer.MIN_VALUE) { // throw new IllegalArgumentException("The amount :" + amount + " is too big for unit: " + unit); // } final T result = createCalendar(calendar, calendar.getTimeInMillis()); //noinspection MagicConstant result.add(unit.value(), amount); return result; } //----------------------------------------------------------------------- private static long toMillis(final CalendarField field, final long amount) { switch (field) { case MILLISECOND: return amount; case SECOND: return amount * 1000L; case MINUTE: return amount * 60 * 1000L; case HOUR: return amount * 60 * 60 * 1000L; case DAY: return amount * 24 * 60 * 60 * 1000L; case WEEK: return amount * 7 * 24 * 60 * 60 * 1000L; default: throw new IllegalArgumentException("Unsupported unit: " + field); } } //----------------------------------------------------------------------- /** * Adds a number of years to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addYears(final T date, final int amount) { return roll(date, amount, CalendarField.YEAR); } //----------------------------------------------------------------------- /** * Adds a number of months to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addMonths(final T date, final int amount) { return roll(date, amount, CalendarField.MONTH); } //----------------------------------------------------------------------- /** * Adds a number of weeks to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addWeeks(final T date, final int amount) { return roll(date, amount, CalendarField.WEEK); } //----------------------------------------------------------------------- /** * Adds a number of days to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addDays(final T date, final int amount) { return roll(date, amount, CalendarField.DAY); } //----------------------------------------------------------------------- /** * Adds a number of hours to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addHours(final T date, final int amount) { return roll(date, amount, CalendarField.HOUR); } //----------------------------------------------------------------------- /** * Adds a number of minutes to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addMinutes(final T date, final int amount) { return roll(date, amount, CalendarField.MINUTE); } //----------------------------------------------------------------------- /** * Adds a number of seconds to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addSeconds(final T date, final int amount) { return roll(date, amount, CalendarField.SECOND); } //----------------------------------------------------------------------- /** * Adds a number of milliseconds to a date returning a new object. * The original {@code Date} is unchanged. * * @param * @param date the date, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the date is null */ public static T addMilliseconds(final T date, final int amount) { return roll(date, amount, CalendarField.MILLISECOND); } //----------------------------------------------------------------------- /** * Adds a number of years to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addYears(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.YEAR); } //----------------------------------------------------------------------- /** * Adds a number of months to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addMonths(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.MONTH); } //----------------------------------------------------------------------- /** * Adds a number of weeks to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addWeeks(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.WEEK); } //----------------------------------------------------------------------- /** * Adds a number of days to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addDays(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.DAY); } //----------------------------------------------------------------------- /** * Adds a number of hours to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addHours(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.HOUR); } //----------------------------------------------------------------------- /** * Adds a number of minutes to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addMinutes(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.MINUTE); } //----------------------------------------------------------------------- /** * Adds a number of seconds to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addSeconds(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.SECOND); } //----------------------------------------------------------------------- /** * Adds a number of milliseconds to a calendar returning a new object. * The original {@code Date} is unchanged. * * @param * @param calendar the calendar, not null * @param amount the amount to add, may be negative * @return * @throws IllegalArgumentException if the calendar is null */ public static T addMilliseconds(final T calendar, final int amount) { return roll(calendar, amount, CalendarField.MILLISECOND); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Rounds a date, leaving the field specified as the most * significant field.

* *

For example, if you had the date-time of 28 Mar 2002 * 13:45:01.231, if this was passed with HOUR, it would return * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it * would return 1 April 2002 0:00:00.000.

* *

For a date in a timezone that handles the change to daylight-saving time, rounding to Calendar.HOUR_OF_DAY will behave as follows. * Suppose daylight-saving time begins at 02:00 on March 30. Rounding a * date that crosses this time would produce the following values: *

*
    *
  • March 30, 2003 01:10 rounds to March 30, 2003 01:00
  • *
  • March 30, 2003 01:40 rounds to March 30, 2003 03:00
  • *
  • March 30, 2003 02:10 rounds to March 30, 2003 03:00
  • *
  • March 30, 2003 02:40 rounds to March 30, 2003 04:00
  • *
* * @param * @param date the date to work with, not null * @param field the field from {@code Calendar} or {@code SEMI_MONTH} * @return * @throws IllegalArgumentException * @throws ArithmeticException if the year is over 280 million */ public static T round(final T date, final int field) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar gval = Calendar.getInstance(); gval.setTime(date); modify(gval, field, ModifyType.ROUND); return createDate(gval.getTimeInMillis(), date.getClass()); } /** * Rounds the given date to the nearest whole unit as specified by the CalendarField. * The original date object is unchanged. * * @param The type of the date object, which must be a subclass of java.util.Date. * @param date The date to be rounded. Must not be {@code null}. * @param field The CalendarField to which the date is to be rounded. Must not be {@code null}. * @return A new date object of type T, rounded to the nearest whole unit as specified by the field. * @throws IllegalArgumentException if the date or field is {@code null}. */ public static T round(final T date, final CalendarField field) { N.checkArgNotNull(date, cs.date); N.checkArgNotNull(field, cs.CalendarField); return round(date, field.value()); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Rounds a date, leaving the field specified as the most * significant field.

* *

For example, if you had the date-time of 28 Mar 2002 * 13:45:01.231, if this was passed with HOUR, it would return * 28 Mar 2002 14:00:00.000. If this was passed with MONTH, it * would return 1 April 2002 0:00:00.000.

* *

For a date in a timezone that handles the change to daylight-saving time, rounding to Calendar.HOUR_OF_DAY will behave as follows. * Suppose daylight-saving time begins at 02:00 on March 30. Rounding a * date that crosses this time would produce the following values: *

*
    *
  • March 30, 2003 01:10 rounds to March 30, 2003 01:00
  • *
  • March 30, 2003 01:40 rounds to March 30, 2003 03:00
  • *
  • March 30, 2003 02:10 rounds to March 30, 2003 03:00
  • *
  • March 30, 2003 02:40 rounds to March 30, 2003 04:00
  • *
* * @param * @param calendar the date to work with, not null * @param field the field from {@code Calendar} or {@code SEMI_MONTH} * @return * @throws IllegalArgumentException if the date is {@code null} * @throws ArithmeticException if the year is over 280 million */ public static T round(final T calendar, final int field) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); final Calendar rounded = (Calendar) calendar.clone(); modify(rounded, field, ModifyType.ROUND); if (rounded.getClass().equals(calendar.getClass())) { return (T) rounded; } return createCalendar(calendar, rounded.getTimeInMillis()); } /** * Rounds the given calendar to the nearest whole unit as specified by the CalendarField. * The original calendar object is unchanged. * * @param The type of the calendar object, which must be a subclass of java.util.Calendar. * @param calendar The calendar to be rounded. Must not be {@code null}. * @param field The CalendarField to which the calendar is to be rounded. Must not be {@code null}. * @return A new calendar object of type T, rounded to the nearest whole unit as specified by the field. * @throws IllegalArgumentException if the calendar or field is {@code null}. */ public static T round(final T calendar, final CalendarField field) { N.checkArgNotNull(calendar, cs.calendar); N.checkArgNotNull(field, cs.CalendarField); return round(calendar, field.value()); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Truncates a date, leaving the field specified as the most * significant field.

* *

For example, if you had the date-time of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 13:00:00.000. If this was passed with MONTH, it would * return 1 Mar 2002 0:00:00.000.

* * @param * @param date the date to work with, not null * @param field the field from {@code Calendar} or {@code SEMI_MONTH} * @return * @throws IllegalArgumentException if the date is {@code null} * @throws ArithmeticException if the year is over 280 million */ public static T truncate(final T date, final int field) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar gval = Calendar.getInstance(); gval.setTime(date); modify(gval, field, ModifyType.TRUNCATE); return createDate(gval.getTimeInMillis(), date.getClass()); } /** * Truncates the given date, leaving the field specified as the most significant field. * The original date object is unchanged. * * @param The type of the date object, which must be a subclass of java.util.Date. * @param date The date to be truncated. Must not be {@code null}. * @param field The CalendarField to which the date is to be truncated. Must not be {@code null}. * @return A new date object of type T, truncated to the nearest whole unit as specified by the field. * @throws IllegalArgumentException if the date or field is {@code null}. */ public static T truncate(final T date, final CalendarField field) { N.checkArgNotNull(date, cs.date); N.checkArgNotNull(field, cs.CalendarField); return truncate(date, field.value()); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Truncates a date, leaving the field specified as the most * significant field.

* *

For example, if you had the date-time of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 13:00:00.000. If this was passed with MONTH, it would * return 1 Mar 2002 0:00:00.000.

* * @param * @param calendar the date to work with, not null * @param field the field from {@code Calendar} or {@code SEMI_MONTH} * @return * @throws IllegalArgumentException if the date is {@code null} * @throws ArithmeticException if the year is over 280 million */ public static T truncate(final T calendar, final int field) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); final Calendar truncated = (Calendar) calendar.clone(); modify(truncated, field, ModifyType.TRUNCATE); if (truncated.getClass().equals(calendar.getClass())) { return (T) truncated; } return createCalendar(calendar, truncated.getTimeInMillis()); } /** * Truncates the given calendar, leaving the field specified as the most significant field. * The original calendar object is unchanged. * * @param The type of the calendar object, which must be a subclass of java.util.Calendar. * @param calendar The calendar to be truncated. Must not be {@code null}. * @param field The CalendarField to which the calendar is to be truncated. Must not be {@code null}. * @return A new calendar object of type T, truncated to the nearest whole unit as specified by the field. * @throws IllegalArgumentException if the calendar or field is {@code null}. */ public static T truncate(final T calendar, final CalendarField field) { N.checkArgNotNull(calendar, cs.calendar); N.checkArgNotNull(field, cs.CalendarField); return truncate(calendar, field.value()); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Gets a date ceiling, leaving the field specified as the most * significant field.

* *

For example, if you had the date-time of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 14:00:00.000. If this was passed with MONTH, it would * return 1 Apr 2002 0:00:00.000.

* * @param * @param date the date to work with, not null * @param field the field from {@code Calendar} or {@code SEMI_MONTH} * @return * @throws IllegalArgumentException if the date is {@code null} * @throws ArithmeticException if the year is over 280 million */ public static T ceiling(final T date, final int field) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar gval = Calendar.getInstance(); gval.setTime(date); modify(gval, field, ModifyType.CEILING); return createDate(gval.getTimeInMillis(), date.getClass()); } /** * Returns a new date object of the same type as the input, but adjusted to the nearest future unit as specified by the CalendarField. * The original date object is unchanged. * * @param The type of the date object, which must be a subclass of java.util.Date. * @param date The date to be adjusted. Must not be {@code null}. * @param field The CalendarField to which the date is to be adjusted. Must not be {@code null}. * @return A new date object of type T, adjusted to the nearest future unit as specified by the field. * @throws IllegalArgumentException if the date or field is {@code null}. */ public static T ceiling(final T date, final CalendarField field) { N.checkArgNotNull(date, cs.date); N.checkArgNotNull(field, cs.CalendarField); return ceiling(date, field.value()); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Gets a date ceiling, leaving the field specified as the most * significant field.

* *

For example, if you had the date-time of 28 Mar 2002 * 13:45:01.231, if you passed with HOUR, it would return 28 Mar * 2002 14:00:00.000. If this was passed with MONTH, it would * return 1 Apr 2002 0:00:00.000.

* * @param * @param calendar the date to work with, not null * @param field the field from {@code Calendar} or {@code SEMI_MONTH} * @return * @throws IllegalArgumentException if the date is {@code null} * @throws ArithmeticException if the year is over 280 million */ public static T ceiling(final T calendar, final int field) throws IllegalArgumentException { N.checkArgNotNull(calendar, cs.calendar); final Calendar ceiled = (Calendar) calendar.clone(); modify(ceiled, field, ModifyType.CEILING); if (ceiled.getClass().equals(calendar.getClass())) { return (T) ceiled; } return createCalendar(calendar, ceiled.getTimeInMillis()); } /** * Adjusts the given calendar to the ceiling of the specified field. * The original calendar object is unchanged; a new calendar object representing the adjusted time is returned. * This method can be used to round up the calendar to the nearest value of the specified field. * * @param The type of the calendar object, which must extend java.util.Calendar. * @param calendar The original calendar object to be adjusted. * @param field The field to be used for the ceiling operation, as a CalendarField. * @return A new calendar object representing the adjusted time. * @throws IllegalArgumentException if the calendar is {@code null}. */ public static T ceiling(final T calendar, final CalendarField field) { N.checkArgNotNull(calendar, cs.calendar); N.checkArgNotNull(field, cs.CalendarField); return ceiling(calendar, field.value()); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Internal calculation method.

* * @param val the calendar, not null * @param field * @param modType type to truncate, round or ceiling * @throws ArithmeticException if the year is over 280 million */ private static void modify(final Calendar val, final int field, final ModifyType modType) { //NOSONAR if (val.get(Calendar.YEAR) > 280_000_000) { throw new ArithmeticException("Calendar value too large for accurate calculations"); } if (field == Calendar.MILLISECOND) { return; } // ----------------- Fix for LANG-59 ---------------------- START --------------- // see https://issues.apache.org/jira/browse/LANG-59 // // Manually truncate milliseconds, seconds and minutes, rather than using // Calendar methods. final java.util.Date date = val.getTime(); long time = date.getTime(); boolean done = false; // truncate milliseconds final int millis = val.get(Calendar.MILLISECOND); if (ModifyType.TRUNCATE == modType || millis < 500) { time = time - millis; } if (field == Calendar.SECOND) { done = true; } // truncate seconds final int seconds = val.get(Calendar.SECOND); if (!done && (ModifyType.TRUNCATE == modType || seconds < 30)) { time = time - (seconds * 1000L); } if (field == Calendar.MINUTE) { done = true; } // truncate minutes final int minutes = val.get(Calendar.MINUTE); if (!done && (ModifyType.TRUNCATE == modType || minutes < 30)) { time = time - (minutes * 60000L); } // reset time if (date.getTime() != time) { date.setTime(time); val.setTime(date); } // ----------------- Fix for LANG-59 ----------------------- END ---------------- boolean roundUp = false; for (final int[] aField : fields) { for (final int element : aField) { if (element == field) { //This is our field... we stop looping if (modType == ModifyType.CEILING || modType == ModifyType.ROUND && roundUp) { if (field == SEMI_MONTH) { //This is a special case that's hard to generalize //If the date is 1, we round up to 16, otherwise // we subtract 15 days and add 1 month if (val.get(Calendar.DATE) == 1) { val.add(Calendar.DATE, 15); } else { val.add(Calendar.DATE, -15); val.add(Calendar.MONTH, 1); } // ----------------- Fix for LANG-440 ---------------------- START --------------- } else if (field == Calendar.AM_PM) { // This is a special case // If the time is 0, we round up to 12, otherwise // we subtract 12 hours and add 1 day if (val.get(Calendar.HOUR_OF_DAY) == 0) { val.add(Calendar.HOUR_OF_DAY, 12); } else { val.add(Calendar.HOUR_OF_DAY, -12); val.add(Calendar.DATE, 1); } // ----------------- Fix for LANG-440 ---------------------- END --------------- } else { //We need at add one to this field since the // last number causes us to round up //noinspection MagicConstant val.add(aField[0], 1); } } return; } } //We have various fields that are not easy roundings int offset = 0; boolean offsetSet = false; //These are special types of fields that require different rounding rules switch (field) { case SEMI_MONTH: if (aField[0] == Calendar.DATE) { //If we're going to drop the DATE field's value, // we want to do this our own way. //We need to subtract 1 since the date has a minimum of 1 offset = val.get(Calendar.DATE) - 1; //If we're above 15 days adjustment, that means we're in the // bottom half of the month and should stay accordingly. if (offset >= 15) { offset -= 15; } //Record whether we're in the top or bottom half of that range roundUp = offset > 7; offsetSet = true; } break; case Calendar.AM_PM: if (aField[0] == Calendar.HOUR_OF_DAY) { //If we're going to drop the HOUR field's value, // we want to do this our own way. offset = val.get(Calendar.HOUR_OF_DAY); if (offset >= 12) { offset -= 12; } roundUp = offset >= 6; offsetSet = true; } break; default: break; } if (!offsetSet) { @SuppressWarnings("MagicConstant") final int min = val.getActualMinimum(aField[0]); @SuppressWarnings("MagicConstant") final int max = val.getActualMaximum(aField[0]); //Calculate the offset from the minimum allowed value //noinspection MagicConstant offset = val.get(aField[0]) - min; //Set roundUp if this is more than halfway between the minimum and maximum roundUp = offset > ((max - min) / 2); } //We need to remove this field if (offset != 0) { //noinspection MagicConstant val.set(aField[0], val.get(aField[0]) - offset); } } throw new IllegalArgumentException("The field " + field + " is not supported"); } /** * Determines if two calendars are equal up to no more than the specified most significant field. * * @param cal1 the first calendar, not null * @param cal2 the second calendar, not null * @param field the field from {@code CalendarField} to be the most significant field for comparison * @return {@code true} if cal1 and cal2 are equal up to the specified field; {@code false} otherwise * @throws IllegalArgumentException if any argument is {@code null} */ public static boolean truncatedEquals(final Calendar cal1, final Calendar cal2, final CalendarField field) { return truncatedCompareTo(cal1, cal2, field) == 0; } /** * Copied from Apache Commons Lang under Apache License v2. *
* * Determines if two calendars are equal up to no more than the specified most significant field. * * @param cal1 the first calendar, not {@code null} * @param cal2 the second calendar, not {@code null} * @param field the field from {@code Calendar} * @return {@code true} if equal; otherwise {@code false} * @throws IllegalArgumentException if any argument is {@code null} * @see #truncate(Calendar, int) * @see #truncatedEquals(java.util.Date, java.util.Date, int) */ public static boolean truncatedEquals(final Calendar cal1, final Calendar cal2, final int field) { return truncatedCompareTo(cal1, cal2, field) == 0; } /** * Determines if two dates are equal up to no more than the specified most significant field. * * @param date1 The first date, not {@code null}. * @param date2 The second date, not {@code null}. * @param field The field from {@code CalendarField} to be the most significant field for comparison. * @return {@code true} if date1 and date2 are equal up to the specified field; {@code false} otherwise. * @throws IllegalArgumentException if any argument is {@code null} */ public static boolean truncatedEquals(final java.util.Date date1, final java.util.Date date2, final CalendarField field) { return truncatedCompareTo(date1, date2, field) == 0; } /** * Copied from Apache Commons Lang under Apache License v2. *
* * Determines if two dates are equal up to no more than the specified * most significant field. * * @param date1 the first date, not {@code null} * @param date2 the second date, not {@code null} * @param field the field from {@code Calendar} * @return {@code true} if equal; otherwise {@code false} * @throws IllegalArgumentException if any argument is {@code null} * @see #truncate(java.util.Date, int) * @see #truncatedEquals(Calendar, Calendar, int) */ public static boolean truncatedEquals(final java.util.Date date1, final java.util.Date date2, final int field) { return truncatedCompareTo(date1, date2, field) == 0; } /** * Compares two Calendar instances up to the specified field. * The comparison is based on the most significant field, meaning that it compares * the Calendar instances year by year, month by month, day by day, etc., depending on the specified field. * * @param cal1 The first Calendar instance to be compared, not {@code null}. * @param cal2 The second Calendar instance to be compared, not {@code null}. * @param field The field from {@code CalendarField} to be the most significant field for comparison. * @return A negative integer, zero, or a positive integer as the first Calendar is less than, equal to, or greater than the second. * @throws IllegalArgumentException if any argument is {@code null}. */ public static int truncatedCompareTo(final Calendar cal1, final Calendar cal2, final CalendarField field) { return truncate(cal1, field).compareTo(truncate(cal2, field)); } /** * Copied from Apache Commons Lang under Apache License v2. *
* * Determines how two calendars compare up to no more than the specified most significant field. * * @param cal1 the first calendar, not {@code null} * @param cal2 the second calendar, not {@code null} * @param field the field from {@code Calendar} * @return a negative integer, zero, or a positive integer as the first * calendar is less than, equal to, or greater than the second. * @throws IllegalArgumentException if any argument is {@code null} * @see #truncate(Calendar, int) * @see #truncatedCompareTo(java.util.Date, java.util.Date, int) */ public static int truncatedCompareTo(final Calendar cal1, final Calendar cal2, final int field) { return truncate(cal1, field).compareTo(truncate(cal2, field)); } /** * Compares two Date instances up to the specified field. * The comparison is based on the most significant field, meaning that it compares * the Date instances year by year, month by month, day by day, etc., depending on the specified field. * * @param date1 The first Date instance to be compared, not {@code null}. * @param date2 The second Date instance to be compared, not {@code null}. * @param field The field from {@code CalendarField} to be the most significant field for comparison. * @return A negative integer, zero, or a positive integer as the first Date is less than, equal to, or greater than the second. * @throws IllegalArgumentException if any argument is {@code null}. */ public static int truncatedCompareTo(final java.util.Date date1, final java.util.Date date2, final CalendarField field) { return truncate(date1, field).compareTo(truncate(date2, field)); } /** * Copied from Apache Commons Lang under Apache License v2. *
* * Determines how two dates compare up to no more than the specified * most significant field. * * @param date1 the first date, not {@code null} * @param date2 the second date, not {@code null} * @param field the field from {@code Calendar} * @return a negative integer, zero, or a positive integer as the first * date is less than, equal to, or greater than the second. * @throws IllegalArgumentException if any argument is {@code null} * @see #truncate(Calendar, int) * @see #truncatedCompareTo(java.util.Date, java.util.Date, int) */ public static int truncatedCompareTo(final java.util.Date date1, final java.util.Date date2, final int field) { return truncate(date1, field).compareTo(truncate(date2, field)); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of milliseconds within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the milliseconds of any date will only return the number of milliseconds * of the current second (resulting in a number between 0 and 999). This * method will retrieve the number of milliseconds for any fragment. * For example, if you want to calculate the number of milliseconds past today, * your fragment is Calendar.DATE or Calendar.DAY_OF_YEAR. The result will * be all milliseconds of the past hour(s), minutes(s) and second(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a SECOND field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.SECOND as fragment will return 538
  • *
  • January 6, 2008 7:15:10.538 with Calendar.SECOND as fragment will return 538
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MINUTE as fragment will return 10538 (10*1000 + 538)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in milliseconds)
  • *
* * @param date the date to work with, not null * @param fragment the {@code Calendar} field part of date to calculate * @return number of milliseconds within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInMilliseconds(final java.util.Date date, final CalendarField fragment) { return getFragment(date, fragment.value(), TimeUnit.MILLISECONDS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of seconds within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the seconds of any date will only return the number of seconds * of the current minute (resulting in a number between 0 and 59). This * method will retrieve the number of seconds for any fragment. * For example, if you want to calculate the number of seconds past today, * your fragment is Calendar.DATE or Calendar.DAY_OF_YEAR. The result will * be all seconds of the past hour(s) and minutes(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a SECOND field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.MINUTE as fragment will return 10 * (equivalent to deprecated date.getSeconds())
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MINUTE as fragment will return 10 * (equivalent to deprecated date.getSeconds())
  • *
  • January 6, 2008 7:15:10.538 with Calendar.DAY_OF_YEAR as fragment will return 26110 * (7*3600 + 15*60 + 10)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in seconds)
  • *
* * @param date the date to work with, not null * @param fragment the {@code Calendar} field part of date to calculate * @return number of seconds within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInSeconds(final java.util.Date date, final CalendarField fragment) { return getFragment(date, fragment.value(), TimeUnit.SECONDS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of minutes within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the minutes of any date will only return the number of minutes * of the current hour (resulting in a number between 0 and 59). This * method will retrieve the number of minutes for any fragment. * For example, if you want to calculate the number of minutes past this month, * your fragment is Calendar.MONTH. The result will be all minutes of the * past day(s) and hour(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a MINUTE field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.HOUR_OF_DAY as fragment will return 15 * (equivalent to deprecated date.getMinutes())
  • *
  • January 6, 2008 7:15:10.538 with Calendar.HOUR_OF_DAY as fragment will return 15 * (equivalent to deprecated date.getMinutes())
  • *
  • January 1, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 15
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 435 (7*60 + 15)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in minutes)
  • *
* * @param date the date to work with, not null * @param fragment the {@code Calendar} field part of date to calculate * @return number of minutes within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInMinutes(final java.util.Date date, final CalendarField fragment) { return getFragment(date, fragment.value(), TimeUnit.MINUTES); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of hours within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the hours of any date will only return the number of hours * of the current day (resulting in a number between 0 and 23). This * method will retrieve the number of hours for any fragment. * For example, if you want to calculate the number of hours past this month, * your fragment is Calendar.MONTH. The result will be all hours of the * past day(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to an HOUR field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.DAY_OF_YEAR as fragment will return 7 * (equivalent to deprecated date.getHours())
  • *
  • January 6, 2008 7:15:10.538 with Calendar.DAY_OF_YEAR as fragment will return 7 * (equivalent to deprecated date.getHours())
  • *
  • January 1, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 7
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 127 (5*24 + 7)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in hours)
  • *
* * @param date the date to work with, not null * @param fragment the {@code Calendar} field part of date to calculate * @return number of hours within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInHours(final java.util.Date date, final CalendarField fragment) { return getFragment(date, fragment.value(), TimeUnit.HOURS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of days within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the days of any date will only return the number of days * of the current month (resulting in a number between 1 and 31). This * method will retrieve the number of days for any fragment. * For example, if you want to calculate the number of days past this year, * your fragment is Calendar.YEAR. The result will be all days of the * past month(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a DAY field will return 0.

* *
    *
  • January 28, 2008 with Calendar.MONTH as fragment will return 28 * (equivalent to deprecated date.getDay())
  • *
  • February 28, 2008 with Calendar.MONTH as fragment will return 28 * (equivalent to deprecated date.getDay())
  • *
  • January 28, 2008 with Calendar.YEAR as fragment will return 28
  • *
  • February 28, 2008 with Calendar.YEAR as fragment will return 59
  • *
  • January 28, 2008 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in days)
  • *
* * @param date the date to work with, not null * @param fragment the {@code Calendar} field part of date to calculate * @return number of days within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInDays(final java.util.Date date, final CalendarField fragment) { return getFragment(date, fragment.value(), TimeUnit.DAYS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* * Gets a Date fragment for any unit. * * @param date the date to work with, not null * @param fragment the Calendar field part of date to calculate * @param unit the time unit * @return number of units within the fragment of the date * @throws IllegalArgumentException if the date is {@code null} or specified fragment is not supported */ private static long getFragment(final java.util.Date date, final int fragment, final TimeUnit unit) { N.checkArgNotNull(date, cs.date); final Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return getFragment(calendar, fragment, unit); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of milliseconds within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the milliseconds of any date will only return the number of milliseconds * of the current second (resulting in a number between 0 and 999). This * method will retrieve the number of milliseconds for any fragment. * For example, if you want to calculate the number of seconds past today, * your fragment is Calendar.DATE or Calendar.DAY_OF_YEAR. The result will * be all seconds of the past hour(s), minutes(s) and second(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a MILLISECOND field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.SECOND as fragment will return 538 * (equivalent to calendar.get(Calendar.MILLISECOND))
  • *
  • January 6, 2008 7:15:10.538 with Calendar.SECOND as fragment will return 538 * (equivalent to calendar.get(Calendar.MILLISECOND))
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MINUTE as fragment will return 10538 * (10*1000 + 538)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in milliseconds)
  • *
* * @param calendar the calendar to work with, not null * @param fragment the {@code Calendar} field part of calendar to calculate * @return number of milliseconds within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInMilliseconds(final Calendar calendar, final CalendarField fragment) { return getFragment(calendar, fragment.value(), TimeUnit.MILLISECONDS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of seconds within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the seconds of any date will only return the number of seconds * of the current minute (resulting in a number between 0 and 59). This * method will retrieve the number of seconds for any fragment. * For example, if you want to calculate the number of seconds past today, * your fragment is Calendar.DATE or Calendar.DAY_OF_YEAR. The result will * be all seconds of the past hour(s) and minutes(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a SECOND field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.MINUTE as fragment will return 10 * (equivalent to calendar.get(Calendar.SECOND))
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MINUTE as fragment will return 10 * (equivalent to calendar.get(Calendar.SECOND))
  • *
  • January 6, 2008 7:15:10.538 with Calendar.DAY_OF_YEAR as fragment will return 26110 * (7*3600 + 15*60 + 10)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in seconds)
  • *
* * @param calendar the calendar to work with, not null * @param fragment the {@code Calendar} field part of calendar to calculate * @return number of seconds within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInSeconds(final Calendar calendar, final CalendarField fragment) { return getFragment(calendar, fragment.value(), TimeUnit.SECONDS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of minutes within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the minutes of any date will only return the number of minutes * of the current hour (resulting in a number between 0 and 59). This * method will retrieve the number of minutes for any fragment. * For example, if you want to calculate the number of minutes past this month, * your fragment is Calendar.MONTH. The result will be all minutes of the * past day(s) and hour(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a MINUTE field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.HOUR_OF_DAY as fragment will return 15 * (equivalent to calendar.get(Calendar.MINUTES))
  • *
  • January 6, 2008 7:15:10.538 with Calendar.HOUR_OF_DAY as fragment will return 15 * (equivalent to calendar.get(Calendar.MINUTES))
  • *
  • January 1, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 15
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 435 (7*60 + 15)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in minutes)
  • *
* * @param calendar the calendar to work with, not null * @param fragment the {@code Calendar} field part of calendar to calculate * @return number of minutes within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInMinutes(final Calendar calendar, final CalendarField fragment) { return getFragment(calendar, fragment.value(), TimeUnit.MINUTES); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of hours within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the hours of any date will only return the number of hours * of the current day (resulting in a number between 0 and 23). This * method will retrieve the number of hours for any fragment. * For example, if you want to calculate the number of hours past this month, * your fragment is Calendar.MONTH. The result will be all hours of the * past day(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to an HOUR field will return 0.

* *
    *
  • January 1, 2008 7:15:10.538 with Calendar.DAY_OF_YEAR as fragment will return 7 * (equivalent to calendar.get(Calendar.HOUR_OF_DAY))
  • *
  • January 6, 2008 7:15:10.538 with Calendar.DAY_OF_YEAR as fragment will return 7 * (equivalent to calendar.get(Calendar.HOUR_OF_DAY))
  • *
  • January 1, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 7
  • *
  • January 6, 2008 7:15:10.538 with Calendar.MONTH as fragment will return 127 (5*24 + 7)
  • *
  • January 16, 2008 7:15:10.538 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in hours)
  • *
* * @param calendar the calendar to work with, not null * @param fragment the {@code Calendar} field part of calendar to calculate * @return number of hours within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInHours(final Calendar calendar, final CalendarField fragment) { return getFragment(calendar, fragment.value(), TimeUnit.HOURS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Returns the number of days within the * fragment. All date fields greater than the fragment will be ignored.

* *

Asking the days of any date will only return the number of days * of the current month (resulting in a number between 1 and 31). This * method will retrieve the number of days for any fragment. * For example, if you want to calculate the number of days past this year, * your fragment is Calendar.YEAR. The result will be all days of the * past month(s).

* *

Valid fragments are: Calendar.YEAR, Calendar.MONTH, both * Calendar.DAY_OF_YEAR and Calendar.DATE, Calendar.HOUR_OF_DAY, * Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND * A fragment less than or equal to a DAY field will return 0.

* *
    *
  • January 28, 2008 with Calendar.MONTH as fragment will return 28 * (equivalent to calendar.get(Calendar.DAY_OF_MONTH))
  • *
  • February 28, 2008 with Calendar.MONTH as fragment will return 28 * (equivalent to calendar.get(Calendar.DAY_OF_MONTH))
  • *
  • January 28, 2008 with Calendar.YEAR as fragment will return 28 * (equivalent to calendar.get(Calendar.DAY_OF_YEAR))
  • *
  • February 28, 2008 with Calendar.YEAR as fragment will return 59 * (equivalent to calendar.get(Calendar.DAY_OF_YEAR))
  • *
  • January 28, 2008 with Calendar.MILLISECOND as fragment will return 0 * (a millisecond cannot be split in days)
  • *
* * @param calendar the calendar to work with, not null * @param fragment the {@code Calendar} field part of calendar to calculate * @return number of days within the fragment of date * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ public static long getFragmentInDays(final Calendar calendar, final CalendarField fragment) { return getFragment(calendar, fragment.value(), TimeUnit.DAYS); } /** * Copied from Apache Commons Lang under Apache License v2. *
* * Gets a Calendar fragment for any unit. * * @param calendar the calendar to work with, not null * @param fragment the Calendar field part of calendar to calculate * @param unit the time unit * @return number of units within the fragment of the calendar * @throws IllegalArgumentException if the date is {@code null} or * fragment is not supported */ @SuppressFBWarnings("SF_SWITCH_FALLTHROUGH") private static long getFragment(final Calendar calendar, final int fragment, final TimeUnit unit) { N.checkArgNotNull(calendar, cs.calendar); long result = 0; final int offset = (unit == TimeUnit.DAYS) ? 0 : 1; // Fragments bigger than a day require a breakdown to days switch (fragment) { case Calendar.YEAR: result += unit.convert(calendar.get(Calendar.DAY_OF_YEAR) - offset, TimeUnit.DAYS); //NOSONAR break; case Calendar.MONTH: result += unit.convert(calendar.get(Calendar.DAY_OF_MONTH) - offset, TimeUnit.DAYS); //NOSONAR break; default: break; } switch (fragment) { // Number of days already calculated for these cases case Calendar.YEAR: case Calendar.MONTH: // The rest of the valid cases case Calendar.DAY_OF_YEAR: case Calendar.DATE: result += unit.convert(calendar.get(Calendar.HOUR_OF_DAY), TimeUnit.HOURS); //$FALL-THROUGH$ case Calendar.HOUR_OF_DAY: result += unit.convert(calendar.get(Calendar.MINUTE), TimeUnit.MINUTES); //$FALL-THROUGH$ case Calendar.MINUTE: result += unit.convert(calendar.get(Calendar.SECOND), TimeUnit.SECONDS); //$FALL-THROUGH$ case Calendar.SECOND: result += unit.convert(calendar.get(Calendar.MILLISECOND), TimeUnit.MILLISECONDS); break; case Calendar.MILLISECOND: break; //never useful default: throw new IllegalArgumentException("The fragment " + fragment + " is not supported"); } return result; } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Checks if two date objects are on the same day ignoring time.

* *

28 Mar 2002 13:45 and 28 Mar 2002 06:01 would return {@code true}. * 28 Mar 2002 13:45 and 12 Mar 2002 13:45 would return {@code false}. *

* * @param date1 the first date, not altered, not null * @param date2 the second date, not altered, not null * @return {@code true} if they represent the same day * @throws IllegalArgumentException if either date is {@code null} */ public static boolean isSameDay(final java.util.Date date1, final java.util.Date date2) throws IllegalArgumentException { N.checkArgNotNull(date1, cs.date1); N.checkArgNotNull(date2, cs.date2); final Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); final Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); return isSameDay(cal1, cal2); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Checks if two calendar objects are on the same day ignoring time.

* *

28 Mar 2002 13:45 and 28 Mar 2002 06:01 would return {@code true}. * 28 Mar 2002 13:45 and 12 Mar 2002 13:45 would return {@code false}. *

* * @param cal1 the first calendar, not altered, not null * @param cal2 the second calendar, not altered, not null * @return {@code true} if they represent the same day * @throws IllegalArgumentException if either calendar is {@code null} */ public static boolean isSameDay(final Calendar cal1, final Calendar cal2) throws IllegalArgumentException { N.checkArgNotNull(cal1, cs.calendar1); N.checkArgNotNull(cal2, cs.calendar2); return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR); } /** * Checks if two date objects are in the same month ignoring day and time. * * @param date1 The first date to compare. Must not be {@code null}. * @param date2 The second date to compare. Must not be {@code null}. * @return {@code true} if the two dates are in the same month of the same year. * @throws IllegalArgumentException if either date is {@code null}. */ public static boolean isSameMonth(final java.util.Date date1, final java.util.Date date2) throws IllegalArgumentException { N.checkArgNotNull(date1, cs.date1); N.checkArgNotNull(date2, cs.date2); final Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); final Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); return isSameMonth(cal1, cal2); } /** * Checks if two calendar objects are in the same month ignoring day and time. * * @param cal1 The first calendar to compare. Must not be {@code null}. * @param cal2 The second calendar to compare. Must not be {@code null}. * @return {@code true} if the two calendars are in the same month of the same year. * @throws IllegalArgumentException if either calendar is {@code null}. */ public static boolean isSameMonth(final Calendar cal1, final Calendar cal2) throws IllegalArgumentException { N.checkArgNotNull(cal1, cs.calendar1); N.checkArgNotNull(cal2, cs.calendar2); return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH); } /** * Checks if two date objects are in the same year ignoring month, day and time. * * @param date1 The first date to compare. Must not be {@code null}. * @param date2 The second date to compare. Must not be {@code null}. * @return {@code true} if the two dates are in the same year. * @throws IllegalArgumentException if either date is {@code null}. */ public static boolean isSameYear(final java.util.Date date1, final java.util.Date date2) throws IllegalArgumentException { N.checkArgNotNull(date1, cs.date1); N.checkArgNotNull(date2, cs.date2); final Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); final Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); return isSameYear(cal1, cal2); } /** * Checks if two calendar objects are in the same year ignoring month, day and time. * * @param cal1 The first calendar to compare. Must not be {@code null}. * @param cal2 The second calendar to compare. Must not be {@code null}. * @return {@code true} if the two calendars are in the same year. * @throws IllegalArgumentException if either calendar is {@code null}. */ public static boolean isSameYear(final Calendar cal1, final Calendar cal2) throws IllegalArgumentException { N.checkArgNotNull(cal1, cs.calendar1); N.checkArgNotNull(cal2, cs.calendar2); return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Checks if two date objects represent the same instant in time.

* *

This method compares the long millisecond time of the two objects.

* * @param date1 the first date, not altered, not null * @param date2 the second date, not altered, not null * @return {@code true} if they represent the same millisecond instant * @throws IllegalArgumentException if either date is {@code null} */ public static boolean isSameInstant(final java.util.Date date1, final java.util.Date date2) throws IllegalArgumentException { N.checkArgNotNull(date1, cs.date1); N.checkArgNotNull(date2, cs.date2); return date1.getTime() == date2.getTime(); } /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Checks if two calendar objects represent the same instant in time.

* *

This method compares the long millisecond time of the two objects.

* * @param cal1 the first calendar, not altered, not null * @param cal2 the second calendar, not altered, not null * @return {@code true} if they represent the same millisecond instant * @throws IllegalArgumentException if either date is {@code null} */ public static boolean isSameInstant(final Calendar cal1, final Calendar cal2) throws IllegalArgumentException { N.checkArgNotNull(cal1, cs.calendar1); N.checkArgNotNull(cal2, cs.calendar2); return cal1.getTime().getTime() == cal2.getTime().getTime(); } //----------------------------------------------------------------------- /** * Copied from Apache Commons Lang under Apache License v2. *
* *

Checks if two calendar objects represent the same local time.

* *

This method compares the values of the fields of the two objects. * In addition, both calendars must be the same of the same type.

* * @param cal1 the first calendar, not altered, not null * @param cal2 the second calendar, not altered, not null * @return {@code true} if they represent the same millisecond instant * @throws IllegalArgumentException if either date is {@code null} */ public static boolean isSameLocalTime(final Calendar cal1, final Calendar cal2) throws IllegalArgumentException { N.checkArgNotNull(cal1, cs.calendar1); N.checkArgNotNull(cal2, cs.calendar2); return cal1.get(Calendar.MILLISECOND) == cal2.get(Calendar.MILLISECOND) && cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND) && cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE) && cal1.get(Calendar.HOUR_OF_DAY) == cal2.get(Calendar.HOUR_OF_DAY) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.getClass() == cal2.getClass(); } private static DateFormat getSDF(final String format, final TimeZone timeZone) { DateFormat sdf = null; if (timeZone == UTC_TIME_ZONE) { //noinspection ConditionCoveredByFurtherCondition if ((format.length() == 28) && format.equals(ISO_8601_TIMESTAMP_FORMAT)) { sdf = utcTimestampDFPool.poll(); if (sdf == null) { sdf = new SimpleDateFormat(format); sdf.setTimeZone(timeZone); } return sdf; } else //noinspection ConditionCoveredByFurtherCondition if ((format.length() == 24) && format.equals(ISO_8601_DATE_TIME_FORMAT)) { sdf = utcDateTimeDFPool.poll(); if (sdf == null) { sdf = new SimpleDateFormat(format); sdf.setTimeZone(timeZone); } return sdf; } } Queue queue = dfPool.get(format); if (queue == null) { queue = new ArrayBlockingQueue<>(POOL_SIZE); dfPool.put(format, queue); } sdf = queue.poll(); if (sdf == null) { sdf = new SimpleDateFormat(format); } sdf.setTimeZone(timeZone); return sdf; } private static void recycleSDF(final String format, final TimeZone timeZone, final DateFormat sdf) { if (timeZone == UTC_TIME_ZONE) { //noinspection ConditionCoveredByFurtherCondition if ((format.length() == 28) && format.equals(ISO_8601_TIMESTAMP_FORMAT)) { utcTimestampDFPool.add(sdf); } else //noinspection ConditionCoveredByFurtherCondition if ((format.length() == 24) && format.equals(ISO_8601_DATE_TIME_FORMAT)) { utcDateTimeDFPool.add(sdf); } else { dfPool.get(format).add(sdf); } } else { dfPool.get(format).add(sdf); } } private static String checkDateFormat(final String str, final String format) { if (Strings.isEmpty(format)) { final int len = str.length(); if (len == 4) { return LOCAL_YEAR_FORMAT; } else if (len == 5 || str.charAt(2) == '-') { return LOCAL_MONTH_DAY_FORMAT; } else if (len > 4 && str.charAt(4) == '-') { switch (len) { case 8: return LOCAL_TIME_FORMAT; case 10: return LOCAL_DATE_FORMAT; case 19: if (str.charAt(10) == 'T') { return ISO_LOCAL_DATE_TIME_FORMAT; } else { return LOCAL_DATE_TIME_FORMAT; } case 20: if (str.charAt(19) == 'Z') { return ISO_8601_DATE_TIME_FORMAT; } break; case 24: if (str.charAt(23) == 'Z') { return ISO_8601_TIMESTAMP_FORMAT; } break; case 25: final char ch = str.charAt(19); if (ch == '-' || ch == '+') { return ISO_OFFSET_DATE_TIME_FORMAT; } break; default: // throw new RuntimeException("No valid date format found for: " + str); return null; } } else if (len == 29 || str.charAt(3) == ',') { return RFC_1123_DATE_TIME_FORMAT; } } return format; } private static TimeZone checkTimeZone(final String dateTime, final String format, final TimeZone timeZone) { if ((Strings.isNotEmpty(dateTime) && dateTime.endsWith("Z")) || (Strings.isNotEmpty(format) && format.endsWith("'Z'"))) { return UTC_TIME_ZONE; } return timeZone == null ? DEFAULT_TIME_ZONE : timeZone; } private static long fastDateParse(final String str, final String format, final TimeZone timeZone) { final int len = str.length(); if (!((len == 19) || (len == 20) || (len == 24)) || !(format.equals(ISO_8601_TIMESTAMP_FORMAT) || format.equals(ISO_8601_DATE_TIME_FORMAT) || format.equals(ISO_LOCAL_DATE_TIME_FORMAT) || format.equals(LOCAL_DATE_TIME_FORMAT))) { return 0; } // // if (!((str.charAt(4) == '-') && (str.charAt(7) == '-') && // (str.charAt(10) == 'T') && (str.charAt(13) == ':') && (str.charAt(16) // == ':') && (str // .charAt(str.length() - 1) == 'Z'))) { // return 0; // } // // int year = Integer.valueOf(str.substring(0, 4)); // int month = Integer.valueOf(str.substring(5, 7)) - 1; // int date = Integer.valueOf(str.substring(8, 10)); // int hourOfDay = Integer.valueOf(str.substring(11, 13)); // int minute = Integer.valueOf(str.substring(14, 16)); // int second = Integer.valueOf(str.substring(17, 19)); // int milliSecond = (str.length() == 24) ? // Integer.valueOf(str.substring(20, 23)) : 0; // // final int year = parseInt(str, 0, 4); final int month = parseInt(str, 5, 7) - 1; final int date = parseInt(str, 8, 10); final int hourOfDay = parseInt(str, 11, 13); final int minute = parseInt(str, 14, 16); final int second = parseInt(str, 17, 19); final int milliSecond = len == 24 ? parseInt(str, 20, 23) : 0; Calendar c = null; Queue timeZoneCalendarQueue = null; if (timeZone == UTC_TIME_ZONE) { c = utcCalendarPool.poll(); } else { timeZoneCalendarQueue = calendarPool.get(timeZone); if (timeZoneCalendarQueue == null) { timeZoneCalendarQueue = new ArrayBlockingQueue<>(POOL_SIZE); calendarPool.put(timeZone, timeZoneCalendarQueue); } else { c = timeZoneCalendarQueue.poll(); } } if (c == null) { c = Calendar.getInstance(timeZone); } //noinspection MagicConstant c.set(year, month, date, hourOfDay, minute, second); c.set(Calendar.MILLISECOND, milliSecond); final long timeInMillis = c.getTimeInMillis(); if (timeZone == UTC_TIME_ZONE) { utcCalendarPool.add(c); } else { timeZoneCalendarQueue.add(c); } return timeInMillis; } private static int parseInt(final String str, int fromIndex, final int toIndex) { int result = 0; while (fromIndex < toIndex) { result = (result * 10) + (str.charAt(fromIndex++) - 48); } return result; } private static T createDate(final long millis, final Class cls) { final LongFunction creator = dateCreatorPool.get(cls); if (creator != null) { return (T) creator.apply(millis); } else { return (T) ClassUtil.invokeConstructor(ClassUtil.getDeclaredConstructor(cls, long.class), millis); } } private static T createCalendar(final T source, final long millis) { final Class cls = (Class) source.getClass(); final BiFunction creator = calendarCreatorPool.get(cls); if (creator != null) { return (T) creator.apply(millis, source); } else { T result = null; Constructor constructor = ClassUtil.getDeclaredConstructor(cls, long.class); if (constructor != null && Modifier.isPublic(constructor.getModifiers())) { result = ClassUtil.invokeConstructor(constructor, millis); } else { constructor = ClassUtil.getDeclaredConstructor(cls); result = ClassUtil.invokeConstructor(constructor); result.setTimeInMillis(millis); } if (!N.equals(source.getTimeZone(), result.getTimeZone())) { result.setTimeZone(source.getTimeZone()); } return result; } } private enum ModifyType { /** * Truncation. */ TRUNCATE, /** * Rounding. */ ROUND, /** * Ceiling. */ CEILING } /** * Checks if the provided date is the last date of its month. * * @param date The date to check. Must not be {@code null}. * @return {@code true} if the provided date is the last date of its month. * @throws IllegalArgumentException if the date is {@code null}. */ public static boolean isLastDateOfMonth(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.get(Calendar.DAY_OF_MONTH) == cal.getActualMaximum(Calendar.DAY_OF_MONTH); } /** * Checks if the provided date is the last date of its year. * * @param date The date to check. Must not be {@code null}. * @return {@code true} if the provided date is the last date of its year. * @throws IllegalArgumentException if the date is {@code null}. */ public static boolean isLastDateOfYear(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.get(Calendar.DAY_OF_YEAR) == cal.getActualMaximum(Calendar.DAY_OF_YEAR); } /** * Returns the last day of the month for the given date. * * @param date The date to be evaluated. Must not be {@code null}. * @return The last day of the month for the given date as an integer. * @throws IllegalArgumentException if the date is {@code null}. */ public static int getLastDateOfMonth(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.getActualMaximum(Calendar.DAY_OF_MONTH); } /** * Returns the last day of the year for the given date. * * @param date The date to be evaluated. Must not be {@code null}. * @return The last day of the year for the given date as an integer. * @throws IllegalArgumentException if the date is {@code null}. */ public static int getLastDateOfYear(final java.util.Date date) throws IllegalArgumentException { N.checkArgNotNull(date, cs.date); final Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.getActualMaximum(Calendar.DAY_OF_YEAR); } /** * Checks if two date ranges overlap. * * @param startTimeOne Start time of the first range. Must not be {@code null}. * @param endTimeOne End time of the first range. Must not be {@code null}. * @param startTimeTwo Start time of the second range. Must not be {@code null}. * @param endTimeTwo End time of the second range. Must not be {@code null}. * @return {@code true} if the two date ranges overlap. * @throws IllegalArgumentException if any date is {@code null} or invalid. */ public static boolean isOverlap(java.util.Date startTimeOne, java.util.Date endTimeOne, java.util.Date startTimeTwo, java.util.Date endTimeTwo) { if (startTimeOne == null || endTimeOne == null || startTimeTwo == null || endTimeTwo == null) { throw new IllegalArgumentException("Date cannot be null"); } if (startTimeOne.after(endTimeOne) || startTimeTwo.after(endTimeTwo)) { throw new IllegalArgumentException("Start date must be before end date"); } return startTimeOne.before(endTimeTwo) && startTimeTwo.before(endTimeOne); } /** * Checks if the given date is between the specified start date and end date, inclusive. * It means {@code startDate <= date <= endDate}. * * @param date The date to check. Must not be {@code null}. * @param startDate The start time of the range. Must not be {@code null}. * @param endDate The end time of the range. Must not be {@code null}. * @return {@code true} if the date is within the specified range. * @throws IllegalArgumentException if any date is {@code null} or invalid. * @see N#geAndLe(Comparable, Comparable, Comparable) * @see N#gtAndLt(Comparable, Comparable, Comparable) */ @Beta public static boolean isBetween(java.util.Date date, java.util.Date startDate, java.util.Date endDate) { if (date == null || startDate == null || endDate == null) { throw new IllegalArgumentException("Date cannot be null"); } if (startDate.after(endDate)) { throw new IllegalArgumentException("Start date must be before end date"); } return N.geAndLe(date, startDate, endDate); } static void formatToForNull(final Appendable appendable) { try { appendable.append(Strings.NULL); } catch (IOException e) { throw new UncheckedIOException(e); } } // /** // * The Class Times. // */ // @Beta // public static final class Times extends DateUtil { // // private Times() { // // singleton. // } // } /** * The major purpose of this class is to get rid of the millisecond part: {@code .SSS} or nanosecond part: {@code .SSSSSS} * * @see {@code DateTimeFormatter} */ public static final class DTF { /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ssXXX'['VV']'} * @see {@link DateTimeFormatter#ISO_ZONED_DATE_TIME} */ static final String ISO_ZONED_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX'['VV']'"; // /** // * Date/Time format: {@code yyyy} // * @see {@link #LOCAL_YEAR_FORMAT} // */ // public static final DTF LOCAL_YEAR = new DTF(DateUtil.LOCAL_YEAR_FORMAT); // // /** // * Date/Time format: {@code MM-dd} // * @see {@link #LOCAL_MONTH_DAY_FORMAT} // */ // public static final DTF LOCAL_MONTH_DAY = new DTF(DateUtil.LOCAL_MONTH_DAY_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd} * @see {@link #LOCAL_DATE_FORMAT} */ public static final DTF LOCAL_DATE = new DTF(Dates.LOCAL_DATE_FORMAT); /** * Date/Time format: {@code HH:mm:ss} * @see {@link #LOCAL_TIME_FORMAT} */ public static final DTF LOCAL_TIME = new DTF(Dates.LOCAL_TIME_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd HH:mm:ss} * @see {@link #LOCAL_DATE_TIME_FORMAT} */ public static final DTF LOCAL_DATE_TIME = new DTF(Dates.LOCAL_DATE_TIME_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ss} * @see {@link #ISO_LOCAL_DATE_TIME_FORMAT} */ public static final DTF ISO_LOCAL_DATE_TIME = new DTF(Dates.ISO_LOCAL_DATE_TIME_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ssXXX} * @see {@link #ISO_OFFSET_DATE_TIME_FORMAT} */ public static final DTF ISO_OFFSET_DATE_TIME = new DTF(Dates.ISO_OFFSET_DATE_TIME_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ssXXX'['VV']'} * @see {@link #ISO_ZONED_DATE_TIME_FORMAT} */ public static final DTF ISO_ZONED_DATE_TIME = new DTF(ISO_ZONED_DATE_TIME_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ss'Z'}. * @see {@link #ISO_8601_DATE_TIME_FORMAT} */ public static final DTF ISO_8601_DATE_TIME = new DTF(Dates.ISO_8601_DATE_TIME_FORMAT); /** * Date/Time format: {@code yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}. * @see {@link #ISO_8601_TIMESTAMP_FORMAT} */ public static final DTF ISO_8601_TIMESTAMP = new DTF(Dates.ISO_8601_TIMESTAMP_FORMAT); /** * Date/Time format: {@code EEE, dd MMM yyyy HH:mm:ss zzz}. * @see {@link #RFC_1123_DATE_TIME_FORMAT} */ public static final DTF RFC_1123_DATE_TIME = new DTF(Dates.RFC_1123_DATE_TIME_FORMAT); private final String format; private final DateTimeFormatter dateTimeFormatter; DTF(final String format) { this.format = format; dateTimeFormatter = DateTimeFormatter.ofPattern(format); } // DTF(final DateTimeFormatter dtf) { // this.format = dtf.toString(); // this.dtf = dtf; // } // // public static DTF of(DateTimeFormatter dtf) { // return new DTF(dtf); // } // DTF(final DateTimeFormatter dtf) { // this.format = dtf.toString(); // this.dtf = dtf; // } // // public static DTF of(DateTimeFormatter dtf) { // return new DTF(dtf); // } /** * Formats the provided java.util.Date instance into a string representation. * * @param date The java.util.Date instance to format. * @return A string representation of the provided java.util.Date instance. * @throws DateTimeException if an error occurs during formatting. * @see {@link DateTimeFormatter#format(TemporalAccessor)} */ @MayReturnNull public String format(final java.util.Date date) { if (date == null) { return null; } return Dates.format(date, format); } /** * Formats the provided java.util.Calendar instance into a string representation. * * @param calenar The java.util.Calendar instance to format. * @return A string representation of the provided java.util.Calendar instance. * @throws DateTimeException if an error occurs during formatting. * @see {@link DateTimeFormatter#format(TemporalAccessor)} */ @MayReturnNull public String format(final java.util.Calendar calenar) { if (calenar == null) { return null; } return Dates.format(calenar, format); } /** * Formats the provided TemporalAccessor instance into a string representation. * * @param temporal The TemporalAccessor instance to format. * @return A string representation of the provided TemporalAccessor instance. * @throws DateTimeException if an error occurs during formatting. * @see {@link DateTimeFormatter#format(TemporalAccessor)} */ @MayReturnNull public String format(final TemporalAccessor temporal) { if (temporal == null) { return null; } return dateTimeFormatter.format(temporal); } /** * Formats the provided java.util.Date instance into a string representation and appends it to the provided Appendable. * * @param date The java.util.Date instance to format. * @param appendable The Appendable to which the formatted string will be appended. * @throws DateTimeException if an error occurs during formatting. * @see {@link DateTimeFormatter#formatTo(TemporalAccessor, Appendable)} */ @MayReturnNull public void formatTo(final java.util.Date date, final Appendable appendable) { if (date == null) { formatToForNull(appendable); return; } Dates.formatTo(date, format, appendable); } /** * Formats the provided java.util.Calendar instance into a string representation and appends it to the provided Appendable. * * @param calendar The java.util.Calendar instance to format. * @param appendable The Appendable to which the formatted string will be appended. * @throws DateTimeException if an error occurs during formatting. * @see {@link DateTimeFormatter#formatTo(TemporalAccessor, Appendable)} */ @MayReturnNull public void formatTo(final java.util.Calendar calendar, final Appendable appendable) { if (calendar == null) { formatToForNull(appendable); return; } Dates.formatTo(calendar, format, appendable); } /** * Formats the provided TemporalAccessor instance into a string representation and appends it to the provided Appendable. * * @param temporal The TemporalAccessor instance to format. * @param appendable The Appendable to which the formatted string will be appended. * @throws DateTimeException if an error occurs during formatting. * @see {@link DateTimeFormatter#formatTo(TemporalAccessor, Appendable)} */ @MayReturnNull public void formatTo(final TemporalAccessor temporal, final Appendable appendable) { if (temporal == null) { formatToForNull(appendable); return; } dateTimeFormatter.formatTo(temporal, appendable); } /** * Parses the provided CharSequence into a LocalDate instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A LocalDate instance representing the parsed date. * @throws DateTimeParseException if the text cannot be parsed to a date. * @see Instant#ofEpochMilli(long) * @see LocalDate#ofInstant(Instant, ZoneId) * @see LocalDate#from(TemporalAccessor) */ @MayReturnNull public LocalDate parseToLocalDate(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } if (isPossibleLong(text)) { try { return LocalDate.ofInstant(Instant.ofEpochMilli(Numbers.toLong(text)), DEFAULT_ZONE_ID); } catch (final NumberFormatException e) { // ignore; if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, text); } } } return LocalDate.from(parse(text)); } /** * Parses the provided CharSequence into a LocalTime instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A LocalTime instance representing the parsed time. * @throws DateTimeParseException if the text cannot be parsed to a time. * @see Instant#ofEpochMilli(long) * @see LocalTime#ofInstant(Instant, ZoneId) * @see LocalTime#from(TemporalAccessor) */ @MayReturnNull public LocalTime parseToLocalTime(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } if (isPossibleLong(text)) { try { return LocalTime.ofInstant(Instant.ofEpochMilli(Numbers.toLong(text)), DEFAULT_ZONE_ID); } catch (final NumberFormatException e) { // ignore; if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, text); } } } return LocalTime.from(parse(text)); } /** * Parses the provided CharSequence into a LocalDateTime instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A LocalDateTime instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see LocalDateTime#ofInstant(Instant, ZoneId) * @see LocalDateTime#from(TemporalAccessor) */ @MayReturnNull public LocalDateTime parseToLocalDateTime(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } if (isPossibleLong(text)) { try { return LocalDateTime.ofInstant(Instant.ofEpochMilli(Numbers.toLong(text)), DEFAULT_ZONE_ID); } catch (final NumberFormatException e) { // ignore; if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, text); } } } return LocalDateTime.from(parse(text)); } /** * Parses the provided CharSequence into an OffsetDateTime instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return An OffsetDateTime instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see OffsetDateTime#ofInstant(Instant, ZoneId) * @see OffsetDateTime#from(TemporalAccessor */ @MayReturnNull public OffsetDateTime parseToOffsetDateTime(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } if (isPossibleLong(text)) { try { return OffsetDateTime.ofInstant(Instant.ofEpochMilli(Numbers.toLong(text)), DEFAULT_ZONE_ID); } catch (final NumberFormatException e) { // ignore; if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, text); } } } return OffsetDateTime.from(parse(text)); } /** * Parses the provided CharSequence into a ZonedDateTime instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A ZonedDateTime instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see OffsetDateTime#ofInstant(Instant, ZoneId) * @see OffsetDateTime#from(TemporalAccessor) */ @MayReturnNull public ZonedDateTime parseToZonedDateTime(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } if (isPossibleLong(text)) { try { return ZonedDateTime.ofInstant(Instant.ofEpochMilli(Numbers.toLong(text)), DEFAULT_ZONE_ID); } catch (final NumberFormatException e) { // ignore; if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, text); } } } return ZonedDateTime.from(parse(text)); } /** * Parses the provided CharSequence into an Instant instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return An Instant instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see Instant#from(TemporalAccessor) */ @MayReturnNull public Instant parseToInstant(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } if (isPossibleLong(text)) { try { return Instant.ofEpochMilli(Numbers.toLong(text)); } catch (final NumberFormatException e) { // ignore; if (logger.isWarnEnabled()) { logger.warn(FAILED_TO_PARSE_TO_LONG, text); } } } return Instant.from(parse(text)); } /** * Parses the provided CharSequence into a java.util.Date instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.util.Date instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.util.Date#from(Instant) */ @MayReturnNull public java.util.Date parseToJUDate(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } return Dates.parseJUDate(text.toString(), format); } /** * Parses the provided CharSequence into a java.util.Date instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.util.Date instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.util.Date#from(Instant) */ @MayReturnNull public java.util.Date parseToJUDate(final CharSequence text, final TimeZone tz) { if (Strings.isEmpty(text)) { return null; } return Dates.parseJUDate(text.toString(), format, tz); } /** * Parses the provided CharSequence into a java.sql.Date instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.sql.Date instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.sql.Date#from(Instant) */ @MayReturnNull public java.sql.Date parseToDate(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } return Dates.parseDate(text.toString(), format); } /** * Parses the provided CharSequence into a java.sql.Date instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.sql.Date instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.sql.Date#from(Instant) */ @MayReturnNull public java.sql.Date parseToDate(final CharSequence text, final TimeZone tz) { if (Strings.isEmpty(text)) { return null; } return Dates.parseDate(text.toString(), format, tz); } /** * Parses the provided CharSequence into a java.sql.Time instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.sql.Time instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.sql.Time#from(Instant) */ @MayReturnNull public Time parseToTime(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } return Dates.parseTime(text.toString(), format); } /** * Parses the provided CharSequence into a java.sql.Time instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.sql.Time instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.sql.Time#from(Instant) */ @MayReturnNull public Time parseToTime(final CharSequence text, final TimeZone tz) { if (Strings.isEmpty(text)) { return null; } return Dates.parseTime(text.toString(), format, tz); } /** * Parses the provided CharSequence into a java.sql.Timestamp instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.sql.Timestamp instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.sql.Timestamp#from(Instant) */ @MayReturnNull public Timestamp parseToTimestamp(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } return Dates.parseTimestamp(text.toString(), format); } /** * Parses the provided CharSequence into a java.sql.Timestamp instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.sql.Timestamp instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. * @see Instant#ofEpochMilli(long) * @see java.sql.Timestamp#from(Instant) */ @MayReturnNull public Timestamp parseToTimestamp(final CharSequence text, final TimeZone tz) { if (Strings.isEmpty(text)) { return null; } return Dates.parseTimestamp(text.toString(), format, tz); } /** * Parses the provided CharSequence into a java.util.Calendar instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.util.Calendar instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. */ @MayReturnNull public Calendar parseToCalendar(final CharSequence text) { if (Strings.isEmpty(text)) { return null; } return Dates.parseCalendar(text.toString(), format); } /** * Parses the provided CharSequence into a java.util.Calendar instance. * * @param text The CharSequence to parse. Must not be {@code null}. * @return A java.util.Calendar instance representing the parsed date and time. * @throws DateTimeParseException if the text cannot be parsed to a date and time. */ @MayReturnNull public Calendar parseToCalendar(final CharSequence text, final TimeZone tz) { if (Strings.isEmpty(text)) { return null; } return Dates.parseCalendar(text.toString(), format, tz); } private TemporalAccessor parse(final CharSequence text) { final int len = text.length(); char ch = 0; if (len > 25 && text.charAt(len - 1) == ']') { return ISO_ZONED_DATE_TIME.dateTimeFormatter.parse(text); } else if (len >= 25 && ((ch = text.charAt(len - 5)) == '+' || ch == '-')) { return ISO_OFFSET_DATE_TIME.dateTimeFormatter.parse(text); } else if (len == 19) { if (text.charAt(10) == 'T') { return ISO_LOCAL_DATE_TIME.dateTimeFormatter.parse(text); } else { return LOCAL_DATE_TIME.dateTimeFormatter.parse(text); } } else if (len == 20 && text.charAt(19) == 'Z') { return ISO_8601_DATE_TIME.dateTimeFormatter.parse(text); } else if (len == 24 && text.charAt(23) == 'Z') { return ISO_8601_TIMESTAMP.dateTimeFormatter.parse(text); } else if (len == 29 && text.charAt(3) == ',') { return RFC_1123_DATE_TIME.dateTimeFormatter.parse(text); } return dateTimeFormatter.parse(text); } /** * Returns a string representation of the DTF object. * * @return A string that represents the format of the DTF object. */ @Override public String toString() { return format; } } /** * The Class DateUtil. */ @Beta public static final class DateUtil extends Dates { private DateUtil() { // singleton. } } // /** // * The Class DateTimeUtil. // */ // @Beta // public static final class DateTimeUtil extends Dates { // // private DateTimeUtil() { // // singleton. // } // } // /** // * The Class Times. // */ // @Beta // public static final class Times extends DateUtil { // // private Times() { // // singleton. // } // } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy