1、背景
最近对接一些数据,其中有一个日期字段的数据是这样的 26/04/201711:11:17 我需要把它转成正常的YYYY-MM-dd HH:mm:ss的格式,由于文件都在hdfs上,所以只有写spark的udf函数来处理,以前处理spark,都是撸scala,但是最近这个项目主要用java,处理数据只是一个很小的部分,所以打算用java来搞定,因此决定研究下java写spark的udf
spark 版本 2.4.3
scala代码
package org
import java.text.SimpleDateFormat
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.sql.functions._
object SparkParseCSV {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.appName("ParseCSV")
.master("local[2]")
.config("spark.executor.cores", "1")
.config("spark.executor.memory", "1G")
.config("hive.metastore.uris", "thrift://hadoop103:9083")
.enableHiveSupport()
.getOrCreate()
import spark.implicits._
val parseToTimestamp=udf((dstring:String)=>{
val sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val sf1 = new SimpleDateFormat("dd/MM/yyyyHH:mm:ss")
val res=sf.format(sf1.parse(dstring))
res
})
val df = spark.read.format("csv")
.option("header","true")
.load("hdfs://mycluster/test/input/Dataset-Unicauca-Version2-87Atts_test.csv")
.withColumn(
"datetime",parseToTimestamp(col("Timestamp"))
)
df.show()
spark.close()
}
}
java代码
A、思路
//查了下网上的一下相关文章,很多都是使用spark提供的java api 的UDF来重写里面的方法,
//然后再注册方法使用
import org.apache.spark.sql.api.java.UDF1;
spark.udf().register("twoDecimal", new UDF1<Double, Double>() {
@Override
public Double call(Double in) throws Exception {
BigDecimal b = new BigDecimal(in);
double res = b.setScale(2,BigDecimal.ROUND_HALF_DOWN).doubleValue();
return res;
}
但是我用这种方法没有成功,最后开了下源码,仿照着写了下,register需要三个参数
1、函数名
2、函数体
3、返回类型
B、实现
/*
register需要三个参数
1、函数名
2、函数体
3、返回类型
*/
spark.udf().register("parseToTimestamp",(String dstring)->{
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sf1 = new SimpleDateFormat("dd/MM/yyyyHH:mm:ss");
String res=sf.format(sf1.parse(dstring));
return res;
}, DataTypes.StringType);
//在sparksql中,直接使用函数即可
spark.sql("select parseToTimestamp('26/04/201711:11:11'");
//在dsl中,需要使用callUDF调用函数
Dataset df = spark.read.format("csv")
.option("header","true")
.load("hdfs://mycluster/test/input/Dataset-Unicauca-Version2-87Atts_test.csv")
.withColumn(
"datetime",callUDF("parseToTimestamp",col("Timestamp"))
);
df.show()