DateUtils.java 11.3 KB
package com.nanyan.securitylink.utils;

import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

@Slf4j
public class DateUtils {
    public static long dayTimeStamp(Date date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String formattedDate = sdf.format(date);
        return sdf.parse(formattedDate).getTime();
    }
    public static boolean isValidDate(Date date) {
        if (date == null) {
            return false; // Date 为 null,非法
        }

        // 检查 Date 是否在合理范围内
        // 例如,检查是否大于某个最小日期(如 1970 年 1 月 1 日)
        Date minDate = new Date(0); // 1970-01-01 00:00:00 UTC
        if (date.before(minDate)) {
            return false; // Date 早于 1970 年 1 月 1 日,非法
        }

        // 检查是否小于某个最大日期(如 2100 年 1 月 1 日)
        Date maxDate = new Date(4102444800000L); // 2100-01-01 00:00:00 UTC
        if (date.after(maxDate)) {
            return false; // Date 晚于 2100 年 1 月 1 日,非法
        }

        return true; // Date 合法
    }

    public static long LocalDateTimeToMillis(LocalDateTime localDateTime, String zoneId) {
        // 结合时区,这里使用系统默认时区
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(zoneId));
        // 转换成Instant
        Instant instant = zonedDateTime.toInstant();
        // 获取毫秒值
        return instant.toEpochMilli();
    }

    public static Long currentUTCMilli(){
        // 获取当前UTC时间的Instant对象
        Instant now = Instant.now();

        // 获取秒级时间戳
        long epochMilli = now.toEpochMilli();
        return epochMilli;
    }

    public static long currentMonthlyStart(Date start) {
        LocalDateTime now = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime firstDayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth());
        // 将开始和结束时间转换为毫秒级时间戳
        return firstDayOfMonth.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }
    public static long currentMonthlyEnd(Date start){
        LocalDateTime now = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime firstDayOfNextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
        // 将开始和结束时间转换为毫秒级时间戳
        return firstDayOfNextMonth.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    public static long yearTimeStamp(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        String year = sdf.format(date);
        return toYMD(String.format("%s-01-01",year)).toInstant().toEpochMilli();
    }

    public static Long monthTimeStamp(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String yyyyMM = sdf.format(date);
        return toYMD(String.format("%s-01",yyyyMM)).toInstant().toEpochMilli();
    }
    public static long quarterTimeStamp(Date date) {
        int month = getMonth(date);
        String monthStr = null;
        int year = getYear(date);
        if (month <= 3) {
            monthStr = "01";
        } else if (month <= 6) {
            monthStr = "03";
        } else if (month <= 9) {
            monthStr = "06";
        } else {
            monthStr = "09";
        }
        String format = String.format("%d-%s-01", year, monthStr);
        return toYMD(format).getTime();
    }

    public static String dateYYYYMMDD(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = sdf.format(date);
        return formattedDate;
    }

    public static String getHourStr(Long dt ){
        Date date = new Date(dt * 1000);
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        return sdf.format(date);
    }

    public static Integer getHour(Date dt ){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dt);

        // 获取小时数
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public static Date toYMD(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try{
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            return sdf.parse(dateStr);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static Date toYMD(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try{
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            String format = sdf.format(date);
            return sdf.parse(format);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static Date lastDate(Date date, Integer day){
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    public static int getMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH) + 1; // 由于月份从0开始,所以需要+1
        return month;
    }
    public static int getYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        return year;
    }
    public static String getDaily(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH) + 1; // 由于月份从0开始,所以需要+1
        int day = calendar.get(Calendar.DAY_OF_MONTH) + 1; // 由于月份从0开始,所以需要+1
        return String.format("%d-%d", month, day);
    }

    public static String calculateTimeDifference(Date date) {
        if(date == null){
            return "";
        }
        Date currentDate = new Date();
        long differenceInMillis = currentDate.getTime() - date.getTime();
        long seconds = differenceInMillis / 1000;

        if (seconds < 60) {
            return seconds + "秒之前";
        } else if (seconds < 3600) {
            long minutes = seconds / 60;
            return minutes + "分钟之前";
        } else if(seconds < 3600 * 24){
            long hours = seconds / 3600;
            return hours + "小时之前";
        }else {
            long hours = seconds / (3600*24);
            return hours + "天之前";
        }
    }

    //通过cron表达式获取下次执行时间
    public static Long getNextExecutionTime(String cronExpression) {
        String tmp = cronExpression.replaceAll("\\?", "*");
        // 1. 定义Linux Crontab解析器
        CronParser parser = new CronParser(
                CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)
        );

        try {
            // 2. 解析表达式
            Cron cron = parser.parse(tmp);

            // 3. 计算下一次执行时间
            ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
            ExecutionTime executionTime = ExecutionTime.forCron(cron);
            Optional<ZonedDateTime> nextTime = executionTime.nextExecution(now);

            if (nextTime.isPresent()) {
                return nextTime.get().toInstant().toEpochMilli();
            } else {
                log.info("无有效执行时间");
            }
        } catch (IllegalArgumentException e) {
            System.err.println("Crontab表达式错误: " + e.getMessage());
        }
        return null;
    }

    public static void main(String[] args) {
        Long nextExecutionTime = getNextExecutionTime("25 6-23 * * ?");
        System.out.println(new Date(nextExecutionTime));
    }
    /**
     * 将毫秒时间长度转换为 N 天 N 小时 N 分 N 秒 格式
     * @param millis 毫秒数
     * @return 格式化后的时间字符串
     */
    public static String formatMillis(long millis) {
        // 计算总秒数
        long seconds = millis / 1000;
        // 计算天数
        long days = seconds / (24 * 60 * 60);
        seconds %= (24 * 60 * 60);
        // 计算小时数
        long hours = seconds / (60 * 60);
        seconds %= (60 * 60);
        // 计算分钟数
        long minutes = seconds / 60;
        // 计算剩余秒数
        seconds %= 60;

        StringBuilder result = new StringBuilder();
        if (days > 0) {
            result.append(days).append("天 ");
        }
        if (hours > 0) {
            result.append(hours).append("小时 ");
        }
        if (minutes > 0) {
            result.append(minutes).append("分 ");
        }
        if (seconds > 0) {
            result.append(seconds).append("秒");
        }
        // 如果结果为空,说明时间为 0,返回 "0 秒"
        if (result.length() == 0) {
            result.append("0 秒");
        }

        return result.toString();
    }

    public static String getWeekFormat(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE", Locale.SIMPLIFIED_CHINESE);
        String format = sdf.format(date);
        if("星期一".equals(format)){
            return "周一";
        }else  if("星期二".equals(format)){
            return "周二";
        }else  if("星期三".equals(format)){
            return "周三";
        }else  if("星期四".equals(format)){
            return "周四";
        }else  if("星期五".equals(format)){
            return "周五";
        }else  if("星期六".equals(format)){
            return "周六";
        }else  if("星期日".equals(format)){
            return "周日";
        }
        return format;
    }


    public static String getYYDDFormat(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("M月d日");
        return sdf.format(date);
    }
    public static long getYesterday0H(){
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算昨天的时间
        LocalDateTime yesterday = now.minusDays(1);
        // 设置为昨天 0 点
        LocalDateTime yesterdayNoon = yesterday.withHour(0).withMinute(0).withSecond(0).withNano(0);
        return yesterdayNoon.toInstant(ZoneOffset.UTC).getEpochSecond();
    }

    public static long getYesterday12H(){
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算昨天的时间
        LocalDateTime yesterday = now.minusDays(1);
        // 设置为昨天 12 点
        LocalDateTime yesterdayNoon = yesterday.withHour(12).withMinute(0).withSecond(0).withNano(0);
        return yesterdayNoon.toInstant(ZoneOffset.UTC).getEpochSecond();
    }

    public static int dateDifference(Date start, Date end) {
        LocalDate s = start.toInstant().atZone(ZoneId.of("UTC")).toLocalDate();
        LocalDate e = end.toInstant().atZone(ZoneId.of("UTC")).toLocalDate();
        return (int)ChronoUnit.DAYS.between(s, e);
    }
}