0
点赞
收藏
分享

微信扫一扫

硕士应聘大专老师

8052cf60ff5c 2023-09-24 阅读 37

TimeFormatEnum

import lombok.Getter;

import java.time.format.DateTimeFormatter;

/**
 * 描述 : 时间格式化类型枚举类.
 *
 * <p>说明:
 * 1. TimeFormatEnum.LONG_DATE_PATTERN_LINE.formatter; // 获取默认时间格式: yyyy-MM-dd HH:mm:ss
 * 2. 对于LocalDate,只能指定短时间格式化类型,否则会出现UnsupportedTemporalTypeException异常
 * 3. 当日期字符串格式与指定的{@link TimeFormatEnum}格式无法对应时,则会出现DateTimeParseException异常
 *
 * @author : MoCha
 * @version : v1
 * @date : 2021-02-14 09:04
 */
@Getter
public enum TimeFormatEnum {
    /* ---------------- 短时间格式 -------------- */

    /**
     * 短时间格式 yyyy-MM-dd.
     */
    SHORT_DATE_PATTERN_LINE("yyyy-MM-dd"),

    /**
     * 短时间格式 yyyy/MM/dd.
     */
    SHORT_DATE_PATTERN_SLASH("yyyy/MM/dd"),

    /**
     * 短时间格式 yyyy\MM\dd.
     */
    SHORT_DATE_PATTERN_BACK_SLASH("yyyy\\MM\\dd"),

    /**
     * 短时间格式 yyyyMMdd.
     */
    SHORT_DATE_PATTERN_NONE("yyyyMMdd"),

    /* ---------------- 长时间格式 -------------- */

    /**
     * 长时间格式 yyyy-MM-dd HH:mm:ss.
     */
    LONG_DATE_PATTERN_LINE("yyyy-MM-dd HH:mm:ss"),

    /**
     * 长时间格式 yyyy/MM/dd HH:mm:ss.
     */
    LONG_DATE_PATTERN_SLASH("yyyy/MM/dd HH:mm:ss"),

    /**
     * 长时间格式 yyyy\MM\dd HH:mm:ss.
     */
    LONG_DATE_PATTERN_BACK_SLASH("yyyy\\MM\\dd HH:mm:ss"),

    /**
     * 长时间格式 yyyyMMdd HH:mm:ss.
     */
    LONG_DATE_PATTERN_NONE("yyyyMMdd HH:mm:ss"),

    /**
     * 长时间格式 yyyyMMddHHmmss.
     */
    LONG_DATE_PATTERN_WITH_NONE("yyyyMMddHHmmss"),

    /* ---------------- 长时间格式 带毫秒 -------------- */

    /**
     * 长时间格式 带毫秒 yyyy-MM-dd HH:mm:ss.SSS .
     */
    LONG_DATE_PATTERN_WITH_MISC_LINE("yyyy-MM-dd HH:mm:ss.SSS"),

    /**
     * 长时间格式 带毫秒 yyyy/MM/dd HH:mm:ss.SSS .
     */
    LONG_DATE_PATTERN_WITH_MISC_SLASH("yyyy/MM/dd HH:mm:ss.SSS"),

    /**
     * 长时间格式 带毫秒 yyyy\MM\dd HH:mm:ss.SSS .
     */
    LONG_DATE_PATTERN_WITH_MISC_BACK_SLASH("yyyy\\MM\\dd HH:mm:ss.SSS"),

    /**
     * 长时间格式 带毫秒 yyyyMMdd HH:mm:ss.SSS .
     */
    LONG_DATE_PATTERN_WITH_MISC_NONE("yyyyMMdd HH:mm:ss.SSS");

    /**
     * 时间格式化器.
     */
    private final DateTimeFormatter formatter;

    TimeFormatEnum(String pattern) {
        formatter = DateTimeFormatter.ofPattern(pattern);
    }

    /**
     * 判断是否为短时间格式类型
     *
     * <p>说明:
     * 1. 判断的界限以{@link TimeFormatEnum#SHORT_DATE_PATTERN_NONE}为参考
     *
     * @param timeFormatEnum 时间格式化类型
     * @return true表示为短时间格式化类型
     */
    public static boolean isShortDatePattern(TimeFormatEnum timeFormatEnum) {
        return timeFormatEnum.ordinal() <= SHORT_DATE_PATTERN_NONE.ordinal();
    }
}

LocalDateTimeUtils

import org.springframework.util.Assert;

import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * 描述 : LocalDate工具类.
 *
 * @author : MoCha
 * @version : v1
 * @date : 2021-02-13 17:00
 */
public final class LocalDateUtils {
    /**
     * Prevents instantiation.
     */
    private LocalDateUtils() {
    }

    /* ---------------- 时间戳相关方法 -------------- */

    /**
     * 当前LocalDate 转 时间戳(秒级别)
     *
     * @return 时间戳(秒级别)
     */
    public static Long toNowSecond() {
        return toSecond(LocalDate.now());
    }

    /**
     * 当前LocalDate 转 时间戳(毫秒级别)
     *
     * @return 时间戳(毫秒级别)
     */
    public static Long toNowMilliseconds() {
        return toMilliseconds(LocalDate.now());
    }

    /**
     * LocalDate 转 时间戳(秒级别).
     *
     * @param localDate 日期对象
     * @return 时间戳(秒级别)
     */
    public static Long toSecond(LocalDate localDate) {
        return localDate.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().getEpochSecond();
    }

    /**
     * LocalDate 转 时间戳(毫秒级别).
     *
     * @param localDate 日期对象
     * @return 时间戳(毫秒级别)
     */
    public static Long toMilliseconds(LocalDate localDate) {
        return localDate.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
    }

    /**
     * 时间戳(秒级别) 转 LocalDate.
     *
     * @param timestamp 时间戳(秒级别)
     * @return 日期对象
     */
    public static LocalDate ofSecond(Long timestamp) {
        return Instant.ofEpochSecond(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDate();
    }

    /**
     * 时间戳(毫秒级别) 转 LocalDate.
     *
     * @param timestamp 时间戳(毫秒级别)
     * @return 日期对象
     */
    public static LocalDate ofMilliseconds(Long timestamp) {
        return Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDate();
    }

    /**
     * 获取指定日期开始时间点(凌晨零点)的时间戳(秒级别).
     *
     * @return 指定日期开始时间点的时间戳(秒级别)
     */
    public static long getTodayStartTimeStamp(LocalDate localDate) {
        return LocalDateTime.of(localDate, LocalTime.MIN).toEpochSecond(ZoneOffset.ofHours(8));
    }

    /**
     * 获取指定日期结束时间点(夜晚23点59分59秒)的时间戳(秒级别).
     *
     * @return 指定日期结束时间点的时间戳(秒级别)
     */
    public static long getTodayEndTimeStamp(LocalDate localDate) {
        return LocalDateTime.of(localDate, LocalTime.MAX).toEpochSecond(ZoneOffset.ofHours(8));
    }

    /* ---------------- 格式化日期对象相关方法 -------------- */

    /**
     * 根据时间戳返回短时间格式化日期对象 .
     *
     * @param timestamp 日期时间戳
     * @return 日期对象格式化值
     */
    public static String formatShortDatePatternLine(Long timestamp) {
        return formatShortDatePatternLine(ofMilliseconds(timestamp));
    }

    /**
     * 短时间格式化日期对象 格式:yyyy-MM-dd {@link TimeFormatEnum#SHORT_DATE_PATTERN_LINE}.
     *
     * @param localDate 日期对象
     * @return 日期对象格式化值
     */
    public static String formatShortDatePatternLine(LocalDate localDate) {
        return TimeFormatEnum.SHORT_DATE_PATTERN_LINE.getFormatter().format(localDate);
    }

    /**
     * 短时间格式化日期对象 格式:yyyyMMdd.
     *
     * @param localDate 日期对象
     * @return 日期对象格式化值
     */
    public static String formatShortDatePatternNone(LocalDate localDate) {
        return TimeFormatEnum.SHORT_DATE_PATTERN_NONE.getFormatter().format(localDate);
    }

    /**
     * 指定格式化类型进行日期对象格式化.
     *
     * <p>说明:
     * 1. 对于LocalDate,只能指定短时间格式化类型,否则会出现UnsupportedTemporalTypeException异常
     *
     * @param localDate      日期对象
     * @param timeFormatEnum 格式化类型枚举 {@link TimeFormatEnum}
     * @return 日期对象格式化值
     */
    public static String format(LocalDate localDate, TimeFormatEnum timeFormatEnum) {
        Assert.isTrue(TimeFormatEnum.isShortDatePattern(timeFormatEnum), "对于LocalDate,只能格式化短时间格式的LocalDate");
        return timeFormatEnum.getFormatter().format(localDate);
    }

    /* ---------------- 解析时间字符串相关方法 -------------- */

    /**
     * 解析日期字符串为日期对象 格式:yyyy-MM-dd.
     *
     * @param text 日期字符串 格式:yyyy-MM-dd {@link TimeFormatEnum#SHORT_DATE_PATTERN_LINE}
     * @return 日期对象
     */
    public static LocalDate parseShortDatePatternLine(CharSequence text) {
        return LocalDate.parse(text, TimeFormatEnum.SHORT_DATE_PATTERN_LINE.getFormatter());
    }

    /**
     * 解析日期字符串为日期对象 格式:yyyyMMdd.
     *
     * @param text 日期字符串 格式:yyyyMMdd
     * @return 日期对象
     */
    public static LocalDate parseShortDatePatternNone(CharSequence text) {
        return LocalDate.parse(text, TimeFormatEnum.SHORT_DATE_PATTERN_NONE.getFormatter());
    }

    /**
     * 指定解析类型进行日期字符串解析
     *
     * <p>说明:
     * 1. 当日期字符串格式与指定的{@link TimeFormatEnum}格式无法对应时,则会出现DateTimeParseException异常
     * 2. 对于LocalDate,只能解析短时间格式的日期字符串
     *
     * @param text           日期字符串
     * @param timeFormatEnum 格式化类型枚举 {@link TimeFormatEnum}
     * @return 日期对象
     */
    public static LocalDate parse(CharSequence text, TimeFormatEnum timeFormatEnum) {
        Assert.isTrue(TimeFormatEnum.isShortDatePattern(timeFormatEnum), "对于LocalDate,只能解析短时间格式的日期字符串");
        return LocalDate.parse(text, timeFormatEnum.getFormatter());
    }

    /* ---------------- 与业务场景相关的方法 -------------- */

    /**
     * 获取指定日期上一个月的最后一天.
     *
     * @return 日期对象
     */
    public static LocalDate getPreviousMonthLastDay(LocalDate localDate) {
        return localDate.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 获取指定日期所在月份的第一个周几.
     *
     * <p>说明:
     * 1. 如果想要获取当前日期所在月份的第一个周几,第一个入参设置为LocalDate.now()
     * 2. DayOfWeek可选值,通常使用MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
     *
     * <p>例如:
     * LocalDateUtils.getFirstDayOfWeek(LocalDate.now(), DayOfWeek.THURSDAY)
     *
     * @param localDate 指定日期对象
     * @param dayOfWeek 周几(周一、周二、周三...、周天)
     * @return 第一个周几的LocalDate日期对象
     */
    public static LocalDate getFirstDayOfWeek(LocalDate localDate, DayOfWeek dayOfWeek) {
        return localDate.with(TemporalAdjusters.firstInMonth(dayOfWeek));
    }

    /**
     * 获取当前月份的第一天.
     *
     * @return 当前月份的第一天日期对象
     */
    public static LocalDate getFirstDayOfCurrentMonth() {
        return LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 获取当前月份的最后一天.
     *
     * @return 当前月份的最后一天日期对象
     */
    public static LocalDate getLastDayOfCurrentMonth() {
        return LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 获取两个日期字符串之间的日期时间戳集.
     *
     * <p>说明:
     * 1. 时间戳仅考虑年月日,不带时分秒
     *
     * <p>示例:
     * getBetweenTimeStampShortDatePatternNone("20210626", "20210712")
     *
     * @param startText 开始日期字符串;须为短时间格式,即不带时分秒
     * @param endText   结束日期字符串;须为短时间格式,即不带时分秒
     * @return 两个日期字符串之间的日期时间戳集
     */
    public static List<Long> getBetweenTimeStampShortDatePatternNone(CharSequence startText, CharSequence endText) {
        List<Long> betweenTimeStampList = new ArrayList<>();
        LocalDate startDate = parse(startText, TimeFormatEnum.SHORT_DATE_PATTERN_NONE);
        LocalDate endDate = parse(endText, TimeFormatEnum.SHORT_DATE_PATTERN_NONE);

        long distance = getBetweenDays(startDate, endDate);
        if (distance < 1) {
            return betweenTimeStampList;
        }

        Stream.iterate(startDate, date -> date.plusDays(1))
                .limit(distance + 1)
                .forEach(localDate -> betweenTimeStampList.add(toMilliseconds(localDate)));
        return betweenTimeStampList;
    }

    /**
     * 获取两个日期字符串之间的日期字符串集.
     *
     * <p>说明:
     * 1. 日期列表为短时间格式 yyyyMMdd
     *
     * <p>示例:
     * getBetweenDateTextShortDatePatternNone("20210626", "20210712")
     *
     * @param startText 开始日期字符串;须为短时间格式,即不带时分秒
     * @param endText   结束日期字符串;须为短时间格式,即不带时分秒
     * @return 两个日期字符串之间的日期字符串集
     */
    public static List<String> getBetweenDateTextShortDatePatternNone(CharSequence startText, CharSequence endText) {
        return getBetweenDateText(startText, endText, TimeFormatEnum.SHORT_DATE_PATTERN_NONE);
    }

    /**
     * 获取两个日期字符串之间的日期字符串集.
     *
     * <p>示例:
     * getBetweenDateText("20210626", "20210712", TimeFormatEnum.SHORT_DATE_PATTERN_NONE)
     *
     * @param startText      开始日期字符串;须为短时间格式,即不带时分秒
     * @param endText        结束日期字符串;须为短时间格式,即不带时分秒
     * @param timeFormatEnum 时间格式化类型枚举类;须为短时间格式枚举类
     * @return 两个日期字符串之间的日期字符串集
     */
    public static List<String> getBetweenDateText(CharSequence startText, CharSequence endText, TimeFormatEnum timeFormatEnum) {
        List<String> betweenDateTextList = new ArrayList<>();
        LocalDate startDate = parse(startText, timeFormatEnum);
        LocalDate endDate = parse(endText, timeFormatEnum);

        long distance = ChronoUnit.DAYS.between(startDate, endDate);
        if (distance < 1) {
            return betweenDateTextList;
        }

        Stream.iterate(startDate, date -> date.plusDays(1))
                .limit(distance + 1)
                .forEach(localDate -> betweenDateTextList.add(format(localDate, timeFormatEnum)));
        return betweenDateTextList;
    }

    /**
     * 计算两个时间戳间隔的天数.
     *
     * <p>说明:时间戳仅考虑年月日,不带时分秒
     *
     * @param startTimeStamp 开始时间戳
     * @param endTimeStamp   结束时间戳
     * @return 间隔天数
     */
    public static Long getBetweenDays(Long startTimeStamp, Long endTimeStamp) {
        LocalDate startLocalDate = ofMilliseconds(startTimeStamp);
        LocalDate endLocalDate = ofMilliseconds(endTimeStamp);
        return getBetweenDays(startLocalDate, endLocalDate);
    }

    /**
     * 计算两个日期对象间隔的天数.
     *
     * @param startDate 起始日期对象
     * @param endDate   结束日期对象
     * @return 两个日期对象间隔的天数
     */
    public static Long getBetweenDays(LocalDate startDate, LocalDate endDate) {
        return startDate.until(endDate, ChronoUnit.DAYS);
    }

    /* ---------------- 季度相关的方法 -------------- */

    /**
     * 获取当前年份季度中文描述.
     *
     * @return 返回示例:2021年第一季度
     */
    public static String getNowYearQuarterlyDesc() {
        switch (getNowQuarterEnum()) {
            case FIRST:
                return LocalDate.now().getYear() + "年第一季度";
            case SECOND:
                return LocalDate.now().getYear() + "年第二季度";
            case THIRD:
                return LocalDate.now().getYear() + "年第三季度";
            case FOURTH:
                return LocalDate.now().getYear() + "年第四季度";
            default:
                return "";
        }
    }

    /**
     * 获取当前季度值.
     *
     * @return 当前季度值
     */
    public static int getNowQuarterly() {
        return getNowQuarterEnum().getValue();
    }

    /**
     * 查询当前季度枚举类.
     *
     * @return 季度枚举类
     */
    public static QuarterEnum getNowQuarterEnum() {
        return LocalDate.now().query(new QuarterOfYearQuery());
    }

    /**
     * 获取当前时间季度开始时间戳(毫秒级别).
     *
     * <p>说明:时间戳仅考虑年月日,不带时分秒
     *
     * @return 返回当前时间季度开始时间戳
     */
    public static Long getNowQuarterStartTimeStamp() {
        LocalDate nowLocalDate = LocalDate.now();
        Month firstMonthOfQuarter = nowLocalDate.getMonth().firstMonthOfQuarter();
        nowLocalDate = LocalDate.of(nowLocalDate.getYear(), firstMonthOfQuarter, 1);
        return toMilliseconds(nowLocalDate);
    }
}

举报

相关推荐

0 条评论