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

2021-02-04 14:13:26 浏览数 (1)

前言

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

一、需求描述

在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表

代码语言:javascript复制
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 代码

代码语言: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 上还有很多好玩的功能组件,也可以进行一个尝试。喜欢的朋友可以给你一键三连哦,源码获取微信搜搜公众号【大数据老哥

0 人点赞