当前位置: 首页 > article >正文

Hive自定义函数—剔除周日周六(小时级别)

🐱背景🍎


Hello,小伙伴们,许久不见,最近遇到一个需求场景,关于物流时差的计算,要求算出差值是小时,且要剔除周日周六,网上很多文章,最好的也就是按照天剔除周日周六,小时级别,考虑的情况会非常多,要比天麻烦太多,最后无奈自己制作,分享给大家且记录一下,有需要的直接Copy下方核心代码 !😊 还请留下你的赞赞👍


☕️代码如下(Java)

package com.trendsi.udf;

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

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

public class NonWeekendHoursDiffUDF extends UDF {

//    public static void main(String[] args) {
//        NonWeekendHoursDiffUDF udf = new NonWeekendHoursDiffUDF();
//
//        // 测试用例1:开始时间是周一,结束时间是周三
//        Text startTime1 = new Text("2023-03-02 00:00:00"); // 周一
//        Text endTime1 = new Text("2023-03-03 00:00:00"); // 周三
//        Integer hoursDiff1 = udf.evaluate(startTime1, endTime1);
//        System.out.println("Case 1: Non-weekend hours difference = " + hoursDiff1);
//
//        // 测试用例2:开始时间是周六,结束时间是下一个周一
//        Text startTime2 = new Text("2023-03-04 09:00:00"); // 周六
//        Text endTime2 = new Text("2023-03-06 09:00:00"); // 下一个周一
//        Integer hoursDiff2 = udf.evaluate(startTime2, endTime2);
//        System.out.println("Case 2: Non-weekend hours difference = " + hoursDiff2);
//
//        // 测试用例3:开始时间和结束时间都是周六
//        Text startTime3 = new Text("2023-03-04 09:00:00"); // 周六
//        Text endTime3 = new Text("2023-03-05 09:00:00"); // 下一个周六
//        Integer hoursDiff3 = udf.evaluate(startTime3, endTime3);
//        System.out.println("Case 3: Non-weekend hours difference = " + hoursDiff3);
//
//        // 测试用例4:开始时间是周五,结束时间是下一个周一的凌晨
//        Text startTime4 = new Text("2023-03-03 13:00:00"); // 周五
//        Text endTime4 = new Text("2023-03-20 00:00:00"); // 下一个周一的凌晨
//        Integer hoursDiff4 = udf.evaluate(startTime4, endTime4);
//        System.out.println("Case 4: Non-weekend hours difference = " + hoursDiff4);
//    }

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public Integer evaluate(Text startTime, Text endTime) {
        try {
            Date startDate = sdf.parse(startTime.toString());
            Date endDate = sdf.parse(endTime.toString());

            Calendar startCal = Calendar.getInstance();
            startCal.setTime(startDate);
            Calendar endCal = Calendar.getInstance();
            endCal.setTime(endDate);

            // 如果开始时间是周末,则调整到下一个周一的0点
            if (isWeekend(startCal)) {
                adjustToNextWeekday(startCal, Calendar.MONDAY);
            }

            // 如果结束时间是周末,则调整到下一个周一的前一秒(即周日23:59:59)
            if (isWeekend(endCal)) {
                // 注意:这里应该是调整到下一个周一的前一天(周日),然后设置时间为23:59:59
                adjustToNextWeekday(endCal, Calendar.MONDAY);
                endCal.add(Calendar.DAY_OF_YEAR, -1);
                endCal.set(Calendar.HOUR_OF_DAY, 23);
                endCal.set(Calendar.MINUTE, 59);
                endCal.set(Calendar.SECOND, 59);
            }

            int hoursDiff = 0;
            while (startCal.before(endCal)) {
                // 只在非周末时增加小时数
                if (!isWeekend(startCal)) {
                    hoursDiff++;
                }
                startCal.add(Calendar.HOUR_OF_DAY, 1);
            }

            return hoursDiff;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    private boolean isWeekend(Calendar cal) {
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        return dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY;
    }

    private void adjustToNextWeekday(Calendar cal, int dayOfWeek) {
        int diff = dayOfWeek - cal.get(Calendar.DAY_OF_WEEK);
        if (diff <= 0) {
            diff += 7;
        }
        cal.add(Calendar.DAY_OF_YEAR, diff);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
    }

    private void adjustToWeekday(Calendar cal, int dayOfWeek) {
        int diff = dayOfWeek - cal.get(Calendar.DAY_OF_WEEK);
        if (diff > 0) {
            cal.add(Calendar.DAY_OF_YEAR, diff);
        } else {
            cal.add(Calendar.DAY_OF_YEAR, diff - 7);
        }
    }
}

简单使用

  • 前提:我这里用的IDEA,Maven,Java 这些基础不再赘述,网上很多教程,关于Hive内的使用如下:
-- 打包的jar包放到你想放的地方,执行下面命令,将jar包添加至hive
add jar hdfs://xxxxxxxx/udf/xxxxx.jar;
-- 根据类的全部包名创建hive函数
create function NonWeekendHoursDiffUDF as 'com.xxx.udf.xxx' using jar 'hdfs://xxxxxxxx/udf/xxxxx.jar'
-- 最后直接测试即可
select  NonWeekendHoursDiffUDF('2024-09-09 02:20:00','2024-09-10 01:00:00')

Java很久没写了,欢迎大佬提建议,其余有问题随时留言,一定回复~🐶 封面献上~

在这里插入图片描述


http://www.kler.cn/a/380275.html

相关文章:

  • 自研小程序-心情追忆
  • 【设计模式】策略模式定义及其实现代码示例
  • IDC报告解读:实用型靶场将成为下一代网络靶场的必然方向
  • LeetCode //C - 447. Number of Boomerangs
  • SpringBoot新闻稿件管理系统:架构与实现
  • 基于人脸识别PCA算法matlab实现及详细步骤讲解
  • 爬虫学习4
  • Vue中ref、reactive、toRef、toRefs的区别
  • IoTDB时序数据库使用
  • R 环境安装
  • 103 - Lecture 2 Table and Data Part 1
  • 初识JDBC
  • 深度学习基础知识-全连接层
  • Spring Cloud OpenFeign:基于Ribbon和Hystrix的声明式服务调用
  • python之正则表达式总结
  • 一键AI换衣-可图AI试衣
  • qt QSplitter详解
  • MySQL 索引的底层实现原理与优化策略
  • python 爬虫0基础入门 (爬虫基础知识)
  • 深度学习中的迁移学习
  • 使用Kafka构建大规模消息传递系统
  • SpringBoot+Shirp的权限管理
  • 云专线优势有哪些?对接入网络有什么要求?
  • Vue3 keep-alive核心源码的解析
  • C++ | Leetcode C++题解之第537题复数乘法
  • 麦麦Docker笔记(一)