我想获得两个日期之间的月数,我正在从csv文件中读取开始日期和结束日期。
id startDate endDate
100 5/1/2016 5/1/2017
200 5/2/2016 5/1/2017
300 5/2/2016 5/1/2017
我的输出应该如下:
id startDate endDate res
100 5/1/2016 5/1/2017 12
200 5/2/2016 5/1/2017 11
300 5/3/2016 5/1/2017 10
请告诉我代码中的错误,
val data = spark.read.option("header", "true").csv("sample.csv");
val result = data.withColumn("res", withColumn("Months", ChronoUnit.MONTHS.between(startDate ,endDate)).show()
答案 0 :(得分:1)
以下是如何使用Spark实现的:
import org.apache.spark.sql.functions
import spark.implicits._
val result = data.withColumn(
"res",
functions.months_between(
functions.to_date($"endDate", "M/d/yyyy"),
functions.to_date($"startDate", "M/d/yyyy")
)
)
withColumn
的第二个参数是Spark的Column
类型。您无法将任意Java / Scala表达式传递给它。
请注意,to_date
仅在Spark 2.2.0中添加。
如果您使用的是较旧版本的Spark,则可以定义UDF,这是一种自定义函数,可将字符串转换为特定格式的日期:
import java.time.format.DateTimeFormatter
import java.time.LocalDate
import java.sql.Date
val strToDate = functions.udf {
val fmt = DateTimeFormatter.ofPattern("M/d/yyyy")
date: String =>
Date.valueOf(LocalDate.parse(date, fmt))
}
现在,配备strToDate
,我们可以将字符串columsn转换为日期并应用months_之间:
val result = data.withColumn(
"res",
functions.months_between(
strToDate($"endDate"),
strToDate($"startDate")
)
)
答案 1 :(得分:1)
语法:
val dt = sqlcontext.sql("SELECT DATEDIFF(month, start_date, end_date) AS DateDiff from relation")
您可以参考以下日期链接:Datediff
以下是一个类似的问题:stackoverflow
答案 2 :(得分:0)
您可以使用提供的名为months_between
,
import org.apache.spark.sql.functions._
val result = data.withColumn("monthsBetween", months_between($"startDate", $"endDate"))
答案 3 :(得分:0)
您的代码的问题只是类型转换。因此,在阅读时,您需要推断您的架构。如果要打印架构,可以注意到所有列都是字符串类型。因此,months_between函数返回null
值。
data.printSchema()
root |-- id: string (nullable = true) |-- startDate: string (nullable = true) |-- endDate: string (nullable = true)
您可以使用以下代码:
val data = sqlContext.read
.option("header", "true")
.option("dateFormat", "d/M/yyyy")
.option("inferSchema", "true")
.csv("sample.csv")
data.printSchema()
root |-- id: integer (nullable = true) |-- startDate: timestamp (nullable = true) |-- endDate: timestamp (nullable = true)
import org.apache.spark.sql.functions
val result = data.withColumn("res", functions.months_between($"endDate", $"startDate"))
result.show()
+---+--------------------+--------------------+----+ | id| startDate| endDate| res| +---+--------------------+--------------------+----+ |100|2016-01-05 00:00:...|2017-01-05 00:00:...|12.0| |200|2016-02-05 00:00:...|2017-01-05 00:00:...|11.0| |300|2016-03-05 00:00:...|2017-01-05 00:00:...|10.0| +---+--------------------+--------------------+----+