日期工具类

Posted 野生java研究僧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日期工具类相关的知识,希望对你有一定的参考价值。

日期工具类

概述

在日常的开发中,我们难免会对日期格式化,对日期进行计算,对日期进行校验,为了避免重复写这些琐碎的逻辑,我这里封装了一个日期工具类,方便以后使用,直接复制代码到项目中即可使用。

日期工具类代码:

import org.apache.commons.lang3.StringUtils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 常用日期工具类
 *
 * @author compass
 * @date 2022/10/21 14:20
 * @since 1.0.0
 **/
public class DateTools 
    public final static String DEFAULT_TIME_FORMAT = "HH:mm:ss";
    public final static String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public final static String DEFAULT_DATE_FORMAT_SHORT = "yyMMdd";
    public final static String DEFAULT_YEAR_MODTH_SHORT = "yyyyMM";
    public final static String DEFAULT_TIME_FORMAT_SHORT = "HHmmss";
    public final static String DEFAULT_DATETIME_FORMAT_SHORT = "yyMMddHHmmss";
    public final static String DEFAULT_DATE_FORMAT_ALLSHORT = "yyyyMMdd";

    public static final String SIMPLE_DATE_STR = "yyyy-MM-dd";
    public static final String FULL_DATE_STR = "yyyy-MM-dd HH:mm:ss";
    public static final String ALL_FULL_DATE_STR = "yyyy-MM-dd HH:mm:ss.S";
    public static final String PART_DATE_STR = "yyyy-MM-dd HH:mm";
    public static final String DATEFORMAT_Y2H = "yyyy-MM-dd HH";

    public static final String SIMPLE_RULE_DATE_STR = "yyyy/MM/dd";
    public static final String FULL_RULE_DATE_STR = "yyyy/MM/dd HH:mm:ss";
    public static final String PART_RULE_DATE_STR = "yyyy/MM/dd HH:mm";
    public static final String SMALL_PART_RULE_DATE_STR = "HH:mm";

    public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";
    public static final String DATE_FORMAT_YYYYMMDDHH = "yyyyMMddHH";
    public static final String DATE_FORMAT_YYYYMMDDHHMM = "yyyyMMddHHmm";
    public static final String DATE_FORMAT_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static final String SIMPLE_POINT_DATE_STR = "yyyy.MM.dd";
    public static final String FULL_POINT_DATE_STR = "yyyy.MM.dd HH:mm:ss";

    /**
     * 锁对象
     */
    private static final Object lockObj = new Object();

    /**
     * 存放不同格式的线程安全的SimpleDateFormat
     */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();

    public enum DateType 
        YEAR("YEAR", 1),
        MONTH("MONTH", 2),
        DAY("DAY", 3),
        HOUR("HOUR", 4),
        MINUTE("MINUTE", 5),
        SECOND("SECOND", 6);

        private String name;
        private int value;

        DateType(String name, int value) 
            this.value = value;
            this.name = name;
        

        public int getValue() 
            return value;
        

        public String getName() 
            return name;
        
    

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getSdf(final String pattern) 
        ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
        if (tl == null) 
            synchronized (lockObj) 
                tl = sdfMap.get(pattern);
                if (tl == null) 
                    tl = ThreadLocal.withInitial(() -> new SimpleDateFormat(pattern));
                    sdfMap.put(pattern, tl);
                
            
        
        return tl.get();
    

    private static String[] supportFmt = new String[]ALL_FULL_DATE_STR, SIMPLE_DATE_STR,DATE_FORMAT_YYYYMMDDHHMMSS, DEFAULT_YEAR_MODTH_SHORT, DEFAULT_TIME_FORMAT, DEFAULT_DATE_FORMAT_SHORT;

    private static String checkFmt(String datestr) 
        if (datestr == null)
            return null;
        int len = datestr.length();
        if (len == 0)
            return null;
        String fmt;
        switch (len) 
            case 19:
                fmt = supportFmt[0];
                break;
            case 10:
                fmt = supportFmt[1];
                break;
            case 14:
                fmt = supportFmt[2];
                break;
            case 6:
                fmt = supportFmt[3];
                break;
            case 8: 
                if (datestr.indexOf(":") > 0) 
                    fmt = supportFmt[4];
                 else 
                    fmt = supportFmt[5];
                
            
            break;
            default:
                return null;
        
        return fmt;
    

    /**
     * 日期格式,正则表达式
     */
    private static String[] supportFmtPattern = new String[]
            "\\\\d4\\\\-\\\\d1,2\\\\-\\\\d1,2", "yyyy-MM-dd",
            "\\\\d4-\\\\d1,2-\\\\d1,2\\\\s+\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy-MM-dd HH:mm:ss",
            "\\\\d1,2:\\\\d1,2:\\\\d1,2", "HH:mm:ss",
            "\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3", "HH:mm:ss.SSS",
            "\\\\d4年\\\\d1,2月\\\\d1,2日", "yyyy年MM月dd日",
            "\\\\d4-\\\\d1,2-\\\\d1,2\\\\s+\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3", "yyyy-MM-dd HH:mm:ss.SSS",
            "\\\\d4(10|11|12|0[1-9])(30|31|[1-2][0-9]|0[1-9])(20|21|22|23|1[0-9]|0[0-9])([1-5][0-9]|0[0-9])([1-5][0-9]|0[0-9])", "yyyyMMddHHmmss",
            "\\\\d4(10|11|12|0[1-9])(30|31|[1-2][0-9]|0[1-9])", "yyyyMMdd",
            "\\\\d4(10|11|12|0[1-9])(30|31|[1-2][0-9]|0[1-9])(20|21|22|23|1[0-9]|0[0-9])([1-5][0-9]|0[0-9])([1-5][0-9]|0[0-9])\\\\d1,3", "yyyyMMddHHmmssSSS",
            "\\\\d4(10|11|12|0[1-9])", "yyyyMM",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2", "yyyy/MM/dd",
            "\\\\d4\\\\.\\\\d1,2\\\\.\\\\d1,2", "yyyy.MM.dd",
            "\\\\d1,2\\\\-\\\\d1,2\\\\-\\\\d4", "MM-dd-yyyy",
            "\\\\d1,2\\\\/\\\\d1,2\\\\/\\\\d4", "MM/dd/yyyy",
            "\\\\d1,2\\\\/\\\\d1,2\\\\/\\\\d2", "MM/dd/yy",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy/MM/dd'T'HH:mm:ss",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy/MM/dd't'HH:mm:ss",
            "\\\\d4-\\\\d1,2-\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy-MM-dd'T'HH:mm:ss",
            "\\\\d4-\\\\d1,2-\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy-MM-dd't'HH:mm:ss",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3Z", "yyyy/MM/dd'T'HH:mm:ss.SSS'Z'",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3z", "yyyy/MM/dd't'HH:mm:ss.SSS'z'",
            "\\\\d4-\\\\d1,2-\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3Z", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
            "\\\\d4-\\\\d1,2-\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3z", "yyyy-MM-dd't'HH:mm:ss.SSS'z'"
    ;

    /**
     * 日期格式,正则表达式
     */
    private static String[] supportDateFmtPattern = new String[]
            "\\\\d4\\\\-\\\\d1,2\\\\-\\\\d1,2", "yyyy-MM-dd",
            "\\\\d4年\\\\d1,2月\\\\d1,2日", "yyyy年MM月dd日",
            "\\\\d4(10|11|12|0[1-9])(30|31|[1-2][0-9]|0[1-9])", "yyyyMMdd",
            "\\\\d4(10|11|12|0[1-9])", "yyyyMM",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2", "yyyy/MM/dd",
            "\\\\d4\\\\.\\\\d1,2\\\\.\\\\d1,2", "yyyy.MM.dd",
            "\\\\d1,2\\\\-\\\\d1,2\\\\-\\\\d4", "MM-dd-yyyy",
            "\\\\d1,2\\\\/\\\\d1,2\\\\/\\\\d4", "MM/dd/yyyy",
            "\\\\d1,2\\\\/\\\\d1,2\\\\/\\\\d2", "MM/dd/yy"
    ;

    /**
     * 时间格式,正则表达式
     */
    private static String[] supportTimeFmtPattern = new String[]
            "\\\\d4-\\\\d1,2-\\\\d1,2\\\\s+\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy-MM-dd HH:mm:ss",
            "\\\\d1,2:\\\\d1,2:\\\\d1,2", "HH:mm:ss",
            "\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3", "HH:mm:ss.SSS",
            "\\\\d4-\\\\d1,2-\\\\d1,2\\\\s+\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3", "yyyy-MM-dd HH:mm:ss.SSS",
            "\\\\d4(10|11|12|0[1-9])(30|31|[1-2][0-9]|0[1-9])(20|21|22|23|1[0-9]|0[0-9])([1-5][0-9]|0[0-9])([1-5][0-9]|0[0-9])", "yyyyMMddHHmmss",
            "\\\\d4(10|11|12|0[1-9])(30|31|[1-2][0-9]|0[1-9])(20|21|22|23|1[0-9]|0[0-9])([1-5][0-9]|0[0-9])([1-5][0-9]|0[0-9])\\\\d1,3", "yyyyMMddHHmmssSSS",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy/MM/dd'T'HH:mm:ss",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy/MM/dd't'HH:mm:ss",
            "\\\\d4-\\\\d1,2-\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy-MM-dd'T'HH:mm:ss",
            "\\\\d4-\\\\d1,2-\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2", "yyyy-MM-dd't'HH:mm:ss",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3Z", "yyyy/MM/dd'T'HH:mm:ss.SSS'Z'",
            "\\\\d4\\\\/\\\\d1,2\\\\/\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3z", "yyyy/MM/dd't'HH:mm:ss.SSS'z'",
            "\\\\d4-\\\\d1,2-\\\\d1,2T\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3Z", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
            "\\\\d4-\\\\d1,2-\\\\d1,2t\\\\d1,2:\\\\d1,2:\\\\d1,2\\\\.\\\\d1,3z", "yyyy-MM-dd't'HH:mm:ss.SSS'z'"
    ;


    /**
     * 根据日期时间串推断日期格式
     *
     * @param datestr 日期字符串
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static String checkFmtByPattern(String datestr) 
        if (datestr == null)
            return null;
        for (int i = 0; i < supportFmtPattern.length; i += 2) 
            if (Pattern.matches(supportFmtPattern[i], datestr)) 
                return supportFmtPattern[i + 1];
            
        
        return null;
    

    /**
     * 根据字符串格式自动判断日期格式,支持11种  <br>
     * yyyy-MM-dd HH:mm:ss.SSS <br>
     * yyyy-MM-dd HH:mm:ss <br>
     * yyyy-MM-dd <br>
     * yyyy.MM.dd <br>
     * yyyy/MM/dd <br>
     * HH:mm:ss.SSS <br>
     * HH:mm:ss <br>
     * yyyyMMdd <br>
     * yyyyMMddHHmmssSSS <br>
     * yyyyMMddHHmmss <br>
     * yyyyMM <br>
     *
     * @param datestr
     * @return
     */
    public static Date parse(String datestr) 
        String fmt = checkFmtByPattern(datestr);
        return parse(datestr, fmt);
    


    /**
     * 获取yyyy-MM-dd日期类型
     *
     * @param dateStr 日期字符串
     * @param fmt     日期格式
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static Date parse(String dateStr, String fmt) 
        try 
            return getSdf(fmt).parse(dateStr);
         catch (NullPointerException | ParseException e) 
            throw new RuntimeException(String.format("不支持的时间格式,[%s]", dateStr));
        

    

    /**
     * 获取yyyy-MM-dd日期类型
     *
     * @param datestr 日期字符串
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static Date parseDay(String datestr) 
        try 
            return getSdf(supportFmt[1]).parse(datestr);
         catch (ParseException e) 
            throw new RuntimeException("不支持的时间格式");
        
    


    /**
     * 获取yyyy-MM-dd HH:mm:ss日期类型
     *
     * @param datestr 日期字符串
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static Date parseDayTime(String datestr) 
        try 
            return getSdf(supportFmt[0]).parse(datestr);
         catch (ParseException e) 
            throw new RuntimeException("不支持的时间格式");
        
    


    /**
     * 将日期格式化成指定格式
     *
     * @param dt 日期
     * @param dt 格式字符串
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static String format(Date dt, String... pattern) 
        if (pattern != null && pattern.length > 1) 
            throw new RuntimeException("日期格式字符串,只支持一个");
        
        String format = pattern.length <= 0 ?DEFAULT_DATETIME_FORMAT : pattern[0];
        return getSdf(format).format(dt);
    


    /**
     * 将日期格式化为yyyy-MM-dd HH:mm:ss
     *
     * @param dt 日期
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static String formatDayTime(Date dt) 
        return getSdf(supportFmt[0]).format(dt);
    


    /**
     * 将日期格式化为yyyy-MM-dd
     *
     * @param dt 开日期
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static String formatDay(Date dt) 
        return getSdf(supportFmt[1]).format(dt);
    


    /**
     * 将日期格式化为HH:mm:ss
     *
     * @param dt 开日期
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static String formatTime(Date dt) 
        return getSdf(supportFmt[4]).format(dt);
    


    /**
     * 计算月份差[日期型],按月份计算忽略天数
     *
     * @param fromDate 开始日期
     * @param toDate   结束日期
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static Integer monthBetween(Date fromDate, Date toDate) 

        if ((fromDate == null) || (toDate == null)) 
            return null;
        
        int times = 1;
        if (!fromDate.after(toDate)) 
            Calendar calFrom = Calendar.getInstance();
            Calendar calTo = Calendar.getInstance();
            calFrom.setTime(fromDate);
            calFrom.set(Calendar.DAY_OF_MONTH, 1);
            calTo.setTime(toDate);
            calTo.set(Calendar.DAY_OF_MONTH, 1);
            while (calFrom.before(calTo)) 
                calFrom.add(2, 1);
                times++;
            
         else 
            return 0;
        
        return times;

    


    /**
     * 计算月份差(字符型),自动判定格式
     *
     * @param fromDate 开始日期
     * @param toDate   结束日期
     * @return java.lang.Integer
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static Integer monthBetween(String fromDate, String toDate) 

        if ((fromDate == null) || (toDate == null)) 
            return null;
        
        return monthBetween(parse(fromDate), parse(toDate));

    

    /**
     * 计算天数差
     *
     * @param from 开始日期
     * @param end  结束日期
     * @return java.util.Date
     * @author compass
     * @date 2022/10/21 11:06
     * @since 1.0.0
     **/
    public static Integer daysBetween(Date from, Date end) 
        if ((from == null) || (end == null)) 
            return null;
        
        long fromL = from.getTime();
        long endL = end.getTime();
        double diff = 网上搜罗的些年月日季度之类的工具类,

Java工作日计算工具类

计算多个日期范围内有多少个重叠日期

Date 日期时间工具类,针对日期的一些常用的处理方法

日期工具类处理总结(全)

java怎么获得当前年月日并赋给变量?