Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 13 additions & 2 deletions datafusion/functions/src/datetime/date_part.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ use datafusion_macros::user_doc;
- dow (day of the week where Sunday is 0)
- doy (day of the year)
- epoch (seconds since Unix epoch for timestamps/dates, total seconds for intervals)
- isodow (day of the week where Monday is 0)
- isodow (ISO 8601 day of the week where Monday is 1 and Sunday is 7)
"#
),
argument(
Expand Down Expand Up @@ -239,7 +239,18 @@ impl ScalarUDFImpl for DatePartFunc {
"qtr" | "quarter" => date_part(array.as_ref(), DatePart::Quarter)?,
"doy" => date_part(array.as_ref(), DatePart::DayOfYear)?,
"dow" => date_part(array.as_ref(), DatePart::DayOfWeekSunday0)?,
"isodow" => date_part(array.as_ref(), DatePart::DayOfWeekMonday0)?,
"isodow" => {
// Postgres `isodow` is 1..=7 with Mon=1. Arrow's
// `DayOfWeekMonday0` returns 0..=6 with Mon=0; shift by
// +1 to match Postgres. TODO: switch to a future
// `DatePart::DayOfWeekMonday1` upstream variant once it
// exists, so this kernel-then-add becomes a single call.
let zero_based =
date_part(array.as_ref(), DatePart::DayOfWeekMonday0)?;
let int_arr = as_int32_array(&zero_based)?;
let one_based: Int32Array = int_arr.unary(|v| v + 1);
Arc::new(one_based) as ArrayRef
}
"epoch" => epoch(array.as_ref())?,
_ => return exec_err!("Date part '{part}' not supported"),
}
Expand Down
7 changes: 5 additions & 2 deletions datafusion/spark/src/function/datetime/date_part.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,11 @@ impl ScalarUDFImpl for SparkDatePart {
));

match part {
// Add 1 for day-of-week parts to convert 0-indexed to 1-indexed
"dow" | "isodow" => Ok(ExprSimplifyResult::Simplified(
// Spark's `dayofweek` is 1..=7 (Sun=1) but df's `dow` is 0..=6
// (Sun=0); shift by +1. df's `isodow` already returns the
// PG-correct 1..=7 (Mon=1), which matches Spark's
// `dayofweek_iso`/`dow_iso`, so no shift is needed there.
"dow" => Ok(ExprSimplifyResult::Simplified(
date_part_expr + Expr::Literal(ScalarValue::Int32(Some(1)), None),
)),
_ => Ok(ExprSimplifyResult::Simplified(date_part_expr)),
Expand Down
8 changes: 4 additions & 4 deletions datafusion/sqllogictest/test_files/datetime/date_part.slt
Original file line number Diff line number Diff line change
Expand Up @@ -1240,22 +1240,22 @@ true
query I
SELECT date_part('ISODOW', CAST('2000-01-01' AS DATE))
----
5
6

query I
SELECT EXTRACT(isodow FROM to_timestamp('2020-09-08T12:00:00+00:00'))
----
1
2

query I
SELECT EXTRACT("isodow" FROM to_timestamp('2020-09-08T12:00:00+00:00'))
----
1
2

query I
SELECT EXTRACT('isodow' FROM to_timestamp('2020-09-08T12:00:00+00:00'))
----
1
2

## Preimage tests

Expand Down
2 changes: 1 addition & 1 deletion docs/source/user-guide/sql/scalar_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2573,7 +2573,7 @@ date_part(part, expression)
- dow (day of the week where Sunday is 0)
- doy (day of the year)
- epoch (seconds since Unix epoch for timestamps/dates, total seconds for intervals)
- isodow (day of the week where Monday is 0)
- isodow (ISO 8601 day of the week where Monday is 1 and Sunday is 7)

- **expression**: Time expression to operate on. Can be a constant, column, or function.

Expand Down
Loading