0
点赞
收藏
分享

微信扫一扫

完美生成年度节假日表,Kettle还能这么玩!



写在前面:​ 博主是一名大数据初学者,昵称来源于《爱丽丝梦游仙境》中的Alice和自己的昵称。作为一名互联网小白,​​写博客一方面是为了记录自己的学习历程,一方面是希望能够帮助到很多和自己一样处于起步阶段的萌新​​。由于水平有限,博客中难免会有一些错误,有纰漏之处恳请各位大佬不吝赐教


        之前已经分享了几篇博客,算是为大家带来了Kettle中较为常用操作。本篇博客,博主为大家再分享一个​Kettle的骚操作​,保准在座的各位想不到

完美生成年度节假日表,Kettle还能这么玩!_云计算/大数据

        好了多的话咋不说了,先来看看需求

  • 请使用Kettle生成一个Excel表格,记录2019年度的所有日期,其中需要包含以下字段

序号

字段

类型

示范值

含义

1

date_key

string

20000101

代理键

2

date_value

string

2000-01-01

年-月-日

3

day_in_year

string

1

当年的第几天

4

day_in_month

string

1

当月的第几天

5

is_first_day_in_month

string

y、n

是否月的第一天

6

is_last_day_in_month

string

y、n

是否月的最后一天

7

weekday

string

星期一

星期

8

week_in_month

string

1

月的第几个星期

9

is_first_day_in_week

string

y、n

是否周一

10

is_dayoff

string

y、n

是否休息日

11

is_workday

string

y、n

是否工作日

12

is_holiday

string

y、n

是否国家法定节假日

13

date_type

string

workday、weekend、holiday

日期类型

工作日:workday

国家法定节假日:holiday

休息日:weekend

14

month_number

string

1、2、… 12

月份

15

year

string

2000

年份

16

quarter_name

string

Q1

季度名称

17

quarter_number

string

1

季度

18

year_quarter

string

2000-Q1

年-季度

19

year_month_number

string

2000-01

年-月份

        看完是不是就一个反应

完美生成年度节假日表,Kettle还能这么玩!_java_02

        ​为了能更加了解大家的想法,我特意现场采访了几个朋友,来看看他们怎么说

A:在我的印象中,Kettle就像水壶一样,可以把各种数据放到一个壶里,然后以一种指定的格式流出。

B:这我也知道,但是这一题需要一整年的数据,我该怎么解决,难不成去百度?

C:去百度的话,帅气的博主还需要费劲口舌跟大伙讲这么久吗?但具体怎么实现,我也暂时没有思路,恳请菌哥指点!

        果然还是有明眼人的哈哈,不要慌,接下来本博主就教各位如何实现。


完美生成年度节假日表,Kettle还能这么玩!_Java_03

1. 确定需要使用到的组件

        因为我们需要的是2019年的所有日期数据,所以也就是365条。我们需要一个​生成记录​的组件,并设置数据条数的限制

完美生成年度节假日表,Kettle还能这么玩!_Hadoop_04

这个时候有人按捺不住了

B:不是需要一年的数据吗,为啥不在生成记录组件里的字段上设置啊?

C: 肯定不能啊,生成记录里面的数据只能写固定的,都靠自己写的话,还要讨论这么多作什么?


完美生成年度节假日表,Kettle还能这么玩!_云计算/大数据_05

哎,我说你们二位能否给我安静一会,咋咋呼呼的。怎么解决动态生成日期的问题,继续听我说不就完了…

        因为该题需要生成一年的动态时间,所以难免需要用到JavaScript代码,在代码中我们可以初始化一个时间,然后再加入一个外部传入的参数,对时间进行累加,这样就可以每次得到不同的时间。

        我们可以先尝试着加入一个​增加序列​的组件,设置序列。

完美生成年度节假日表,Kettle还能这么玩!_Kettle_06

        上述我们设置了一个名为​​DayNum​​的序列变量,接下来我们就需要再添加一个​JavaScript代码组件​,在里面书写JS代码,同时利用到我们的​​DayNum​​组件,就可以获取到不同的时间。

        在这个组件中,我们需要留意的地方已经在下图中标注出来了。

完美生成年度节假日表,Kettle还能这么玩!_Kettle_07

        首先是在上一步生成的序列变量​​DayNum​​,我们可以在JS中直接引用。还有需要设置​步骤名​,​JS代码区​,最后最最关键的就是设置​需要保存的字段​,不然辛辛苦苦写了大半天的代码最后没设置需要保存不是折了。

        最后生成了所有我们需要的字段后,依题意得,我们还需要一个​Excel输出组件​,接收我们上一步生成的数据并做输出。

完美生成年度节假日表,Kettle还能这么玩!_云计算/大数据_08

        最后总结一下整体的流程

完美生成年度节假日表,Kettle还能这么玩!_云计算/大数据_09

        首先我们需要生成365条数据,然后需要添加一个序列变量,接着在JavaScript代码中使用到序列变量得到最新的时间,然后获取到题目所需要的那些字段后,我们设置字段保存之后,就可以利用Excel进行输出了。

A:我淦,我好像懂了,感谢菌哥分享

B:搞得你懂了就会写一样,菌哥,我看了你梳理的思路,确实不错,但我可能理解能力偏差,你能接下来讲点细节的东西吗?

C:是啊,我也觉得JS代码那部分好难啊,学了这么久大数据,之前的那点JS基础早就没了,菌哥能教教我们吗?

完美生成年度节假日表,Kettle还能这么玩!_Java_10

        既然大家的学习热情都这么高,那我们就继续吧!

2. 流程剖析

在第一步我们也谈到了,需要使用到的组件有这四个。

完美生成年度节假日表,Kettle还能这么玩!_Kettle_11

生成记录,作用就是确定最后数据的生成条数

增加序列,就是为了生成一个指定范围内的连续数字变量,供后面的的JavaScript的代码调用获取不同的时间

JavaScript代码的书写将是我们下面具体要讲的内容,也是该需要的核心部分

Excel输出,将保存的结果输出到指定的路径

其他几个组件确实没什么需要注意的点,下面我将带着大家书写JavaScript的代码

3. 书写JS代码

上面有小伙伴反应,JS太久没写了,有点生疏,那么接下来我们就先用Java代码来写。

public class ProduceDateDate {

public static void main(String[] args) throws ParseException {

// 初始化日期
String initDate = "2000-01-01";

// 变量N 天(测试阶段先写死,投入到正式使用用序列字段代替)
int add = 1;

// 设置日期的格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

//将String转换为Date
Date parseTime = simpleDateFormat.parse(initDate);

// 初始化一个日历对象
Calendar calendar = Calendar.getInstance();

// 设置日历的初始值
calendar.setTime(parseTime);

// 输出日期数据 2000-01-01
//System.out.println(simpleDateFormat.format(calendar.getTime()));

// 日期+1
calendar.add(Calendar.DAY_OF_MONTH,add);

// 最新的时间: 例如 2000-01-02
String date_value = simpleDateFormat.format(calendar.getTime());

在上面的Java代码中,完成了生成不同时间的功能,这个时候如果想把它投放到JS代码中,照搬肯定是不行的。想要变成JS语法,我们需要先注意下面点:

完美生成年度节假日表,Kettle还能这么玩!_Hadoop_12

接下来我们开始熟悉了规则之后,就正式开始写JS代码

// 初始化日期
var initDate = "2019-01-01";

// 变量N 天(编号)
var add = 1;

// 设置日期的格式
var simpleDateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd");

//将String转换为Date
var parseTime = simpleDateFormat.parse(initDate);

// 初始化一个日历对象
var calendar = java.util.Calendar.getInstance();

// 设置日历的初始值
calendar.setTime(parseTime);

// 输出日期数据 2000-01-01
//System.out.println(simpleDateFormat.format(calendar.getTime()));

// 日期 + DayNum(序列变量)
calendar.add(java.util.Calendar.DAY_OF_MONTH,DayNum);

// 最新的时间: 例如 2000-01-02
/* 2. 年月日 */
var date_value = simpleDateFormat.format(calendar.getTime());

/* 1. 代理键 */
var date_key = date_value.replace("-", "");

//System.out.println("word1:"+word1);
// 解析最新的时间 string-> date
parseTime = simpleDateFormat.parse(date_value);
// 设置给日历对象
calendar.setTime(parseTime);
// 调用方法获取到当前时间是一年的第几天
/* 3. 当年的第几天 */
var day_in_year = calendar.get(java.util.Calendar.DAY_OF_YEAR);
//System.out.println(day_in_year);

/* 4. 当月的第几天 */
var day_in_month = calendar.get(java.util.Calendar.DAY_OF_MONTH)+"";
//System.out.println(day_in_month);

/* 5. 是否月的第一天 */
var is_first_day_in_month = "";
if (day_in_month==1){

is_first_day_in_month="y";
}else {
is_first_day_in_month="n";
}

// 获取到当前月最大的天数 31
var lastDay = calendar.getActualMaximum(java.util.Calendar.DATE);

/* 6. 是否月的最后一天 */
var is_last_day_in_month = "";

if (day_in_month==lastDay){

is_last_day_in_month = "y";
}else {
is_last_day_in_month = "n";
}


/* 7. 星期数 */
var weekday = calendar.get(java.util.Calendar.DAY_OF_WEEK);

/* 8. 月的第几个星期 */
var week_in_month = calendar.get(java.util.Calendar.WEEK_OF_MONTH);

/* 9. 是否是周一,国外以周日作为一周的第一天,这里我们需要将判断的结果+1 */
var is_first_day_in_week = "";
if (weekday==2){
is_first_day_in_week = "y";
}else {
is_first_day_in_week = "n";
}

//请求的url
var url = null;
//输入流的缓冲
var tmpInfo = null;


// 开始调用API
// 因为调用有失败的风险,所以这里设置了循环,如果失败则重复执行
for (var i = 0; i < 5; i++) {
//创建一个临时变量用来保存json
tmpInfo = java.lang.StringBuffer();
//读取文件
var ins = null;
//创建url
var urlStr = "https://timor.tech/api/holiday/info/" + date_value;
url = java.net.URL(urlStr);
var str = null;
try {
//调用API
ins = java.io.BufferedReader(java.io.InputStreamReader(url.openStream(), "UTF-8"));
//一行一行进行读入
while ((str = ins.readLine()) != null) {
tmpInfo.append(str);
}
// 如果成功了,就结束循环
// 否则就重新遍历
break;
} catch (err) {

} finally {
if (ins != null) {
ins.close(); //关闭流
}
}
}

// 将数据转换为字符串String
var result = tmpInfo.toString();
// 利用JSON解析对象
var obj = JSON.parse(result);
// 获取到type属性
var type = obj.type;

/* 13. 提前定义一个变量,保存日期类型*/
var date_type = "";

/* 10. 是否休息日 */
var is_dayoff = "";
if (type.type == "1"){
is_dayoff="y"
date_type = "weekend"
}else {
is_dayoff="n"
}

/* 11. 是否工作日 */
var is_workday = "";
if (type.type == "0"){
is_workday="y"
date_type = "workday"
}else {
is_workday="n"
}

/* 12. 是否国家法定节假日 */
var is_holiday = "";

if (type.type == "2") {
is_holiday = "y";
date_type = "workday";

}else {
is_holiday = "n";
}


/**/

/* 14. 月份 */
var month_number = calendar.get(java.util.Calendar.MONTH)+1;

/* 15. 年份 */
var year = calendar.get(java.util.Calendar.YEAR);

/* 16. 季度 */
var quarter_number = parseInt(calendar.get(java.util.Calendar.MONTH) / 3 + 1);

/* 17. 季度名称 */
var quarter_name = "Q"+parseInt(quarter_number);

/* 18. 年-季度 */
var year_quarter = year + "-"+quarter_name;

/* 19. 年-月份 */
var year_month_number = date_value.substring(0,7);

在JS代码中获取到对应需求的每一个字段,都有​清楚的序号和中文注释标注

只要是有一定Java基础的朋友我相信都能看懂

另外,由于需要根据日期获取到不同日期是否为国家节假日或者休息日,工作日等分类,因此调用了API来辅助完成

4. 测试

我们在编译器中写好的JS代码,复制粘贴到我们Kettle的JS代码区组件中

就像我所展示的图一样

完美生成年度节假日表,Kettle还能这么玩!_Kettle_07

然后在设置好了Excel输出组件之后,我们点击运行

发现生成的结果​完美​符合题目需求

完美生成年度节假日表,Kettle还能这么玩!_java_14

等会,话没说完…

A:牛X,我要给你生猴子…

B:给大佬端茶…

C:(一脸鄙夷…)感谢大佬分享,给你点个赞


完美生成年度节假日表,Kettle还能这么玩!_Java_15

总结

        感谢能看到这里的朋友????

        本次的分享就到这里,萌新小白借此只是想以​更好的方式​为大家分享有趣的知识????

        ​如果以上过程中出现了任何的纰漏错误,烦请大佬们指正????

        ​受益的朋友或对大数据技术感兴趣的伙伴记得点赞关注支持一波????



举报

相关推荐

0 条评论