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

com.moon.core.time.DateTimeUtil Maven / Gradle / Ivy

package com.moon.core.time;

import com.moon.core.enums.Const;
import com.moon.core.lang.IntUtil;
import com.moon.core.lang.StringUtil;
import com.moon.core.lang.ParseSupportUtil;
import com.moon.core.util.function.TableIntConsumer;
import com.moon.core.util.function.TableIntFunction;
import com.moon.core.util.validator.ResidentID18Validator;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.WeekFields;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

import static com.moon.core.lang.ThrowUtil.noInstanceError;
import static java.time.LocalDateTime.ofInstant;

/**
 * JDK 8 time 工具类
 * 

* 有些从方法定义对方法的作用一目了然的方法不再添加注释 * * @author moonsky */ public final class DateTimeUtil { private DateTimeUtil() { noInstanceError(); } /** * 当前时间时间戳毫秒数 * * @return 时间戳 */ public static long now() { return System.currentTimeMillis(); } /** * 获取当前日期 * * @return 当前日期 LocalDate */ public static LocalDate nowDate() { return LocalDate.now(); } /** * 获取当前时间 * * @return 当前时间 LocalTime */ public static LocalTime nowTime() { return LocalTime.now(); } /** * 获取当前时间 * * @return 当前日期时间 LocalDateTime */ public static LocalDateTime nowDateTime() { return LocalDateTime.now(); } /** * 默认当前时间,如果指定时间为 null 的话 * * @param date 指定时间 * * @return 如果指定时间为 null 就返回当前时间,否则返回字段时间 */ public static LocalTime nowIfNull(LocalTime date) { return (date == null ? nowTime() : date); } /** * 默认当前时间,如果指定时间为 null 的话 * * @param date 指定时间 * * @return 如果字段时间不为 null 就返回指定时间,否则返回当前时间 */ public static LocalDate nowIfNull(LocalDate date) { return (date == null ? nowDate() : date); } /** * 默认当前时间,如果指定时间为 null 的话 * * @param date 指定时间 * * @return 如果字段时间不为 null 就返回指定时间,否则返回当前时间 */ public static LocalDateTime nowIfNull(LocalDateTime date) { return (date == null ? nowDateTime() : date); } /** * date1、date2 是否是同一年份 * * @param date1 date1 * @param date2 date2 * * @return date1、date2 是同一年份时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isYearEquals(LocalDate date1, LocalDate date2) { return date1.getYear() == date2.getYear(); } /** * date1 的年份是否在 date2 之前 * * @param date1 date1 * @param date2 date2 * * @return 当 date1 的年份在 date2 的年份之前时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isYearBefore(LocalDate date1, LocalDate date2) { return date1.getYear() < date2.getYear(); } /** * date1 的年份是否在 date2 之后 * * @param date1 date1 * @param date2 date2 * * @return 当 date1 的年份在 date2 的年份之后时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isYearAfter(LocalDate date1, LocalDate date2) { return date1.getYear() > date2.getYear(); } /** * date1、date2是否是同一月份 * * @param date1 date1 * @param date2 date2 * * @return date1、date2是同一月份时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isMonthEquals(LocalDate date1, LocalDate date2) { return (date1.getYear() == date2.getYear() && date1.getMonthValue() < date2.getMonthValue()); } /** * date1 的月份是否在 date2 之前 * * @param date1 date1 * @param date2 date2 * * @return 当 date1 的月份在 date2 的月份之前时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isMonthBefore(LocalDate date1, LocalDate date2) { int year1 = date1.getYear(), year2 = date2.getYear(); return year1 < year2 || (year1 == year2 && date1.getMonthValue() < date2.getMonthValue()); } /** * date1 的月份是否在 date2 之后 * * @param date1 date1 * @param date2 date2 * * @return 当 date1 的月份在 date2 的月份之后时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isMonthAfter(LocalDate date1, LocalDate date2) { int year1 = date1.getYear(), year2 = date2.getYear(); return year1 > year2 || (year1 == year2 && date1.getMonthValue() > date2.getMonthValue()); } /** * date1、date2是否是同一日期 * * @param date1 date1 * @param date2 date2 * * @return date1、date2是同一日期时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isDateEquals(LocalDate date1, LocalDate date2) { return (date1.getYear() == date2.getYear() && date1.getDayOfYear() < date2.getDayOfYear()); } /** * date1 的日期是否在 date2 之前 * * @param date1 date1 * @param date2 date2 * * @return 当 date1 的日期在 date2 的日期之前时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isDateBefore(LocalDate date1, LocalDate date2) { int year1 = date1.getYear(), year2 = date2.getYear(); return year1 < year2 || (year1 == year2 && date1.getDayOfYear() < date2.getDayOfYear()); } /** * date1 的日期是否在 date2 之后 * * @param date1 date1 * @param date2 date2 * * @return 当 date1 的日期在 date2 的日期之后时返回 true,否则返回 false * * @throws NullPointerException 当 date1 或 date2 为 null 时抛出异常 */ public static boolean isDateAfter(LocalDate date1, LocalDate date2) { int year1 = date1.getYear(), year2 = date2.getYear(); return year1 > year2 || (year1 == year2 && date1.getDayOfYear() > date2.getDayOfYear()); } /** * time1 的小时数是否与 time2 相同 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的小时数是否与 time2 相同时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isHourEquals(LocalTime time1, LocalTime time2) { return time1.getHour() == time2.getHour(); } /** * datetime1 的小时数是否与 datetime 相同 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的小时数是否与 datetime2 相同时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isHourEquals(LocalDateTime datetime1, LocalDateTime datetime2) { return isDateEquals(datetime1.toLocalDate(), datetime2.toLocalDate())// && isHourEquals(datetime1.toLocalTime(), datetime2.toLocalTime()); } /** * time1 的小时数是否在 time2 之前 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的小时数是否在 time2 之前时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isHourBefore(LocalTime time1, LocalTime time2) { return time1.getHour() < time2.getHour(); } /** * datetime1 的小时数是否在 datetime2 之前 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的小时数是否在 datetime2 之前时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isHourBefore(LocalDateTime datetime1, LocalDateTime datetime2) { return isDateBefore(datetime1.toLocalDate(), datetime2.toLocalDate())// || (isDateEquals(datetime1.toLocalDate(), datetime2.toLocalDate())// && isHourBefore(datetime1.toLocalTime(), datetime2.toLocalTime())); } /** * time1 的小时数是否在 time2 之后 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的小时数是否在 time2 之后时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isHourAfter(LocalTime time1, LocalTime time2) { return time1.getHour() > time2.getHour(); } /** * datetime1 的小时数是否在 datetime2 之后 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的小时数是否在 datetime2 之后时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isHourAfter(LocalDateTime datetime1, LocalDateTime datetime2) { return isDateAfter(datetime1.toLocalDate(), datetime2.toLocalDate())// || (isDateEquals(datetime1.toLocalDate(), datetime2.toLocalDate())// && isHourAfter(datetime1.toLocalTime(), datetime2.toLocalTime())); } /** * time1 的分钟数是否与 time2 相同 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的小时数是否与 time2 相同时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isMinuteEquals(LocalTime time1, LocalTime time2) { return (isHourEquals(time1, time2) && time1.getMinute() < time2.getMinute()); } /** * datetime1 的分钟数是否与 datetime2 相同 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的小时数是否与 datetime2 相同时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isMinuteEquals(LocalDateTime datetime1, LocalDateTime datetime2) { return (isHourEquals(datetime1, datetime2) && datetime1.getMinute() == datetime2.getMinute()); } /** * time1 的分钟数是否在 time2 之前 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的分钟数是否在 time2 之前时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isMinuteBefore(LocalTime time1, LocalTime time2) { int hour1 = time1.getHour(), hour2 = time2.getHour(); return hour1 < hour2 || (hour1 == hour2 && time1.getMinute() < time2.getMinute()); } /** * datetime1 的分钟数是否在 datetime2 之前 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的分钟数是否在 datetime2 之前时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isMinuteBefore(LocalDateTime datetime1, LocalDateTime datetime2) { return isHourBefore(datetime1, datetime2)// || (isHourEquals(datetime1, datetime2) && datetime1.getMinute() < datetime2.getMinute()); } /** * time1 的分钟数是否在 time2 之后 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的分钟数是否在 time2 之后时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isMinuteAfter(LocalTime time1, LocalTime time2) { int hour1 = time1.getHour(), hour2 = time2.getHour(); return hour1 > hour2 || (hour1 == hour2 && time1.getMinute() > time2.getMinute()); } /** * datetime1 的分钟数是否在 datetime2 之后 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的分钟数是否在 datetime2 之后时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isMinuteAfter(LocalDateTime datetime1, LocalDateTime datetime2) { return isHourBefore(datetime1, datetime2)// || (isHourEquals(datetime1, datetime2) && datetime1.getMinute() > datetime2.getMinute()); } /** * time1 的秒数是否与 time2 相同 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的小时数是否与 time2 相同时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ public static boolean isSecondEquals(LocalTime time1, LocalTime time2) { return (isMinuteEquals(time1, time2) && time1.getSecond() < time2.getSecond()); } /** * datetime1 的秒数是否与 datetime2 相同 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的小时数是否与 datetime2 相同时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ public static boolean isSecondEquals(LocalDateTime datetime1, LocalDateTime datetime2) { return isMinuteEquals(datetime1, datetime2) && datetime1.getSecond() == datetime2.getSecond(); } /** * time1 的秒数是否在 time2 之前 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的秒数是否在 time2 之前时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ @SuppressWarnings("all") public static boolean isSecondBefore(LocalTime time1, LocalTime time2) { int hour1 = time1.getHour(), hour2 = time2.getHour(); if (hour1 < hour2) { return true; } if (hour1 > hour2) { return false; } int minute1 = time1.getMinute(), minute2 = time2.getMinute(); return minute1 < minute2 || (minute1 == minute2 && time1.getSecond() < time2.getSecond()); } /** * datetime1 的秒数是否在 datetime2 之前 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的秒数是否在 datetime2 之前时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ @SuppressWarnings("all") public static boolean isSecondBefore(LocalDateTime datetime1, LocalDateTime datetime2) { return isMinuteBefore(datetime1, datetime2)// || (isMinuteEquals(datetime1, datetime2) && datetime1.getSecond() < datetime2.getSecond()); } /** * time1 的秒数是否在 time2 之后 * * @param time1 time1 * @param time2 time2 * * @return 当 time1 的秒数是否在 time2 之后时返回 true,否则返回 false * * @throws NullPointerException 当 time1 或 time2 为 null 时抛出异常 */ @SuppressWarnings("all") public static boolean isSecondAfter(LocalTime time1, LocalTime time2) { int hour1 = time1.getHour(), hour2 = time2.getHour(); if (hour1 > hour2) { return true; } if (hour1 < hour2) { return false; } int minute1 = time1.getMinute(), minute2 = time2.getMinute(); return minute1 > minute2 || (minute1 == minute2 && time1.getSecond() > time2.getSecond()); } /** * datetime1 的秒数是否在 datetime2 之后 * * @param datetime1 datetime1 * @param datetime2 datetime2 * * @return 当 datetime1 的秒数是否在 datetime2 之后时返回 true,否则返回 false * * @throws NullPointerException 当 datetime1 或 datetime2 为 null 时抛出异常 */ @SuppressWarnings("all") public static boolean isSecondAfter(LocalDateTime datetime1, LocalDateTime datetime2) { return isMinuteAfter(datetime1, datetime2)// || (isMinuteEquals(datetime1, datetime2) && datetime1.getSecond() > datetime2.getSecond()); } public final static boolean isBeforeMonthDay(LocalDate date, LocalDate date2) { return isBeforeMonthDay(date, date2.getMonthValue(), date2.getDayOfMonth()); } public final static boolean isBeforeMonthDay(LocalDate date, int month, int dayOfMonth) { int month1 = date.getMonthValue(); return month1 > month || (month1 == month && date.getDayOfMonth() > dayOfMonth); } public final static boolean isAfterMonthDay(LocalDate date, int month, int dayOfMonth) { int month1 = date.getMonthValue(); return month1 > month || (month1 == month && date.getDayOfMonth() > dayOfMonth); } /** * 获取一年的第几周 * * @param date 日期 * @param firstDayOfWeek 一周的第一天是星期几 * * @return 返回指定日期是对应当前年的第几周 * * @see LocalDateTime#toLocalDate() 转换 LocalDateTime 请先调用这个方法 */ public static int getWeekOfYear(LocalDate date, DayOfWeek firstDayOfWeek) { return date.get(WeekFields.of(firstDayOfWeek, 4).weekOfYear()); } /** * 获取一年的第几周,设一周的第一天是星期一 * * @param date 日期 * * @return 返回指定日期是对应当前年的第几周 * * @see LocalDateTime#toLocalDate() 转换 LocalDateTime 请先调用这个方法 */ public static int getWeekOfYearOnMonday(LocalDate date) { return getWeekOfYear(date, DayOfWeek.MONDAY); } /** * 获取一年的第几周,设一周的第一天是星期日 * * @param date 日期 * * @return 返回指定日期是对应当前年的第几周 * * @see LocalDateTime#toLocalDate() 转换 LocalDateTime 请先调用这个方法 */ public static int getWeekOfYearOnSunday(LocalDate date) { return getWeekOfYear(date, DayOfWeek.SUNDAY); } /** * 获取一月的第几周 * * @param date 日期 * @param firstDayOfWeek 一周的第一天是星期几 * * @return 返回指定日期是对应当前月份的第几周 * * @see LocalDateTime#toLocalDate() 转换 LocalDateTime 请先调用这个方法 */ public static int getWeekOfMonth(LocalDate date, DayOfWeek firstDayOfWeek) { return date.get(WeekFields.of(firstDayOfWeek, 4).weekOfMonth()); } /** * 获取一月的第几周,设一周的第一天是星期一 * * @param date 日期 * * @return 返回指定日期是对应当前月份的第几周 * * @see LocalDateTime#toLocalDate() 转换 LocalDateTime 请先调用这个方法 */ public static int getWeekOfMonthOnMonday(LocalDate date) { return getWeekOfMonth(date, DayOfWeek.MONDAY); } /** * 获取一月的第几周,设一周的第一天是星期日 * * @param date 日期 * * @return 返回指定日期是对应当前月份的第几周 * * @see LocalDateTime#toLocalDate() 转换 LocalDateTime 请先调用这个方法 */ public static int getWeekOfMonthOnSunday(LocalDate date) { return getWeekOfMonth(date, DayOfWeek.SUNDAY); } /** * 根据日期获取年龄(周岁) * * @param birthday 出生日期 * * @return 周岁 * * @see ResidentID18Validator#getAge() * @see LocalDateTime#toLocalDate() 不单独对 LocalDateTime 提供方法 */ public static int getAge(LocalDate birthday) { return getAge(birthday, LocalDate.now()); } /** * 返回生日到指定日期的周岁数 * * @param birthday 出生日期 * @param endDate 指定日期 * * @return 周岁 */ public static int getAge(LocalDate birthday, LocalDate endDate) { int age = endDate.getYear() - birthday.getYear(); return isBeforeMonthDay(birthday, endDate) ? age - 1 : age; } /** * 根据日期获取年龄(虚岁) * * @param date 日期 * * @return 虚岁 * * @see ResidentID18Validator#getNominalAge() * @see LocalDateTime#toLocalDate() 不单独对 LocalDateTime 提供方法 */ public static int getNominalAge(LocalDate date) { return getAge(date) + 1; } /* 始末时间 */ /** * 年初:当年第 0 纳秒时刻 * * @param date 指定日期 * * @return 指定日期所在年份的最初时刻 */ public static LocalDate startOfYear(LocalDate date) { return toDate(IntUtil.toInts(date.getYear())); } /** * 年初:当年第 0 纳秒时刻 * * @param datetime 指定日期时间 * * @return 指定日期所在年份的最初时刻 */ public static LocalDateTime startOfYear(LocalDateTime datetime) { return toDateTime(IntUtil.toInts(datetime.getYear())); } /** * 月初:当月第 0 纳秒时刻 * * @param date 指定日期 * * @return 指定日期所在月份的最初时刻 */ public static LocalDate startOfMonth(LocalDate date) { return toDate(date.getYear(), date.getMonthValue()); } /** * 月初:当月第 0 纳秒时刻 * * @param datetime 指定日期 * * @return 指定时间所在天的最初时刻 */ public static LocalDateTime startOfMonth(LocalDateTime datetime) { return toDateTime(datetime.getYear(), datetime.getMonthValue()); } /** * 周初:当前日期所在周的第一天 * * @param date 当前日期 * @param firstDayOfWeek 星期几为一周的第一天 * * @return 当前日期所在周的第一天 */ public static LocalDate startOfWeek(LocalDate date, DayOfWeek firstDayOfWeek) { int diffDays = date.getDayOfWeek().ordinal() - firstDayOfWeek.ordinal(); return date.minusDays(diffDays < 0 ? diffDays + 7 : diffDays); } /** * 周初:当前日期所在周的第 0 秒时刻 * * @param datetime 当前日期 * @param firstDayOfWeek 星期几为一周的第一天 * * @return 指定时间所在周的最初时刻 */ public static LocalDateTime startOfWeek(LocalDateTime datetime, DayOfWeek firstDayOfWeek) { int diffDays = datetime.getDayOfWeek().ordinal() - firstDayOfWeek.ordinal(); return startOfDay(datetime.minusDays(diffDays < 0 ? diffDays + 7 : diffDays)); } /** * 当天开始时间:当日第 0 纳秒时刻 * * @param datetime 指定日期 * * @return 指定时间所在天的最初时刻 */ public static LocalDateTime startOfDay(LocalDateTime datetime) { return toDateTime(datetime.getYear(), datetime.getMonth().getValue(), datetime.getDayOfMonth()); } /** * 当前小时第 0 纳秒时刻 * * @param time 指定日期 * * @return 指定时间所在小时的最初时刻 */ public static LocalTime startOfHour(LocalTime time) { return toTime(IntUtil.toInts(time.getHour())); } /** * 当前小时第 0 纳秒时刻 * * @param datetime 指定日期 * * @return 指定时间所在小时的最初时刻 */ public static LocalDateTime startOfHour(LocalDateTime datetime) { return LocalDateTime.of(datetime.toLocalDate(), startOfHour(datetime.toLocalTime())); } /** * 当前分钟第 0 纳秒时刻 * * @param datetime 指定日期 * * @return 指定时间所在分钟的最初时刻 */ public static LocalDateTime startOfMinute(LocalDateTime datetime) { return LocalDateTime.of(datetime.toLocalDate(), startOfMinute(datetime.toLocalTime())); } /** * 当前分钟第 0 纳秒时刻 * * @param time 指定时间 * * @return 指定时间所在分钟的最初时刻 */ public static LocalTime startOfMinute(LocalTime time) { return toTime(time.getHour(), time.getMinute()); } /** * 当前秒第 0 纳纳秒时刻 * * @param time 指定时间 * * @return 指定时间所在秒的最初时刻 */ public static LocalTime startOfSecond(LocalTime time) { return toTime(time.getHour(), time.getMinute(), time.getSecond()); } /** * 当前秒第 0 纳纳秒时刻 * * @param datetime 指定时间 * * @return 指定时间所在秒的最初时刻 */ public static LocalDateTime startOfSecond(LocalDateTime datetime) { return LocalDateTime.of(datetime.toLocalDate(), startOfSecond(datetime.toLocalTime())); } /** * 年末:当前年最后一纳秒时刻 * * @param date 指定日期 * * @return 指定日期所在年份的最后时刻 */ public static LocalDate endOfYear(LocalDate date) { return toDate(IntUtil.toInts(date.getYear() + 1)).minusDays(1); } /** * 年末:当前年最后一纳秒时刻 * * @param datetime 指定日期 * * @return 指定日期所在年份的最后时刻 */ public static LocalDateTime endOfYear(LocalDateTime datetime) { return toDateTime(IntUtil.toInts(datetime.getYear() + 1)).minusNanos(1); } /** * 月末:当前月最后一纳秒时刻 * * @param date 指定日期 * * @return 指定日期所在月份的最后时刻 */ public static LocalDate endOfMonth(LocalDate date) { return toDate(date.getYear(), date.getMonth().getValue()).plusMonths(1).minusDays(1); } /** * 月末:当前月最后一纳秒时刻 * * @param datetime 指定日期 * * @return 指定日期所在月份的最后时刻 */ public static LocalDateTime endOfMonth(LocalDateTime datetime) { return toDateTime(datetime.getYear(), datetime.getMonth().getValue()).plusMonths(1).minusNanos(1); } /** * 周初:当前日期所在周的最后一天 * * @param date 当前日期 * @param firstDayOfWeek 星期几为一周的第一天 * * @return 当前日期所在周的最后一天 */ public static LocalDate endOfWeek(LocalDate date, DayOfWeek firstDayOfWeek) { int diffDays = firstDayOfWeek.ordinal() - date.getDayOfWeek().ordinal(); return date.plusDays(diffDays <= 0 ? diffDays + 6 : diffDays - 1); } /** * 周初:当前日期所在周的最后一纳秒时刻 * * @param datetime 当前日期 * @param firstDayOfWeek 星期几为一周的第一天 * * @return 指定日期所在周的最后时刻 */ public static LocalDateTime endOfWeek(LocalDateTime datetime, DayOfWeek firstDayOfWeek) { int diffDays = firstDayOfWeek.ordinal() - datetime.getDayOfWeek().ordinal(); return endOfDay(datetime.plusDays(diffDays <= 0 ? diffDays + 6 : diffDays - 1)); } /** * 当日最后一纳秒时刻 * * @param datetime 指定日期 * * @return 指定日期所在天的最后时刻 */ public static LocalDateTime endOfDay(LocalDateTime datetime) { return toDateTime(datetime.getYear(), datetime.getMonth().getValue(), datetime.getDayOfMonth()).plusDays(1) .minusNanos(1); } /** * 当前小时最后一纳秒时刻 * * @param time 指定时间 * * @return 指定时间所在小时的最后时刻 */ public static LocalTime endOfHour(LocalTime time) { return toTime(IntUtil.toInts(time.getHour())).plusHours(1).minusNanos(1); } /** * 当前小时最后一纳秒时刻 * * @param datetime 指定时间 * * @return 指定时间所在小时的最后时刻 */ public static LocalDateTime endOfHour(LocalDateTime datetime) { return LocalDateTime.of(datetime.toLocalDate(), endOfHour(datetime.toLocalTime())); } /** * 当前分钟最后一纳秒时刻 * * @param time 指定时间 * * @return 指定时间所在分钟的最后时刻 */ public static LocalTime endOfMinute(LocalTime time) { return toTime(time.getHour(), time.getMinute()).plusMinutes(1).minusNanos(1); } /** * 当前分钟最后一纳秒时刻 * * @param datetime 指定时间 * * @return 指定时间所在分钟的最后时刻 */ public static LocalDateTime endOfMinute(LocalDateTime datetime) { return LocalDateTime.of(datetime.toLocalDate(), endOfMinute(datetime.toLocalTime())); } /** * 当前秒最后一纳秒时刻 * * @param time 指定时间 * * @return 指定时间所在秒的最后时刻 */ public static LocalTime endOfSecond(LocalTime time) { return toTime(time.getHour(), time.getMinute(), time.getSecond()).plusSeconds(1).minusNanos(1); } /** * 当前秒最后一纳秒时刻 * * @param datetime 指定时间 * * @return 指定时间所在秒的最后时刻 */ public static LocalDateTime endOfSecond(LocalDateTime datetime) { return LocalDateTime.of(datetime.toLocalDate(), endOfSecond(datetime.toLocalTime())); } /* * ---------------------------------------------------------------------------------- * formats * ---------------------------------------------------------------------------------- */ /** * 格式化日期/时间 * * @param accessor 日期/时间 * * @return 格式化后的字符串 */ public static String format(TemporalAccessor accessor) { return format(accessor, Const.PATTERN); } /** * 格式化日期 * * @param date 日期 * * @return 格式化后的字符串 */ public static String format(LocalDate date) { return format(date, Const.PATTERN_DATE); } /** * 格式化时间 * * @param time 时间 * * @return 格式化后的字符串 */ public static String format(LocalTime time) { return format(time, Const.PATTERN_TIME); } /** * 格式化日期/时间 * * @param accessor 日期/时间 * @param pattern 输出格式 * * @return 格式化后的字符串 */ public static String format(TemporalAccessor accessor, String pattern) { return format(accessor, DateTimeFormatter.ofPattern(pattern)); } /** * 格式化日期/时间 * * @param accessor 日期/时间 * @param formatter 输出格式 * * @return 格式化后的字符串 */ public static String format(TemporalAccessor accessor, DateTimeFormatter formatter) { return formatter.format(accessor); } /* * ---------------------------------------------------------------------------------- * converters * ---------------------------------------------------------------------------------- */ public static LocalDateTime safeToDateTime(Instant instant) { return ofInstant(instant, ZoneId.systemDefault()); } public static LocalDateTime safeToDateTime(Date date) { return safeToDateTime(date.toInstant()); } public static LocalDateTime safeToDateTime(Calendar calendar) { return safeToDateTime(calendar.toInstant()); } public static Instant safeToInstant(Date date) { return date.toInstant(); } public static Instant safeToInstant(Calendar calendar) { return calendar.toInstant(); } public static Instant toInstant(long time) { return Instant.ofEpochMilli(time); } public static Instant toInstant(Date date) { return date == null ? null : date.toInstant(); } public static Instant toInstant(Calendar calendar) { return calendar == null ? null : calendar.toInstant(); } public static LocalDate toDate(Calendar calendar) { return calendar == null ? null : safeToDateTime(calendar).toLocalDate(); } public static LocalTime toTime(Calendar calendar) { return calendar == null ? null : safeToDateTime(calendar).toLocalTime(); } public static LocalDateTime toDateTime(Calendar calendar) { return calendar == null ? null : safeToDateTime(calendar); } public static LocalDate toDate(Date date) { return date == null ? null : safeToDateTime(date).toLocalDate(); } public static LocalTime toTime(Date date) { return date == null ? null : safeToDateTime(date).toLocalTime(); } public static LocalDateTime toDateTime(Date date) { return date == null ? null : safeToDateTime(date); } public static LocalDateTime toDateTime(Instant instant) { return instant == null ? null : safeToDateTime(instant); } public static LocalDate toDate(CharSequence date) { return parseToDate(date); } public static LocalTime toTime(CharSequence date) { return parseToTime(date); } public static LocalDateTime toDateTime(CharSequence date) { return parseToDateTime(date); } public static LocalDate toDate(long milliseconds) { return toDateTime(milliseconds).toLocalDate(); } public static LocalTime toTime(long milliseconds) { return toDateTime(milliseconds).toLocalTime(); } public static LocalDateTime toDateTime(long milliseconds) { return toDateTime(toInstant(milliseconds)); } public static LocalDate toDate(int... values) { int i = 0; switch (values == null ? 0 : values.length) { case 0: return null; case 1: return LocalDate.of(values[i], 1, 1); case 2: return LocalDate.of(values[i++], values[i], 1); default: return LocalDate.of(values[i++], values[i++], values[i]); } } public static LocalTime toTime(int... values) { int i = 0; switch (values == null ? 0 : values.length) { case 0: return null; case 1: return LocalTime.of(values[i], 0); case 2: return LocalTime.of(values[i++], values[i]); case 3: return LocalTime.of(values[i++], values[i++], values[i]); default: return LocalTime.of(values[i++], values[i++], values[i++], values[i]); } } @SuppressWarnings("all") public static LocalDateTime toDateTime(int... parts) { int[] vs = parts; int i = 0; switch (parts == null ? 0 : parts.length) { case 0: return null; case 1: return LocalDateTime.of(vs[i], 1, 1, 0, 0); case 2: return LocalDateTime.of(vs[i++], vs[i], 1, 0, 0); case 3: return LocalDateTime.of(vs[i++], vs[i++], vs[i], 0, 0); case 4: return LocalDateTime.of(vs[i++], vs[i++], vs[i++], vs[i], 0); case 5: return LocalDateTime.of(vs[i++], vs[i++], vs[i++], vs[i++], vs[i]); case 6: return LocalDateTime.of(vs[i++], vs[i++], vs[i++], vs[i++], vs[i++], vs[i]); default: return LocalDateTime.of(vs[i++], vs[i++], vs[i++], vs[i++], vs[i++], vs[i++], vs[i]); } } public static LocalDate toDate(Object obj) { return obj == null ? null : toDateTime(obj).toLocalDate(); } public static LocalTime toTime(Object obj) { return obj == null ? null : toDateTime(obj).toLocalTime(); } public static LocalDateTime toDateTime(Object obj) { if (obj == null) { return null; } if (obj instanceof LocalDateTime) { return (LocalDateTime) obj; } if (obj instanceof CharSequence) { return toDateTime((CharSequence) obj); } if (obj instanceof Number) { int maybeYear = ((Number) obj).intValue(); if (maybeYear < 10000) { return toDateTime(new int[]{maybeYear}); } return toDateTime(((Number) obj).longValue()); } if (obj instanceof int[]) { return toDateTime((int[]) obj); } if (obj instanceof Date) { return toDateTime((Date) obj); } if (obj instanceof Calendar) { return toDateTime((Calendar) obj); } if (obj instanceof LocalDate) { LocalDate date = (LocalDate) obj; return toDateTime(date.getYear(), date.getMonthValue(), date.getDayOfMonth()); } if (obj instanceof LocalTime) { return LocalDateTime.of(LocalDate.now(), (LocalTime) obj); } try { return toDateTime(ParseSupportUtil.unboxing(obj)); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(String.format("Can not cast to LocalDateTime of: %s", obj.toString()), e); } } /* * ---------------------------------------------------------------------------------- * parse * ---------------------------------------------------------------------------------- */ /** * 将时间字符串中解析为{@link LocalDateTime} *

* 要求符合格式:yyyy-MM-dd HH:mm:ss SSS 的一个或多个字段,并且每个字段的位数一致 * * @param dateString 日期字符串 * * @return 如果能正常解析返回 LocalDateTime 实例,否则返回 null * * @see CalendarUtil#extractDateTimeFields(CharSequence) */ public static LocalDateTime parseToDateTime(CharSequence dateString) { return CalendarUtil.transformDateTimeString(dateString, DateTimeUtil::toDateTime, DateTimeUtil::toDateTime); } /** * 将时间字符串中解析为{@link LocalDate} *

* 要求符合格式:yyyy-MM-dd 的一个或多个字段,并且每个字段的位数一致 * * @param dateString 日期字符串 * * @return 如果能正常解析返回 LocalDate 实例,否则返回 null * * @see CalendarUtil#extractDateTimeFields(CharSequence) */ public static LocalDate parseToDate(CharSequence dateString) { return CalendarUtil.transformDateTimeString(dateString, DateTimeUtil::toDate, DateTimeUtil::toDate); } /** * 将时间字符串中解析为{@link LocalTime} *

* 要求符合格式:HH:mm:ss SSS 的一个或多个字段,并且每个字段的位数一致 * * @param timeString 时间字符串 * * @return 如果能正常解析返回 LocalTime 实例,否则返回 null * * @see CalendarUtil#extractTimeFields(CharSequence) */ public static LocalTime parseToTime(CharSequence timeString) { return timeString == null ? null : toTime(CalendarUtil.extractTimeFields(timeString)); } /* * ---------------------------------------------------------------------------------- * reduce * ---------------------------------------------------------------------------------- */ /** * 聚合函数,从开始年份(含)至结束年份(不含),用年份比较,遍历处理每个年份数据 *

* 如: *

     *     LocalDate begin = DateTimeUtil.toDate(2015);
     *     LocalDate end = DateTimeUtil.toDate(2019);
     *     List values = DateTimeUtil.reduceYears(begin, end, (list, date, idx) -> {
     *         list.add(DateTimeUtil.format(date, "yyyy"));
     *         return list;
     *     }, new ArrayList());
     *     // values == {"2015","2016","2017","2018"}
     * 
* * @param begin 开始年份(含) * @param end 结束年份(不含) * @param reducer 聚合函数,接受三个参数:(总值,当前年份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceYears( LocalDate begin, LocalDate end, TableIntFunction reducer, T totalValue ) { return reduce(startOfYear(begin), startOfYear(end), b -> b.plusYears(1), reducer, totalValue); } /** * 聚合函数,从开始月份(含)至结束月份(不含),用月份比较,遍历处理每个月份数据 *

* 如: *

     *     LocalDate begin = DateTimeUtil.toDate(2019, 02);
     *     LocalDate end = DateTimeUtil.toDate(2019, 05);
     *     List values = DateTimeUtil.reduceMonths(begin, end, (list, date, idx) -> {
     *         list.add(DateTimeUtil.format(date, "yyyy-MM"));
     *         return list;
     *     }, new ArrayList());
     *     // values == {"2019-02","2019-03","2019-04"}
     * 
* * @param begin 开始月份(含) * @param end 结束月份(不含) * @param reducer 聚合函数,接受三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceMonths( LocalDate begin, LocalDate end, TableIntFunction reducer, T totalValue ) { return reduce(startOfMonth(begin), startOfMonth(end), b -> b.plusMonths(1), reducer, totalValue); } /** * 聚合函数,以周为单位逐步遍历增长处理 * * @param begin 开始月份(含) * @param end 结束月份(不含) * @param reducer 聚合函数,接受三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceWeeks( LocalDate begin, LocalDate end, TableIntFunction reducer, T totalValue ) { return reduce(begin, end, b -> b.plusWeeks(1), reducer, totalValue); } /** * 聚合函数,从开始日(含)至结束日(不含),用日比较,遍历处理每个月份数据 *

* 如: *

     *     LocalDate begin = DateTimeUtil.toDate(2019, 5, 1);
     *     LocalDate end = DateTimeUtil.toDate(2019, 5, 5);
     *     List values = DateTimeUtil.reduceDays(begin, end, (list, date, idx) -> {
     *         list.add(DateTimeUtil.format(date, "yyyy-MM-dd"));
     *         return list;
     *     }, new ArrayList());
     *     // values == {"2019-05-01","2019-05-02","2019-05-03","2019-05-04"}
     * 
* * @param begin 开始日(含) * @param end 结束日(不含) * @param reducer 聚合函数,接受三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceDays( LocalDate begin, LocalDate end, TableIntFunction reducer, T totalValue ) { return reduce(begin, end, b -> b.plusDays(1), reducer, totalValue); } /** * 正序聚合函数:从前面的日期逐步增长到后面的日期; *

* 自定义增长粒度 * * @param begin 开始日期 * @param end 结束日期 * @param reducer 聚合函数,接收三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param addr 增长函数,用于自定义增长粒度 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduce( LocalDate begin, LocalDate end, Function addr,// TableIntFunction reducer, T totalValue ) { for (int i = 0; begin.isBefore(end); begin = addr.apply(begin)) { totalValue = reducer.apply(totalValue, begin, i++); } return totalValue; } /** * 正序聚合函数:从前面的时间逐步增长到后面的时间; *

* 自定义增长粒度 * * @param begin 开始时间 * @param end 结束时间 * @param reducer 聚合函数,接收三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param addr 增长函数,用于自定义增长粒度 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduce( LocalTime begin, LocalTime end, Function addr,// TableIntFunction reducer, T totalValue ) { for (int i = 0; begin.isBefore(end); begin = addr.apply(begin)) { totalValue = reducer.apply(totalValue, begin, i++); } return totalValue; } /** * 正序聚合函数:从前面的时间逐步增长到后面的时间; *

* 自定义增长粒度 * * @param begin 开始时间 * @param end 结束时间 * @param reducer 聚合函数,接收三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param addr 增长函数,用于自定义增长粒度 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduce( LocalDateTime begin, LocalDateTime end, Function addr,// TableIntFunction reducer, T totalValue ) { for (int i = 0; begin.isBefore(end); begin = addr.apply(begin)) { totalValue = reducer.apply(totalValue, begin, i++); } return totalValue; } /** * 倒序聚合函数:从后面的日期逐步递减到前面的日期; *

* 自定义增长粒度 * * @param begin 开始日期 * @param end 结束日期 * @param reducer 聚合函数,接收三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param addr 递减函数,用于自定义递减粒度 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceReverse( LocalDate begin, LocalDate end, Function addr,// TableIntConsumer reducer, T totalValue ) { for (int i = 0; begin.isAfter(end); begin = addr.apply(begin)) { reducer.accept(totalValue, begin, i++); } return totalValue; } /** * 倒序聚合函数:从后面的时间逐步递减到前面的时间; *

* 自定义增长粒度 * * @param begin 开始时间 * @param end 结束时间 * @param reducer 聚合函数,接收三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param addr 递减函数,用于自定义递减粒度 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceReverse( LocalTime begin, LocalTime end, Function addr,// TableIntConsumer reducer, T totalValue ) { for (int i = 0; begin.isAfter(end); begin = addr.apply(begin)) { reducer.accept(totalValue, begin, i++); } return totalValue; } /** * 倒序聚合函数:从后面的时间逐步递减到前面的时间; *

* 自定义增长粒度 * * @param begin 开始时间 * @param end 结束时间 * @param reducer 聚合函数,接收三个参数:(总值,当前月份,索引),返回值作为下一次循环的总值或最终返回值 * @param totalValue 聚合函数初始总值 * @param addr 递减函数,用于自定义递减粒度 * @param 返回值类型 * * @return 执行完聚合函数后的总值 */ public static T reduceReverse( LocalDateTime begin, LocalDateTime end, Function addr,// TableIntConsumer reducer, T totalValue ) { for (int i = 0; begin.isAfter(end); begin = addr.apply(begin)) { reducer.accept(totalValue, begin, i++); } return totalValue; } /* * ---------------------------------------------------------------------------------- * for each * ---------------------------------------------------------------------------------- */ /** * 正序遍历:从前面的日期逐步增长到后面的时间; * * @param begin 开始日期 * @param end 结束日期 * @param addr 增长函数,自定义增长粒度 * @param consumer 处理器 */ public static void forEach( LocalDate begin, LocalDate end, Function addr, Consumer consumer ) { for (; begin.isBefore(end); begin = addr.apply(begin)) { consumer.accept(begin); } } /** * 倒序遍历:从后面的时间逐步递减到前面的时间; * * @param begin 开始日期 * @param end 结束日期 * @param addr 增长函数,自定义增长粒度 * @param consumer 处理器 */ public static void forEachReverse( LocalDate begin, LocalDate end, Function addr, Consumer consumer ) { for (; begin.isAfter(end); begin = addr.apply(begin)) { consumer.accept(begin); } } /** * 正序遍历:从前面的时间逐步增长到后面的时间; * * @param begin 开始时间 * @param end 结束时间 * @param addr 增长函数,自定义增长粒度 * @param consumer 处理器 */ public static void forEach( LocalTime begin, LocalTime end, Function addr, Consumer consumer ) { for (; begin.isBefore(end); begin = addr.apply(begin)) { consumer.accept(begin); } } /** * 倒序遍历:从后面的时间逐步递减到前面的时间; * * @param begin 开始时间 * @param end 结束时间 * @param addr 增长函数,自定义增长粒度 * @param consumer 处理器 */ public static void forEachReverse( LocalTime begin, LocalTime end, Function addr, Consumer consumer ) { for (; begin.isAfter(end); begin = addr.apply(begin)) { consumer.accept(begin); } } /** * 正序遍历:从前面的时间逐步增长到后面的时间; * * @param begin 开始时间 * @param end 结束时间 * @param addr 增长函数,自定义增长粒度 * @param consumer 处理器 */ public static void forEach( LocalDateTime begin, LocalDateTime end, Function addr, Consumer consumer ) { for (; begin.isBefore(end); begin = addr.apply(begin)) { consumer.accept(begin); } } /** * 倒序遍历:从后面的时间逐步递减到前面的时间; * * @param begin 开始时间 * @param end 结束时间 * @param addr 增长函数,自定义增长粒度 * @param consumer 处理器 */ public static void forEachReverse( LocalDateTime begin, LocalDateTime end, Function addr, Consumer consumer ) { for (; begin.isAfter(end); begin = addr.apply(begin)) { consumer.accept(begin); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy