通用自然日计算工具

package com.zhou.util;
 
import com.zhou.common.enums.RateTypeEnum;
import com.zhou.util.enums.IEnum;
import lombok.Data;
import lombok.SneakyThrows;
 
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
 
/**
 * 通用自然日转换器
 * @author lang.zhou
 * @since 2024/3/12 9:53
 */
@Data
public class DateParse {
 
    /**
     * 默认输出格式,默认yyyyMMdd
     */
    //private static final SimpleDateFormat DF = new SimpleDateFormat("yyyyMMdd");
 
    /**
     * 自定义输出格式,默认yyyyMMdd
     */
    private String pattern ;
 
    private SimpleDateFormat format ;
 
    private static DateParse PARSER =  new DateParse("yyyyMMdd");
 
 
    private DateParse(String pattern) {
        this.pattern = pattern;
        this.format = new SimpleDateFormat(pattern);
    }
 
    /**
     * 传入一个日期格式,返回转换器
     * @param pattern   yyyyMMdd
     */
    public static DateParse ct(String pattern){
        return new DateParse(pattern);
    }
 
    /**
     * 返回默认转换器yyyyMMdd
     */
    public static DateParse ct(){
        return PARSER;
    }
 
 
    public static void main(String[] args){
        System.out.println(DateParse.ct("yyyy-MM-dd").getNextDay(20240309,-4));
        System.out.println(DateParse.ct("yyyy-MM-dd").getLastDayOfWeek(20240312,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getFirstDayOfWeek(20240312,1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getFirstDayOfMonth(20240309,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getLastDayOfMonth(20240309,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getFirstDayOfQuarter(20240309,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getLastDayOfQuarter(20240309,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getFirstDayOfYear(20240309,1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getLastDayOfYear(20240309,1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getFirstDayOfHalfYear(20240309,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getLastDayOfHalfYear(20240309,-1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getDayInMonth(20240312,1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getDayInWeek(20240312,1));
        System.out.println(DateParse.ct("yyyy-MM-dd").getDayInQuarter(20240312,60));
        System.out.println(DateParse.ct("yyyy-MM-dd").getDayInYear(20240312,60));
        System.out.println(DateParse.getBetweenDay(20240309,20240318));
        System.out.println(DateParse.getBetweenWeek(20240311,20240317));
        System.out.println(DateParse.getBetweenMonth(20240331,20240401));
        System.out.println(DateParse.getBetweenQuarter(20240331,20240401));
        System.out.println(DateParse.getBetweenYear(20240331,20260401));
        System.out.println(DateParse.getWeekInYear(20240312));
        System.out.println(DateParse.getDayInWeek(20240312));
        System.out.println(DateParse.getMonthInYear(20240312));
        System.out.println(DateParse.getQuarterInYear(20240312));
        System.out.println(DateParse.getYear(20240312));
        System.out.println(DateParse.getWeekInYear(20241230));
    }
 
 
    /**
     * 将字符型或Date对象转换成整型,yyyyMMdd格式
     * @return yyyyMMdd
     */
    @SneakyThrows
    public static Integer parseInt(Object date){
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        if(date instanceof Long){
            return Integer.parseInt(df.format(new Date((Long) date)));
        }else if(date instanceof Number){
            return ((Number) date).intValue();
        }else if(date instanceof String){
            return Integer.parseInt(replace(date.toString(),df));
        }else if(date instanceof Date){
            return Integer.parseInt(df.format((Date) date));
        }
        throw new IllegalArgumentException(date.toString() + "无法转换为日期格式");
    }
 
    /**
     * 将字符型或Date对象转换成字符,yyyyMMdd格式
     * @return yyyyMMdd
     */
    @SneakyThrows
    public static String parseYmd(Object date){
        return parseInt(date).toString();
    }
 
    /**
     * 将字符型或Date对象转换成format格式的字符串
     */
    @SneakyThrows
    public String parseString(Object date){
        return format.format(parseDate(date));
    }
 
    /**
     * 去除输入字符对象中的特殊字符,只保留ymd
     */
    private static String replace(String o, SimpleDateFormat df){
        //只保留数字
        String s = StringTool.filterNum(o);
        //支持6位日期
        if(s.length() == 6){
            s = s.substring(0,4) + "0" + s.charAt(4) + "0" + s.charAt(5);
        }
        if(s.length() > 8){
            try{
                long v = Long.parseLong(s);
                s = df.format(new Date(v));
            }catch (Exception e){
                throw new IllegalArgumentException(s + "无法转换为日期格式");
            }
        }
        return s;
    }
 
    /**
     * 将任意对象转为Date对象
     */
    @SneakyThrows
    public static Date parseDate(Object date){
        return parseDate(date,new SimpleDateFormat("yyyyMMdd"));
    }
 
    @SneakyThrows
    public static Date parseDate(Object date, SimpleDateFormat df){
        if(date instanceof Long){
            return new Date((Long) date);
        }else if(date instanceof Number){
            return df.parse(replace(date.toString(),df));
        }else if(date instanceof String){
            return df.parse(replace(date.toString(),df));
 
        }else if(date instanceof Date){
            return (Date) date;
        }
        throw new IllegalArgumentException(date + "无法转换为日期格式");
    }
 
    public static Calendar getCalendar(Object dateObj){
        Calendar calendar = Calendar.getInstance();
        Date date = parseDate(dateObj);
        calendar.setTime(date);
        return calendar;
    }
 
    /**
     * 获取后n天,n为负数时表示前n天,n为0表示当天
     * @param dateObj:可以输入整型、字符串或Date对象。格式为20180926 或"2018-09-26" 或"2018/09/26"
     */
    public String getNextDay(Object dateObj, int n){
        Calendar calendar = getCalendar(dateObj);
        calendar.add(Calendar.DATE, n);
        return format.format(calendar.getTime());
    }
 
 
 
    /**
     * 获取date所在周的后n周最后一天,n为负数时表示前n周,n为0表示本周
     * @param dateObj:格式为20180926
     */
    public String getLastDayOfWeek(Object dateObj, int n) {
        Calendar calendar = getCalendar(dateObj);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//将每周第一天设为星期一,默认是星期天
        calendar.add(Calendar.DATE, 7*n);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return format.format(calendar.getTime());
    }
    /**
     * 获取date所在周的后n周第一天,n为负数时表示前n周,n为0表示本周
     * @param dateObj:格式为20180926
     */
    public String getFirstDayOfWeek(Object dateObj,int n) {
        Calendar calendar = getCalendar(dateObj);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//将每周第一天设为星期一,默认是星期天
        calendar.add(Calendar.DATE, 7*n);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return format.format(calendar.getTime());
    }
 
    /**
     * 获取date所在月的第后n个月的最后一天,n为负数时表示前n个月,n为0表示本月
     */
    public String getLastDayOfMonth(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        calendar.add(Calendar.MONTH, n+1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.DATE, -1);
        return format.format(calendar.getTime());
    }
    /**
     * 获取date所在月的第后n个月的第一天,n为负数时表示前n个月,n为0表示本月
     */
    public String getFirstDayOfMonth(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        calendar.add(Calendar.MONTH, n);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return format.format(calendar.getTime());
    }
    /**
     * 获取date所在季度的后n个季度的最后一天,n为负数时表示前n个季度,n为0表示本季度
     * @param dateObj:格式为20180926
     */
//    public String getLastDayOfQuarter(Object dateObj, int n){
//        Calendar c = getCalendar(dateObj);
//        int date = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(c.getTime()));
//        int monthSet = date%10000/100-1;
//        int month = monthSet+1;
//        c.add(Calendar.MONTH,n*3+1);
//        c.set(Calendar.DAY_OF_MONTH, 1);
//        c.add(Calendar.DATE, -1);
//        c.add(Calendar.MONTH, 3-(month%3==0 ? 3 : month%3));
//        return format.format(c.getTime());
//    }
    public String getLastDayOfQuarter(Object dateObj, int n) {
        Calendar c = getCalendar(dateObj);
        // 先移动到当前季度的第一个月
        int currentMonth = c.get(Calendar.MONTH);
        int quarterStartMonth = (currentMonth / 3) * 3;
        c.set(Calendar.MONTH, quarterStartMonth);
        c.set(Calendar.DAY_OF_MONTH, 1);
 
        // 添加n个季度的偏移
        c.add(Calendar.MONTH, n * 3);
 
        // 移动到季度的最后一天
        c.add(Calendar.MONTH, 3); // 下个季度的第一个月
        c.add(Calendar.DAY_OF_MONTH, -1); // 前一天的当前季度的最后一天
 
        return format.format(c.getTime());
    }
 
    /**
     * 获取date所在季度的后n个季度的第一天,n为负数时表示前n个季度,n为0表示本季度
     * @param dateObj:格式为20180926
     */
    public String getFirstDayOfQuarter(Object dateObj,int n){
        Calendar c = getCalendar(dateObj);
        int date = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(c.getTime()));
        int monthSet = date%10000/100-1;
        int month = monthSet+1;
        c.add(Calendar.MONTH,n*3);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.add(Calendar.MONTH, 1-(month%3==0 ? 3 : month%3));
        return format.format(c.getTime());
    }
    /**
     * 获取date所在年的后n年的最后一天,n为负数时表示前n年,n为0表示本年
     * @param dateObj:格式为20180926
     */
    public String getLastDayOfYear(Object dateObj, int n){
        Calendar calendar = getCalendar(dateObj);
        calendar.add(Calendar.YEAR, n+1);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.add(Calendar.DATE, -1);
        return format.format(calendar.getTime());
    }
 
    public static int getDayOfYear(Object dateObj){
        Calendar calendar = getCalendar(dateObj);
        return calendar.get(Calendar.YEAR);
    }
    /**
     * 获取date所在年的后n年的第一天,n为负数时表示前n年,n为0表示本年
     * @param dateObj:格式为20180926
     */
    public String getFirstDayOfYear(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        calendar.add(Calendar.YEAR, n);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        return format.format(calendar.getTime());
    }
    /**
     * 获取date所在半年的后n个半年的第一天,n为负数时表示前n个半年,n为0表示本半年
     * @param dateObj:格式为20180926
     */
    public String getFirstDayOfHalfYear(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        int addM = n * 6;
        calendar.add(Calendar.MONTH, addM);
        int m = calendar.get(Calendar.MONTH) + 1;
        calendar.set(Calendar.MONTH,m > 6 ? 6 : 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return format.format(calendar.getTime());
    }
 
    /**
     * 获取date所在半年的后n个半年的最后一天,n为负数时表示前n个半年,n为0表示本半年
     * @param dateObj:格式为20180926
     */
    public String getLastDayOfHalfYear(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        int addM = n * 6;
        calendar.add(Calendar.MONTH, addM);
        int m = calendar.get(Calendar.MONTH) + 1;
        calendar.set(Calendar.MONTH,m > 6 ? 11 : 5);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.DATE, -1);
        return format.format(calendar.getTime());
    }
 
    /**
     * 获取两个日期间的天数
     */
    public static int getBetweenDay(Object d1,Object d2){
        long a= getCalendar(d1).getTimeInMillis();
        long b= getCalendar(d2).getTimeInMillis();
        double betweenDays = (((b - a) * 1.0) / (1000 * 60 * 60 * 24)) + 0.5;
        return (int) Math.floor(betweenDays);
    }
 
    /**
     * 获取两个日期所间隔的周数
     */
    private static int getBetweenWeek(Object date1,Object date2){
 
        int d1 = Integer.parseInt(PARSER.getFirstDayOfWeek(date1,0));
        int d2 = Integer.parseInt(PARSER.getFirstDayOfWeek(date2,0));
        long n = getBetweenDay(d1,d2);
        return (int)(n/7);
    }
 
    /**
     * 获取两个日期所在月数的差值
     */
    public static int getBetweenMonth(Object d1,Object d2){
        int date1 = parseInt(d1);
        int date2 = parseInt(d2);
        int year1 = date1/10000;
        int year2 = date2/10000;
        int month1 = date1%10000/100;
        int month2 = date2%10000/100;
        if(month2 < month1){
            month2 += 12;
            year2 --;
        }
        return (year2-year1)*12+month2-month1;
    }
 
    /**
     * 获取两个日期所在季度数的差值
     */
    public static int getBetweenQuarter(Object date1,Object date2){
        return getBetweenMonth(PARSER.getFirstDayOfQuarter(date1,0),PARSER.getFirstDayOfQuarter(date2,0))/3;
    }
 
    /**
     * 获取两个日期所在年数的差值
     */
    public static int getBetweenYear(Object date1,Object date2){
        return parseInt(date2)/10000 - parseInt(date1)/10000;
    }
 
    /**
     * 获取date在本年的周数
     */
    public static int getWeekInYear(Object dateObj){
        Calendar calendar = getCalendar(dateObj);
        //calendar.setMinimalDaysInFirstWeek(7);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }
 
    /**
     * 获取date在本月的周数
     */
    public static int getWeekInMonth(Object dateObj){
        Calendar calendar = getCalendar(dateObj);
        //calendar.setMinimalDaysInFirstWeek(7);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        return calendar.get(Calendar.WEEK_OF_MONTH);
    }
    /**
     * 获取date是本星期中的第几天
     * @return 返回1~7
     */
    public static int getDayInWeek(Object dateObj){
        Calendar calendar = getCalendar(dateObj);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        int dayOfWeek=calendar.get(Calendar.DAY_OF_WEEK);
        return dayOfWeek!=1 ? dayOfWeek-1 : 7;
    }
 
    /**
     * 获取dateObj是所在月的第几天
     */
    public static int getDayInMonth(Object dateObj){
        Calendar calendar = getCalendar(dateObj);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }
 
    /**
     * 获取dateObj所在月的第n天,若超出本月天数,返回本月最后一天
     */
    public String getDayInMonth(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        n = n > 0 ? n :32;
        if(n > calendar.getActualMaximum(Calendar.DAY_OF_MONTH)){
            return getLastDayOfMonth(dateObj,0);
        }
        return getNextDay(getFirstDayOfMonth(dateObj,0),n - 1);
    }
 
    /**
     * 获取dateObj所在年
     */
    public static int getYear(Object dateObj){
        int date = parseInt(dateObj);
        return date/10000;
    }
 
    /**
     * 获取dateObj所在月是本年的第几个月
     */
    public static int getMonthInYear(Object dateObj){
        int date = parseInt(dateObj);
        return date%10000/100;
    }
 
    /**
     * 获取dateObj是上半年还是下半年
     */
    public static String getHalfYear(Object dateObj){
        int month = getMonthInYear(dateObj);
        return month > 6 ? "下半年" : "上半年";
    }
 
    /**
     * 获取dateObj所在周的第n天,若超出本周天数,返回本周最后一天
     */
    public String getDayInWeek(Object dateObj,int n){
        Calendar calendar = getCalendar(dateObj);
        n = n > 0 ? n :32;
        if(n>calendar.getActualMaximum(Calendar.DAY_OF_WEEK)){
            return getLastDayOfWeek(dateObj,0);
        }
        return getNextDay(getFirstDayOfWeek(dateObj,0),n - 1);
    }
 
    public static String getWeek(Date date) {
        return "周" + "?一二三四五六日".charAt(getDayInWeek(date));
    }
 
    /**
     * 获取dateObj所在季度的第n天,若超出本季度天数,返回本季度最后一天
     */
    public String getDayInQuarter(Object dateObj, int n){
        String fir = PARSER.getFirstDayOfQuarter(dateObj,0);
        String las = PARSER.getLastDayOfQuarter(dateObj,0);
        String now = PARSER.getNextDay(fir,n - 1);
        int d = parseInt(now);
        if(d > parseInt(las)){
            return getLastDayOfQuarter(dateObj,0);
        }
        return getNextDay(fir,n - 1);
    }
 
    /**
     * 获取dateObj所在年的第n天,若超出本年天数,返回本年最后一天
     */
    public String getDayInYear(Object dateObj, int n){
        Calendar calendar = getCalendar(dateObj);
        n = n > 0 ? n :32;
        if(n > calendar.getActualMaximum(Calendar.DAY_OF_YEAR)){
            return getLastDayOfYear(dateObj,0);
        }
        return getNextDay(getFirstDayOfYear(dateObj,0),n - 1);
    }
 
    public static int getQuarterInYear(Object dateObj){
        int month = parseInt(dateObj)%10000/100;
        if(month>=1 && month<=3){
            return 1;
        }else if(month>3 && month<=6){
            return 2;
        }else if(month>6 && month<=9){
            return 3;
        }else if(month>9 && month<=12){
            return 4;
        }
        return 0;
    }
 
    /**
     * 拿到一年内的日期
     * @param date 一年内的任意日期
     */
    public static List<Integer> getYearDays(Object date){
        int startDay = Integer.parseInt(DateParse.ct().getFirstDayOfYear(date,0));
        int endDay = Integer.parseInt(DateParse.ct().getLastDayOfYear(date,0));
        List<Integer> res = new ArrayList<>();
        int i = 0;
        while (true){
            int nextDay = Integer.parseInt(DateParse.ct().getNextDay(startDay, i));
            if(nextDay > endDay){
                break;
            }else{
                res.add(nextDay);
            }
            i ++;
        }
        return res;
    }
 
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值