Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions R/pkg/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ exportMethods("%<=>%",
"current_timestamp",
"hash",
"cume_dist",
"make_date",
"date_add",
"date_format",
"date_sub",
Expand Down
31 changes: 31 additions & 0 deletions R/pkg/R/functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ NULL
#' df <- createDataFrame(cbind(model = rownames(mtcars), mtcars))}
NULL

#' Make date time functions
#'
#' @param year The year to represent, from 1 to 9999
#' @param month The month-of-year to represent, from 1 (January) to 12 (December)
#' @param day The day-of-month to represent, from 1 to 31
#'
#' @name make_datetime_functions
#' @rdname make_datetime_functions
#' @family data time functions
NULL
Comment thread
MaxGekk marked this conversation as resolved.
Outdated

#' Date time functions for Column operations
#'
#' Date time functions defined for \code{Column}.
Expand Down Expand Up @@ -4016,3 +4027,23 @@ setMethod("current_timestamp",
jc <- callJStatic("org.apache.spark.sql.functions", "current_timestamp")
column(jc)
})



Comment thread
MaxGekk marked this conversation as resolved.
Outdated
#' @details
#' \code{make_date}: Returns date made from year, month and day.
#'
#' @rdname make_datetime_functions
#' @aliases make_date make_date,Column,Column,Column-method
#' @examples
#' \dontrun{
#' df <- createDataFrame(list(list(2019, 7, 20)), c("year", "month", "day"))
#' head(select(df, make_date(df$year, df$month, df$day)))}
#' @note make_date since 3.0.0
setMethod("make_date",
signature(year = "Column", month = "Column", day = "Column"),
function(year, month, day) {
jc <- callJStatic("org.apache.spark.sql.functions", "make_date",
year@jc, month@jc, day@jc)
column(jc)
})
3 changes: 3 additions & 0 deletions R/pkg/R/generics.R
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,9 @@ setGeneric("xxhash64", function(x, ...) { standardGeneric("xxhash64") })
#' @name NULL
setGeneric("year", function(x) { standardGeneric("year") })

#' @rdname make_datetime_functions
#' @name NULL
setGeneric("make_date", function(year, month, day) { standardGeneric("make_date") })

###################### Spark.ML Methods ##########################

Expand Down
16 changes: 16 additions & 0 deletions python/pyspark/sql/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,22 @@ def ntile(n):

# ---------------------- Date/Timestamp functions ------------------------------

@since(3.0)
def make_date(year, month, day):
"""
Create date from year, month and day.

>>> df = spark.createDataFrame([(2013, 7, 15)], ['year', 'month', 'day'])
>>> df.select(make_date('year', 'month', 'day').alias('date')).collect()
[Row(date=datetime.date(2013, 7, 15))]
"""
sc = SparkContext._active_spark_context
y = _to_java_column(year)
m = _to_java_column(month)
d = _to_java_column(day)
return Column(sc._jvm.functions.make_date(y, m, d))


@since(1.5)
def current_date():
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ object FunctionRegistry {
expression[WeekOfYear]("weekofyear"),
expression[Year]("year"),
expression[TimeWindow]("window"),
expression[MakeDate]("make_date"),

// collection functions
expression[CreateArray]("array"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1605,3 +1605,49 @@ private case class GetTimestamp(
override def withTimeZone(timeZoneId: String): TimeZoneAwareExpression =
copy(timeZoneId = Option(timeZoneId))
}

@ExpressionDescription(
usage = "_FUNC_(year, month, day) - Create date from year, month and day fields.",
arguments = """
Arguments:
* year - the year to represent, from 1 to 9999
* month - the month-of-year to represent, from 1 (January) to 12 (December)
* day - the day-of-month to represent, from 1 to 31
""",
examples = """
Examples:
> SELECT _FUNC_(2013, 7, 15);
'2013-07-15'
Comment thread
MaxGekk marked this conversation as resolved.
Outdated
""",
since = "3.0.0")
case class MakeDate(year: Expression, month: Expression, day: Expression)
extends TernaryExpression with ImplicitCastInputTypes {

override def children: Seq[Expression] = Seq(year, month, day)
override def inputTypes: Seq[AbstractDataType] = Seq(IntegerType, IntegerType, IntegerType)
override def dataType: DataType = DateType
override def nullable: Boolean = true

override def nullSafeEval(year: Any, month: Any, day: Any): Any = {
try {
val ld = LocalDate.of(year.asInstanceOf[Int], month.asInstanceOf[Int], day.asInstanceOf[Int])
localDateToDays(ld)
} catch {
case _: java.time.DateTimeException => null
}
}

override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
val dtu = DateTimeUtils.getClass.getName.stripSuffix("$")
nullSafeCodeGen(ctx, ev, (year, month, day) => {
s"""
try {
${ev.value} = $dtu.localDateToDays(java.time.LocalDate.of($year, $month, $day));
} catch (java.time.DateTimeException e) {
${ev.isNull} = true;
}"""
})
}

override def prettyName: String = "make_date"
}
Original file line number Diff line number Diff line change
Expand Up @@ -918,4 +918,14 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
}

test("creating values of DateType via make_date") {
checkEvaluation(MakeDate(Literal(2013), Literal(7), Literal(15)), Date.valueOf("2013-7-15"))
checkEvaluation(MakeDate(Literal.create(null, IntegerType), Literal(7), Literal(15)), null)
checkEvaluation(MakeDate(Literal(2019), Literal.create(null, IntegerType), Literal(19)), null)
checkEvaluation(MakeDate(Literal(2019), Literal(7), Literal.create(null, IntegerType)), null)
checkEvaluation(MakeDate(Literal(Int.MaxValue), Literal(13), Literal(19)), null)
checkEvaluation(MakeDate(Literal(2019), Literal(13), Literal(19)), null)
checkEvaluation(MakeDate(Literal(2019), Literal(7), Literal(32)), null)
}
}
14 changes: 14 additions & 0 deletions sql/core/src/main/scala/org/apache/spark/sql/functions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2580,6 +2580,20 @@ object functions {
// DateTime functions
//////////////////////////////////////////////////////////////////////////////////////////////

/**
* Makes the date column from the year, month and day columns.
*
* @param year the year to represent, from 1 to 9999
* @param month the month-of-year to represent, from 1 (January) to 12 (December)
* @param day the day-of-month to represent, from 1 to 31
* @return A date, or null if `year` or `month` or `day` are null, or out of their valid range.
* @group datetime_funcs
* @since 3.0.0
*/
def make_date(year: Column, month: Column, day: Column): Column = withExpr {
MakeDate(year.expr, month.expr, day.expr)
}

/**
* Returns the date that is `numMonths` after `startDate`.
*
Expand Down
2 changes: 2 additions & 0 deletions sql/core/src/test/resources/sql-tests/inputs/datetime.sql
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ select date '2001-09-28' + 7;
select 7 + date '2001-09-28';
select date '2001-10-01' - 7;
select date '2001-10-01' - date '2001-09-28';

select make_date(2013, 7, 15);
Comment thread
MaxGekk marked this conversation as resolved.
Outdated
10 changes: 9 additions & 1 deletion sql/core/src/test/resources/sql-tests/results/datetime.sql.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Automatically generated by SQLQueryTestSuite
-- Number of queries: 15
-- Number of queries: 16


-- !query 0
Expand Down Expand Up @@ -129,3 +129,11 @@ select date '2001-10-01' - date '2001-09-28'
struct<datediff(DATE '2001-10-01', DATE '2001-09-28'):int>
-- !query 14 output
3


-- !query 15
select make_date(2013, 7, 15)
-- !query 15 schema
struct<make_date(2013, 7, 15):date>
-- !query 15 output
2013-07-15
Original file line number Diff line number Diff line change
Expand Up @@ -764,4 +764,18 @@ class DateFunctionsSuite extends QueryTest with SharedSQLContext {
Seq(Row(Instant.parse(timestamp))))
}
}

test("make_date") {
val df = Seq(
(1969, 13, 1),
(1970, 1, 1),
(2019, 7, 19),
(9999, 12, 31)).toDF("year", "month", "day")
checkAnswer(df.select(make_date($"year", $"month", $"day")),
Seq(
Row(null),
Row(Date.valueOf("1970-01-01")),
Row(Date.valueOf("2019-07-19")),
Row(Date.valueOf("9999-12-31"))))
}
}