kettle生成节假日数据原来还可以这样操作?

前言

         最近有好多小伙伴私信我,遇到一个问题在做数仓项目中遇到了瓶颈有的需求需要根据节假日去统计信息。但是由于节假日每年都不一样目前提供的方法没法动态的去获取关于节假日的信息。所以自己去编写一个实现类就完成这个操作。

在这里插入图片描述

一、需求描述

         在Hive中生成一个表用来保存关于日期的工具。目前大公司为了提高效率。创建一个日期表 将需要的数据保存到日期表中,使用的时候只需要join下即可实现次功能。

类型 示例值 中文名
date_key string 20000101 代理键
date_value string 2000-01-01 年-月-日
day_in_year string 1 当年的第几天
day_in_month string 1 当月的第几天
is_first_day_in_month string y 是否月的第一天
is_last_day_in_month string n 是否月的最后一天
weekday string 星期一 星期
week_in_month string 1 月的第几个星期
is_first_day_in_week string y、n 是否周一
is_dayoff string y、n 是否休息日
is_workday string y、n 是否工作日
is_holiday string y、n 是否国家法定节假日
date_type string workday、weekend、holiday
工作日、周末、法定节假日
日期类型
工作日:workday
国家法定节假日:holiday

休息日:weekend
month_number string 1、2、…、12 月份
year string 2000 年份
quarter_name string Q1 季度名称
quarter_number string 1 季度
year_quarter string 2000-Q1 年-季度
year_month_number string 2000-01 年-月份

预期结果数据

dim_date.date_value dim_date.day_in_month dim_date.is_first_day_in_month dim_date.is_last_day_in_month dim_date.weekday dim_date.week_in_month dim_date.is_first_day_in_week dim_date.is_dayoff dim_date.is_workday dim_date.is_holiday dim_date.date_type dim_date.month_number dim_date.year dim_date.year_month_number dim_date.quarter_name dim_date.quarter_number dim_date.year_quarter
20200113 2020-01-13 2020 13 n n 1 3 y n y n workday 01 2020 2020-01 Q1
20200112 2020-01-12 2020 12 n n 7 3 n n y n weekend 01 2020 2020-01 Q1
20200111 2020-01-11 2020 11 n n 6 2 n n y n weekend 01 2020 2020-01 Q1
20200110 2020-01-10 2020 10 n n 5 2 n n y n workday 01 2020 2020-01 Q1
20200109 2020-01-09 2020 9 n n 4 2 n n y n workday 01 2020 2020-01 Q1
20200108 2020-01-08 2020 8 n n 3 2 n n y n workday 01 2020 2020-01 Q1
20200107 2020-01-07 2020 7 n n 2 2 n n y n workday 01 2020 2020-01 Q1
20200106 2020-01-06 2020 6 n n 1 2 y n y n workday 01 2020 2020-01 Q1
20200105 2020-01-05 2020 5 n n 7 2 n n y n weekend 01 2020 2020-01 Q1
20200104 2020-01-04 2020 4 n n 6 1 n n y n weekend 01 2020 2020-01 Q1
20200103 2020-01-03 2020 3 n n 5 1 n n y n workday 01 2020 2020-01 Q1
20200102 2020-01-02 2020 2 n n 4 1 n n y n workday 01 2020 2020-01 Q1

二、实现思路

         我们可以通过爬虫的去获取官网上的节假日信息,但是对于小白了来说是有点困难的,于是就有好多大佬写了一些工具来提供我们来使用https://github.com/Haoshenqi0123/holiday 我们可以通过 大佬提供出来的API 接口发送HTTP请求来获取数据进行解析即可获取我们想要的数据。

三、编写代码

实现步骤:

  1. 创建hive表 用来存储结果数据
  2. 编写JavaScript代码
  3. 使用kettle 整个流程连接起来

3.1 创建hive表

create database kettle;
use kettle;

CREATE TABLE kettle.`date`(
  `date_key` string,
  `date_value` string,
  `day_in_year` string,
  `day_in_month` string,
  `is_first_day_in_month` string,
  `is_last_day_in_month` string,
  `weekday` string,
  `week_in_month` string,
  `is_first_day_in_week` string,
  `is_dayoff` string,
  `is_workday` string,
  `is_holiday` string,
  `date_type` string,
  `month_number` string,
  `year` string,
  `year_month_number` string,
  `quarter_name` string,
  `quarter_number` string,
  `year_quarter` string)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  'hdfs://node01:8020/user/hive/warehouse/kettle.db'

3.2 编写 JavaScript 代码


        // 1. 初始化上游变量
        var initDateStr = "2020-01-01";
        var locale = new java.util.Locale("en", "us");
        var calendar = java.util.Calendar.getInstance();
        var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd", locale);
        var initDate  = sdf.parse(initDateStr);

        calendar.setTime(initDate);
        calendar.add(java.util.Calendar.DAY_OF_MONTH, setup);

        var curDate = calendar.getTime();

        // 2. 生成维度数据
        // 2.1 生成代理键
        sdf.applyPattern("yyyyMMdd");
        var date_key = sdf.format(curDate);

        // 2.2 年-月-日
        sdf.applyPattern("yyyy-MM-dd");
        var date_value = sdf.format(curDate);

        // 2.3 当年的第几天
        var day_in_year = calendar.get(java.util.Calendar.YEAR) + "";

        // 2.4 当月的第几天
        var day_in_month = calendar.get(java.util.Calendar.DAY_OF_MONTH) + "";

        // 2.5 是否为当月的第一天
        var is_first_day_in_month = day_in_month.equals("1") ? "y":"n";

        // 2.6 是否为当月最后一天
        // 1. 加一天
        calendar.add(java.util.Calendar.DAY_OF_MONTH, 1);

        var is_last_day_in_month = calendar.get(java.util.Calendar.DAY_OF_MONTH) == 1 ? "y":"n";
        // 2. 减回去
        calendar.add(java.util.Calendar.DAY_OF_MONTH, -1);

        // 2.7 星期
        var weekday = (calendar.get(java.util.Calendar.DAY_OF_WEEK) - 1) + "";
        if(weekday.equals("0")) {
    
    
            weekday = "7";
        }

        // 2.8 月的第几个星期
        sdf.applyPattern("W");
        var week_in_month = sdf.format(curDate);

        // 2.9 是否周一
        var is_first_day_in_week = calendar.get(java.util.Calendar.DAY_OF_WEEK) == java.util.Calendar.MONDAY ? "y":"n";

        // 2.10 是否休息日
        var is_dayoff = "n";

        // 2.11 是否工作日
        var is_workday = "n";

        // 2.12 是否国家法定节假日
        var is_holiday = "n";
        // 2.12 国家法定节假日获取URL
        //var holiday_url = "http://timor.tech/api/holiday/info/" + date_value;
		
		var holiday_url = "http://api.haoshenqi.top/holiday?date="+date_value

        // 2.13 日期类型
        var date_type = "workday";

        // 2.14 月份
        sdf.applyPattern("MM");
        var month_number = sdf.format(curDate);

        // 2.15 年份
        sdf.applyPattern("yyyy");
        var year = sdf.format(curDate);

        // 2.16 年份-月份
        sdf.applyPattern("yyyy-MM");
        var year_month_number = sdf.format(curDate);

        // 2.16 季度名称、季度、年季度
        var quarter_name = "";
        var quarter_number = "";
        var year_quarter = "";

        switch (calendar.get(java.util.Calendar.MONTH)) {
    
    
            case java.util.Calendar.FEBRUARY:
            case java.util.Calendar.JANUARY:
            case java.util.Calendar.MARCH:
                quarter_name = "Q1";
                quarter_number = "1";
                year_quarter = year + "-" + quarter_name;
                break;
            case java.util.Calendar.APRIL:
            case java.util.Calendar.MAY:
            case java.util.Calendar.JUNE:
                quarter_name = "Q2";
                quarter_number = "2";
                year_quarter = year + "-" + quarter_name;
                break;
            case java.util.Calendar.JULY:
            case java.util.Calendar.AUGUST:
            case java.util.Calendar.SEPTEMBER:
                quarter_name = "Q3";
                quarter_number = "3";
                year_quarter = year + "-" + quarter_name;
                break;
            case java.util.Calendar.OCTOBER:
            case java.util.Calendar.NOVEMBER:
            case java.util.Calendar.DECEMBER:
                quarter_name = "Q4";
                quarter_number = "4";
                year_quarter = year + "-" + quarter_name;
                break;
        }

3.3 kettle整个流程

整体流程

3.4 运行结果图

运行结果图

小结

         好了到这里我们就成功的实现了这个需求,其实kettle 上还有很多好玩的功能组件,也可以进行一个尝试。喜欢的朋友可以给你一键三连哦,源码获取微信搜搜公众号【大数据老哥】回复:【kettle日期】即可获源码。我们下期见~~~。

微信公众号搜索【大数据老哥】可以获取 200个为你定制的简历模板、大数据面试题、企业面试
题…等等。

资源获取

猜你喜欢

转载自blog.csdn.net/qq_43791724/article/details/111561546
今日推荐