hiveUDF——返回指定时间区间内的日期数组

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

/**
 * function:日期函数
 * 参数:开始时间、结束时间和天数差
 * 返回:数组,数组内是所有天数
 * example:
 * -----------------------------------------------------------------------|
 * 起始日期    | 结束日期      | 天数差  | 返回日期数组                     |
 * -----------------------------------------------------------------------|
 * 2021-01-01 | 2021-01-01	|   30	 | ["2021-01-01"]                    |
 * 2021-01-01 | 2021-01-15	|   30	 | ["2021-01-01",......"2021-01-15"] |
 * 2021-01-01 | 2021-02-15	|   30	 | ["2021-01-01",......"2021-01-31"] |
 * 2021-01-01 | null	    |   30	 | ["2021-01-01",......"2021-01-31"] |
 * -----------------------------------------------------------------------|
 *
 * @author
 * @date 2021/4/30
 */

public class DateRangeUDF extends UDF {
    
    

    private transient SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    private final Calendar calBegin = Calendar.getInstance();
    private final Calendar calEnd = Calendar.getInstance();

    /**
     * 只传start_date,默认返回截至start_date当月月末的日期数组
     * @param dBegin 开始日期
     * @return ArrayList<String>
     */
    public ArrayList<String> evaluate(Text dBegin) throws UDFArgumentLengthException {
    
    
        if (dBegin==null){
    
    
            throw new UDFArgumentLengthException("It requires start_date.");
        }
        try {
    
    
            //格式化开始时间
            calBegin.setTime(format.parse(dBegin.toString()));
            // 获取当月月末日期
            Calendar temBegin = Calendar.getInstance();
            temBegin.setTime(format.parse(dBegin.toString()));
            calBegin.add(Calendar.MONTH, 1);
            calBegin.set(Calendar.DAY_OF_MONTH, 0);
            Date lastday = calBegin.getTime();
            //装返回的日期集合容器
            ArrayList<String> Datelist = new ArrayList<>();
            // 算上开始日期那一天
            temBegin.add(Calendar.DAY_OF_MONTH, -1);
            while (format.parse(format.format(lastday)).after(temBegin.getTime())) {
    
    
                // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
                temBegin.add(Calendar.DAY_OF_MONTH, 1);
                Datelist.add(format.format(temBegin.getTime()));
            }

            return Datelist;
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

    /**
     * start_date 和 end_date都不为空,返回限定日期内日期数组
     * start_date不为空,end_date为空,返回从start_date开始截至到月末的日期数组
     *
     * @param dBegin 开始日期
     * @param dEnd  结束日期
     * @return ArrayList<String>
     */
    public ArrayList<String> evaluate(Text dBegin, Text dEnd) throws UDFArgumentException {
    
    
        if (dBegin==null){
    
    
            throw new UDFArgumentLengthException("It requires start_date.");
        }
        Date lastday;
        //装返回的日期集合容器
        ArrayList<String> Datelist = new ArrayList<>();
        try {
    
    
            //格式化开始时间
            calBegin.setTime(format.parse(dBegin.toString()));
            if (dEnd != null) {
    
    
                //格式化结束时间
                calEnd.setTime(format.parse(dEnd.toString()));
                lastday = calEnd.getTime();

            } else {
    
    
                // 如果dEnd为空,则取dBegin当月最后一天作为dEnd
                Calendar temBegin = Calendar.getInstance();
                temBegin.setTime(format.parse(dBegin.toString()));

                temBegin.add(Calendar.MONTH, 1);
                temBegin.set(Calendar.DAY_OF_MONTH, 0);
                lastday = temBegin.getTime();
            }
            calBegin.add(Calendar.DAY_OF_MONTH, -1);
            while (format.parse(format.format(lastday)).after(calBegin.getTime())) {
    
    
                // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                Datelist.add(format.format(calBegin.getTime()));
            }
            return Datelist;

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

    /**
     * start_date, end_date, dayNum都不为空,比较日期间隔与dayNum大小, 两者取其小返回限定日期内日期数组
     * start_date不为空, end_date为空, dayNum为空 返回至start_date当月月末的日期数组
     * start_date不为空, end_date为空, dayNum不为空 返回start_date加天数差范围内日期数组
     * @param dBegin 开始日期
     * @param dEnd   结束日期
     * @param dayNum 天数差
     * @return ArrayList<String>
     */
    public ArrayList<String> evaluate(Text dBegin, Text dEnd, IntWritable dayNum) throws UDFArgumentException {
    
    
        if (dBegin==null){
    
    
            throw new UDFArgumentLengthException("It requires start_date.");
        }
        //装返回的日期集合容器
        ArrayList<String> Datelist = new ArrayList<>();
        try {
    
    
            Date lastday;
            //格式化开始时间
            calBegin.setTime(format.parse(dBegin.toString()));
            // 如果 end_date和dayNum都为空
            if (dEnd == null && dayNum == null){
    
    
                // 获取当月月末日期
                Calendar temBegin = Calendar.getInstance();
                temBegin.setTime(format.parse(dBegin.toString()));
                temBegin.add(Calendar.MONTH, 1);
                temBegin.set(Calendar.DAY_OF_MONTH, 0);
                lastday = temBegin.getTime();

            }else if (dEnd == null){
    
    
                // end_date 为空,则取dBegin当月最后一天作为dEnd
                Calendar calBegin1 = Calendar.getInstance();
                calBegin1.setTime(format.parse(dBegin.toString()));
                calBegin1.add(Calendar.DAY_OF_MONTH, dayNum.get());
                lastday = calBegin1.getTime();

            }else if (dayNum == null){
    
    
                calEnd.setTime(format.parse(dEnd.toString()));
                lastday = calEnd.getTime();
            }else {
    
    
                // end_date不为空,计算日期间隔相差天数
                calEnd.setTime(format.parse(dEnd.toString()));
                Long starTime = calBegin.getTime().getTime();
                Long endTime = calEnd.getTime().getTime();
                Long num = (endTime - starTime) / 24 / 60 / 60 / 1000;

                // 判断日期间隔与天数差大小
                if (num.intValue() >= dayNum.get()) {
    
    
                    Calendar calBegin1 = Calendar.getInstance();
                    calBegin1.setTime(format.parse(dBegin.toString()));
                    calBegin1.add(Calendar.DAY_OF_MONTH, dayNum.get());
                    lastday = calBegin1.getTime();
                } else {
    
    
                    lastday = calEnd.getTime();
                }
            }
            calBegin.add(Calendar.DAY_OF_MONTH, -1);
            // 每次循环给calBegin日期加一天,直到calBegin.getTime()时间等于dEnd
            while (format.parse(format.format(lastday)).after(calBegin.getTime())) {
    
    
                // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                Datelist.add(format.format(calBegin.getTime()));
            }

            return Datelist;
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

}



猜你喜欢

转载自blog.csdn.net/Pioo_/article/details/116307917