Apache spark Spark SQL年函数
我正在使用spark sql的Apache spark Spark SQL年函数,apache-spark,Apache Spark,我正在使用spark sql的weekofyear函数计算给定日期的周数 我正在使用以下代码 test("udf - week number of the year") { val spark = SparkSession.builder().master("local").appName("udf - week number of the year").getOrCreate() import spark.implicits._ val data1 = Seq("20
weekofyear
函数计算给定日期的周数
我正在使用以下代码
test("udf - week number of the year") {
val spark = SparkSession.builder().master("local").appName("udf - week number of the year").getOrCreate()
import spark.implicits._
val data1 = Seq("20220101", "20220102", "20220103", "20220104", "20220105", "20220106", "20220107", "20220108", "20220109", "20220110", "20220111", "20220112")
data1.toDF("day").createOrReplaceTempView("tbl_day")
spark.sql("select day, to_date(day, 'yyyyMMdd') as date, weekofyear(to_date(day, 'yyyyMMdd')) as week_num from tbl_day").show(truncate = false)
/*
+--------+----------+--------+
|day |date |week_num|
+--------+----------+--------+
|20220101|2022-01-01|52 |
|20220102|2022-01-02|52 |
|20220103|2022-01-03|1 |
|20220104|2022-01-04|1 |
|20220105|2022-01-05|1 |
|20220106|2022-01-06|1 |
|20220107|2022-01-07|1 |
|20220108|2022-01-08|1 |
|20220109|2022-01-09|1 |
|20220110|2022-01-10|2 |
|20220111|2022-01-11|2 |
|20220112|2022-01-12|2 |
+--------+----------+--------+
*/
spark.stop
}
我惊讶地发现20220101的周数是52,但这是2022年的第一天,所以应该是1
我找出weekofyear
的源代码,并发现:
它使用下面的代码创建日历实例,以便给出上面的结果
@transient private lazy val c = {
val c = Calendar.getInstance(DateTimeUtils.getTimeZone("UTC"))
c.setFirstDayOfWeek(Calendar.MONDAY)
c.setMinimalDaysInFirstWeek(4)
c
}
我想问为什么spark sql会这样对待一年中的头几天
作为比较,
1
从“双”菜单中选择“到”数字(到字符(到日期('01/01/2022','MM/DD/YYYY'),'WW'))我将在这里发布我的发现: Spark SQL和Hive遵循ISO-8601标准来计算给定日期的年度周数
需要注意的一点是:Spark SQL内部正在使用
java.util.Calendar
API来完成这项工作,java 8'java.time
API一直在本地支持ISO-8601标准,使用java.time API,我们不必做这些事(c.setminimadaysinfirstweek(4)
)我将在这里发布我的发现:
Spark SQL和Hive遵循ISO-8601标准来计算给定日期的年度周数
需要注意的一点是:Spark SQL内部正在使用
java.util.Calendar
API来完成这项工作,java 8'java.time
API一直在本地支持ISO-8601标准,使用java.time API,我们不必做任何事情(c.setminimadaysinfirstweek(4)
)在Spark 3.0上,您可以使用EXTRACT
函数。举几个例子:
> SELECT extract(YEAR FROM TIMESTAMP '2019-08-12 01:00:00.123456');
2019
> SELECT extract(week FROM timestamp'2019-08-12 01:00:00.123456');
33
> SELECT extract(doy FROM DATE'2019-08-12');
224
> SELECT extract(SECONDS FROM timestamp'2019-10-01 00:00:01.000001');
1.000001
> SELECT extract(days FROM interval 1 year 10 months 5 days);
5
> SELECT extract(seconds FROM interval 5 hours 30 seconds 1 milliseconds 1 microseconds);
30.001001
文档在Spark 3.0上,您可以使用
提取
功能。举几个例子:
> SELECT extract(YEAR FROM TIMESTAMP '2019-08-12 01:00:00.123456');
2019
> SELECT extract(week FROM timestamp'2019-08-12 01:00:00.123456');
33
> SELECT extract(doy FROM DATE'2019-08-12');
224
> SELECT extract(SECONDS FROM timestamp'2019-10-01 00:00:01.000001');
1.000001
> SELECT extract(days FROM interval 1 year 10 months 5 days);
5
> SELECT extract(seconds FROM interval 5 hours 30 seconds 1 milliseconds 1 microseconds);
30.001001
文档是否有任何方法可以更改此方法的一年和一周的开始日期。我不这么认为。要改变这种行为,必须编写一个新的UDF。有没有办法改变这种方法的年和周的开始日期。我不这么认为。要更改行为,必须编写新的UDF。