报表中常用的一个时间段内按照不同周期划分时间段,同时也命名每个时间段名称

发布时间 2023-11-27 10:39:53作者: 红与黑

用Java写的,基于若依的玩意,有需要拿去用或优化一下

 

首先建立返回的实体对象和周期枚举

public class ChartLine {
    private Date beginTime;
    private Date endTime;
    private String lineName;
}
public enum SplitWay
{

    /**
     * 天
     */
    Day(0),
    /**
     * 周
     */
    Week(1),

    /**
     * 月
     */
    Month(2),

    /**
     * 年
     */
    Year(3),

    /**
     * 季度
     */
    Quarter(4),

    /**
     * 半年
     */
    HalfY(5);

    // 成员变量
    private int value;
    // 构造方法
    SplitWay(int value) {
        this.value = value;
    }
    // get set 方法
    public int getValue()
    {
        return this.value;
    }

    public SplitWay setValue(int value)
    {
        for (SplitWay way:SplitWay.values()){
            if(way.getValue()==value){
                return way;
            }
        }
        return SplitWay.Day;
    }
}

几个常用的时间格式化规则

public static String YYYY = "yyyy";
public static String YY = "yy";
public static String YYYY_MM = "yyyy-MM";
public static String CN_SHORT_YYYY_MM = "yy年M月";
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

核心代码,私有的,DateUtils是当前Java Class,用过若依的都懂的,这里也只是提供一个算法。我个人其实比较喜欢if-else,想改造成switch-case也行

private static ChartLine getDateOne(Date begin, Date end, SplitWay splitWay){
        if(end.after(begin)){
            ChartLine dateRef=new ChartLine();
            dateRef.setBeginTime(begin);;
            Date beginDate= DateUtils.dateTime(DateUtils.YYYY_MM_DD,DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,begin));
            Calendar CAL = Calendar.getInstance();
            CAL.setFirstDayOfWeek(Calendar.MONDAY);
            CAL.setTime(beginDate);
            Date refEnd=begin;

            if(splitWay.equals(SplitWay.Day)){
                if(beginDate.equals(refEnd)){
                    refEnd=DateUtils.addDays(begin,1);
                }else{
                    refEnd=DateUtils.addDays(beginDate,1);
                }
                if(refEnd.after(end))refEnd=end;
                dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,begin));

            }else if(splitWay.equals(SplitWay.Week)){
                Integer beginWeek=CAL.get(Calendar.DAY_OF_WEEK);
                if(beginDate.equals(refEnd)&&beginWeek==CAL.getFirstDayOfWeek()){
                    refEnd=DateUtils.addDays(begin,7);
                }else{
                    if(beginWeek<CAL.getFirstDayOfWeek()) {
                        refEnd = DateUtils.addDays(beginDate, 1);
                    }else{
                        refEnd = DateUtils.addDays(beginDate, 9-beginWeek);
                    }
                }
                if(refEnd.after(end))refEnd=end;
                dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.CN_SHORT_YYYY_MM,begin)+"第"+CAL.get(Calendar.WEEK_OF_MONTH)+"周");

            }else if(splitWay.equals(SplitWay.Month)){
                Integer beginMonth=CAL.get(Calendar.DATE);
                if(beginDate.equals(refEnd)&&beginMonth==1){
                    refEnd=DateUtils.addMonths(begin,1);
                }else{
                    String endStr=DateUtils.parseDateToStr(DateUtils.YYYY_MM,DateUtils.addMonths(beginDate, 1))+"-01";
                    refEnd=DateUtils.dateTime(DateUtils.YYYY_MM_DD,endStr);
                }
                if(refEnd.after(end))refEnd=end;
                dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.CN_SHORT_YYYY_MM,begin));
            }else if(splitWay.equals(SplitWay.Year)){
                Integer beginMonth=CAL.get(Calendar.DATE);
                Integer beginYear=CAL.get(Calendar.MONTH)+1;
                if(beginDate.equals(refEnd)&&beginMonth==1&&beginYear==1){
                    refEnd=DateUtils.addYears(begin,1);
                }else{
                    String endStr=DateUtils.parseDateToStr(DateUtils.YYYY,DateUtils.addYears(beginDate, 1))+"-01-01";
                    refEnd=DateUtils.dateTime(DateUtils.YYYY_MM_DD,endStr);
                }

                if(refEnd.after(end))refEnd=end;
                dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YYYY,begin)+"年");

            }else if(splitWay.equals(SplitWay.Quarter)){
                Integer beginMonth=CAL.get(Calendar.DATE);
                Integer beginYear=CAL.get(Calendar.MONTH)+1;
                List<Integer> beginYears=new ArrayList<>();
                beginYears.add(1);
                beginYears.add(4);
                beginYears.add(7);
                beginYears.add(10);
                if(beginDate.equals(refEnd)&&beginMonth==1&&beginYears.contains(beginYear)){
                    refEnd=DateUtils.addMonths(begin,3);
                }else{
                    Integer addMonth=(beginYear-1)%3==0?3:(beginYear-1)%3;
                    String endStr=DateUtils.parseDateToStr(DateUtils.YYYY_MM,DateUtils.addMonths(beginDate, addMonth))+"-01";
                    refEnd=DateUtils.dateTime(DateUtils.YYYY_MM_DD,endStr);
                }
                if(refEnd.after(end))refEnd=end;
                if(beginYear<4){
                    dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YY,begin)+"年第1季度");
                }else if(beginYear<7){
                    dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YY,begin)+"年第2季度");
                }else if(beginYear<10){
                    dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YY,begin)+"年第3季度");
                }else{
                    dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YY,begin)+"年第4季度");
                }
            }else if(splitWay.equals(SplitWay.HalfY)){
                Integer beginMonth=CAL.get(Calendar.DATE);
                Integer beginYear=CAL.get(Calendar.MONTH)+1;
                List<Integer> beginYears=new ArrayList<>();
                beginYears.add(1);
                beginYears.add(7);
                if(beginDate.equals(refEnd)&&beginMonth==1&&beginYears.contains(beginYear)){
                    refEnd=DateUtils.addMonths(begin,6);
                }else{
                    Integer addMonth=(beginYear-1)%6==0?6:(beginYear-1)%6;
                    String endStr=DateUtils.parseDateToStr(DateUtils.YYYY_MM,DateUtils.addMonths(beginDate, addMonth))+"-01";
                    refEnd=DateUtils.dateTime(DateUtils.YYYY_MM_DD,endStr);
                }

                if(refEnd.after(end))refEnd=end;
                if(beginYear<7){
                    dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YY,begin)+"年上半年");
                }else{
                    dateRef.setLineName(DateUtils.parseDateToStr(DateUtils.YY,begin)+"年下半年");
                }

            }else{
                refEnd= DateUtils.addDays(begin,-1);
            }
            if(refEnd.after(begin)) {
                dateRef.setEndTime(refEnd);;
                return dateRef;
            }else{
                return null;
            }
        }else{
            return null;
        }
    }

然后是内循环方法,生成list,也是私有的

private static List<ChartLine> getDates(List<ChartLine> dates,Date begin, Date end, SplitWay splitWay){
        ChartLine one=getDateOne(begin,end,splitWay);
        if(one!=null) {
            dates.add(one);
            if(one.getEndTime().before(end)){
                dates=getDates(dates,one.getEndTime(),end,splitWay);
            }
        }
        return dates;
    }

最后是public

public static List<ChartLine> toDateList(Date begin, Date end, SplitWay splitWay)
    {
        List<ChartLine> refDate=new ArrayList<>();
        if(end.after(begin)){
            refDate=getDates(refDate,begin,end,splitWay);
        }
        return refDate;
    }

题外话,正常前端默认是不会传具体起止时间给后端,传给后端也通常是【yyyy-MM-dd】格式,后端遇到这个问题可以有很多处理方式,我个人习惯是默认给一个时间的最大值最小值,而且结束时间正常加一天。那样SQL层面一个between-and梭哈就完了....

public static String getAddOneDayDate(String dateStr){
        if(StringUtils.isNotEmpty(dateStr)) {
            try {
                Date date = DateUtils.addDays(DateUtils.dateTime(DateUtils.YYYY_MM_DD,dateStr),1);
                return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,date);
            }catch (Exception e){
                return "2099-01-01 00:00:00";
            }
        }else{
            return "2099-01-01 00:00:00";
        }
    }

    public static String getThisDayDate(String dateStr){
        if(StringUtils.isNotEmpty(dateStr)) {
            try {
                Date date = DateUtils.dateTime(DateUtils.YYYY_MM_DD,dateStr);
                return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,date);
            }catch (Exception e){
                return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(0L));
            }
        }else{
            return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(0L));
        }
    }