如何在scala中获取周开始日期
我编写了下面的代码来获取传递日期的星期一日期,基本上创建了一个udf来传递日期并获取它的星期一日期如何在scala中获取周开始日期,scala,date,apache-spark,user-defined-functions,Scala,Date,Apache Spark,User Defined Functions,我编写了下面的代码来获取传递日期的星期一日期,基本上创建了一个udf来传递日期并获取它的星期一日期 def calculate_weekstartUDF = udf((pro_rtc:String)=>{ val df = new SimpleDateFormat("yyyy-MM-dd").parse(pro_rtc) val cal = Calendar.getInstance() cal.setTime(df) cal.set(Calendar.DAY_OF_WEEK
def calculate_weekstartUDF = udf((pro_rtc:String)=>{
val df = new SimpleDateFormat("yyyy-MM-dd").parse(pro_rtc)
val cal = Calendar.getInstance()
cal.setTime(df)
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
//Get this Monday date
val Period=cal.getTime()
})
在下面的代码中使用上述UDF
flattedJSON.withColumn(“weekstartdate”,calculate\u weekstartUDF($“pro\u rtc”)).show()
有没有更好的方法来实现这一点。您可以使用Java 8 Date API:
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.{TemporalField, WeekFields}
import java.util.Locale
def calculate_weekstartUDF =
(pro_rtc:String)=>{
val localDate = LocalDate.parse(pro_rtc); // By default parses a string in YYYY-MM-DD format.
val dayOfWeekField = WeekFields.of(Locale.getDefault).dayOfWeek()
localDate.`with`(dayOfWeekField, 1)
}
当然,如果要使用另一个
Locale
,请指定除Locale.getDefault
以外的内容 您可以使用Java 8 Date API:
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.{TemporalField, WeekFields}
import java.util.Locale
def calculate_weekstartUDF =
(pro_rtc:String)=>{
val localDate = LocalDate.parse(pro_rtc); // By default parses a string in YYYY-MM-DD format.
val dayOfWeekField = WeekFields.of(Locale.getDefault).dayOfWeek()
localDate.`with`(dayOfWeekField, 1)
}
当然,如果要使用另一个Locale
,请指定除Locale.getDefault
以外的内容 试试这个:
在我的示例中,“pro_rtc”以秒为单位。如果需要,调整
import org.apache.spark.sql.functions._
dataFrame
.withColumn("Date", to_date(from_unixtime(col("pro_rtc"))))
.withColumn("Monday", expr("date_sub(Date, dayofweek(Date) - 2)"))
这样,您还可以利用Spark的查询引擎,避免UDF的延迟尝试以下方法:
在我的示例中,“pro_rtc”以秒为单位。如果需要,调整
import org.apache.spark.sql.functions._
dataFrame
.withColumn("Date", to_date(from_unixtime(col("pro_rtc"))))
.withColumn("Monday", expr("date_sub(Date, dayofweek(Date) - 2)"))
这样,您还可以利用Spark的查询引擎,避免UDF的延迟尝试使用Spark中的
date\u sub,next\u day
函数使用这种方法
说明:
示例:
date_sub(
next_day('dt,"monday"), //get next monday date
7)) //substract week from the date
val df =Seq(("2019-08-06")).toDF("dt")
import org.apache.spark.sql.functions._
df.withColumn("week_strt_day",date_sub(next_day('dt,"monday"),7)).show()
+----------+-------------+
| dt|week_strt_day|
+----------+-------------+
|2019-08-06| 2019-08-05|
+----------+-------------+
结果:
date_sub(
next_day('dt,"monday"), //get next monday date
7)) //substract week from the date
val df =Seq(("2019-08-06")).toDF("dt")
import org.apache.spark.sql.functions._
df.withColumn("week_strt_day",date_sub(next_day('dt,"monday"),7)).show()
+----------+-------------+
| dt|week_strt_day|
+----------+-------------+
|2019-08-06| 2019-08-05|
+----------+-------------+
使用spark中的日期、下一天功能尝试此方法 说明:
示例:
date_sub(
next_day('dt,"monday"), //get next monday date
7)) //substract week from the date
val df =Seq(("2019-08-06")).toDF("dt")
import org.apache.spark.sql.functions._
df.withColumn("week_strt_day",date_sub(next_day('dt,"monday"),7)).show()
+----------+-------------+
| dt|week_strt_day|
+----------+-------------+
|2019-08-06| 2019-08-05|
+----------+-------------+
结果:
date_sub(
next_day('dt,"monday"), //get next monday date
7)) //substract week from the date
val df =Seq(("2019-08-06")).toDF("dt")
import org.apache.spark.sql.functions._
df.withColumn("week_strt_day",date_sub(next_day('dt,"monday"),7)).show()
+----------+-------------+
| dt|week_strt_day|
+----------+-------------+
|2019-08-06| 2019-08-05|
+----------+-------------+
tl;博士
2019-01-21
避免遗留日期时间类
您正在使用可怕的日期时间类,这些类在几年前被JSR310中定义的现代java.time类所取代
java.time
您的输入字符串是标准格式的。默认情况下,java.time类在解析/生成字符串时使用这些标准格式。因此,无需指定格式化模式
下面是Java语法示例代码。(我不知道斯卡拉)
要从该日期移动到另一日期,请使用。你可以在班上找到几个
使用枚举指定一周中的一天,预定义七个对象,一周中的每一天一个
TemporalAdjuster ta = TemporalAdjusters.previous( DayOfWeek.MONDAY ) ;
LocalDate previousMonday = ld.with( ta ) ;
看这个
2019年1月21日,星期一
如果开始日期恰好是星期一,并且您希望继续保持该日期,请使用备用调整器。tl;博士
2019-01-21
避免遗留日期时间类
您正在使用可怕的日期时间类,这些类在几年前被JSR310中定义的现代java.time类所取代
java.time
您的输入字符串是标准格式的。默认情况下,java.time类在解析/生成字符串时使用这些标准格式。因此,无需指定格式化模式
下面是Java语法示例代码。(我不知道斯卡拉)
要从该日期移动到另一日期,请使用。你可以在班上找到几个
使用枚举指定一周中的一天,预定义七个对象,一周中的每一天一个
TemporalAdjuster ta = TemporalAdjusters.previous( DayOfWeek.MONDAY ) ;
LocalDate previousMonday = ld.with( ta ) ;
看这个
2019年1月21日,星期一
如果开始日期恰好是星期一,并且您希望继续使用该日期,请使用备用调节器。解决此问题的最简单方法是使用beginingofweek
和endOfWeek
函数。它们也是最灵活的,因为它们可以很容易地针对不同的周末日期进行配置
假设您有以下数据集:
+----------+
| some_date|
+----------+
|2020-12-27|
|2020-12-28|
|2021-01-03|
|2020-12-12|
| null|
+----------+
假设一周在星期三结束,下面是如何计算一周的开始和结束时间:
导入com.github.mrpowers.spark.daria.sql.functions_
df
.带列(“周末”,周末(列(“某个日期”),“周三”))
.使用列(“周的开始”,周的开始(列(“某个日期”),“星期三”))
.show()
结果如下:
+----------+-----------+-----------------+
| some_date|end_of_week|beginning_of_week|
+----------+-----------+-----------------+
|2020-12-27| 2020-12-30| 2020-12-24|
|2020-12-28| 2020-12-30| 2020-12-24|
|2021-01-03| 2021-01-06| 2020-12-31|
|2020-12-12| 2020-12-16| 2020-12-10|
| null| null| null|
+----------+-----------+-----------------+
有关底层实现,请参阅。更详细地解释这些函数。解决此问题的最简单方法是使用beginingofweek
和endOfWeek
函数。它们也是最灵活的,因为它们可以很容易地针对不同的周末日期进行配置
假设您有以下数据集:
+----------+
| some_date|
+----------+
|2020-12-27|
|2020-12-28|
|2021-01-03|
|2020-12-12|
| null|
+----------+
假设一周在星期三结束,下面是如何计算一周的开始和结束时间:
导入com.github.mrpowers.spark.daria.sql.functions_
df
.带列(“周末”,周末(列(“某个日期”),“周三”))
.使用列(“周的开始”,周的开始(列(“某个日期”),“星期三”))
.show()
结果如下:
+----------+-----------+-----------------+
| some_date|end_of_week|beginning_of_week|
+----------+-----------+-----------------+
|2020-12-27| 2020-12-30| 2020-12-24|
|2020-12-28| 2020-12-30| 2020-12-24|
|2021-01-03| 2021-01-06| 2020-12-31|
|2020-12-12| 2020-12-16| 2020-12-10|
| null| null| null|
+----------+-----------+-----------------+
有关底层实现,请参阅。更详细地解释这些函数。获取此错误
不支持java.time.LocalDate类型的架构
BTW输入可能是unix时间格式?获取此错误不支持java.time.LocalDate类型的架构
BTW输入可能是unix时间格式?是否可以发布确切的日期格式?是,当然有更好的方法(至少有一种)。我建议您不要使用SimpleDateFormat
和Calendar
。这些类设计得很糟糕,而且早已过时,其中前者尤其令人讨厌。请改用LocalDate
和DateTimeFormatter
,这两种格式都来自。您可以发布确切的日期格式吗?是的,当然有更好的方法(至少有一种)。我建议您不要使用SimpleDateFormat
和Calendar
。这些类设计得很糟糕,而且早已过时,其中前者尤其令人讨厌。改为使用LocalDate
和DateTimeFormatter
,这两种格式都是从日期开始的。date\u sub(date,dayofweek(date)-1)
将给出星期天而不是星期一,无论如何,感谢您的回答:)正确。我会解决它,即使现在有一个问题dayofweek
只适用于星期天,你确定吗?我检查了7天date\u sub(date,dayofweek(date)-1)
将给出星期天,但不是星期一,无论如何,感谢您的回答:)正确。我会解决它,即使现在有一个问题dayofweek
只适用于星期天,你确定吗?我查过了