You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by ti...@apache.org on 2026/04/02 21:47:53 UTC
(datafusion-python) branch main updated: Add missing datetime functions (#1467)
This is an automated email from the ASF dual-hosted git repository.
timsaucer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-python.git
The following commit(s) were added to refs/heads/main by this push:
new 0113a6ee Add missing datetime functions (#1467)
0113a6ee is described below
commit 0113a6ee55cc61f9ebd897ae8cfc9213f560e468
Author: Tim Saucer <ti...@gmail.com>
AuthorDate: Thu Apr 2 17:47:47 2026 -0400
Add missing datetime functions (#1467)
* Add missing datetime functions: make_time, current_timestamp, date_format
Closes #1451. Adds make_time Rust binding and Python wrapper, and adds
current_timestamp (alias for now) and date_format (alias for to_char)
Python functions.
Co-Authored-By: Claude Opus 4.6 (1M context) <no...@anthropic.com>
* Add unit tests for make_time, current_timestamp, and date_format
Co-Authored-By: Claude Opus 4.6 (1M context) <no...@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <no...@anthropic.com>
---
crates/core/src/functions.rs | 2 ++
python/datafusion/functions.py | 36 ++++++++++++++++++++++++++++++++++++
python/tests/test_functions.py | 33 +++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
diff --git a/crates/core/src/functions.rs b/crates/core/src/functions.rs
index c3213405..6996dca9 100644
--- a/crates/core/src/functions.rs
+++ b/crates/core/src/functions.rs
@@ -616,6 +616,7 @@ expr_fn!(date_part, part date);
expr_fn!(date_trunc, part date);
expr_fn!(date_bin, stride source origin);
expr_fn!(make_date, year month day);
+expr_fn!(make_time, hour minute second);
expr_fn!(to_char, datetime format);
expr_fn!(translate, string from to, "Replaces each character in string that matches a character in the from set with the corresponding character in the to set. If from is longer than to, occurrences of the extra characters in from are deleted.");
@@ -974,6 +975,7 @@ pub(crate) fn init_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(date_part))?;
m.add_wrapped(wrap_pyfunction!(date_trunc))?;
m.add_wrapped(wrap_pyfunction!(make_date))?;
+ m.add_wrapped(wrap_pyfunction!(make_time))?;
m.add_wrapped(wrap_pyfunction!(digest))?;
m.add_wrapped(wrap_pyfunction!(ends_with))?;
m.add_wrapped(wrap_pyfunction!(exp))?;
diff --git a/python/datafusion/functions.py b/python/datafusion/functions.py
index f062cbfc..3c8d2bce 100644
--- a/python/datafusion/functions.py
+++ b/python/datafusion/functions.py
@@ -128,7 +128,9 @@ __all__ = [
"cume_dist",
"current_date",
"current_time",
+ "current_timestamp",
"date_bin",
+ "date_format",
"date_part",
"date_trunc",
"datepart",
@@ -200,6 +202,7 @@ __all__ = [
"make_array",
"make_date",
"make_list",
+ "make_time",
"max",
"md5",
"mean",
@@ -1948,6 +1951,15 @@ def now() -> Expr:
return Expr(f.now())
+def current_timestamp() -> Expr:
+ """Returns the current timestamp in nanoseconds.
+
+ See Also:
+ This is an alias for :py:func:`now`.
+ """
+ return now()
+
+
def to_char(arg: Expr, formatter: Expr) -> Expr:
"""Returns a string representation of a date, time, timestamp or duration.
@@ -1970,6 +1982,15 @@ def to_char(arg: Expr, formatter: Expr) -> Expr:
return Expr(f.to_char(arg.expr, formatter.expr))
+def date_format(arg: Expr, formatter: Expr) -> Expr:
+ """Returns a string representation of a date, time, timestamp or duration.
+
+ See Also:
+ This is an alias for :py:func:`to_char`.
+ """
+ return to_char(arg, formatter)
+
+
def _unwrap_exprs(args: tuple[Expr, ...]) -> list:
return [arg.expr for arg in args]
@@ -2270,6 +2291,21 @@ def make_date(year: Expr, month: Expr, day: Expr) -> Expr:
return Expr(f.make_date(year.expr, month.expr, day.expr))
+def make_time(hour: Expr, minute: Expr, second: Expr) -> Expr:
+ """Make a time from hour, minute and second component parts.
+
+ Examples:
+ >>> ctx = dfn.SessionContext()
+ >>> df = ctx.from_pydict({"h": [12], "m": [30], "s": [0]})
+ >>> result = df.select(
+ ... dfn.functions.make_time(dfn.col("h"), dfn.col("m"),
+ ... dfn.col("s")).alias("t"))
+ >>> result.collect_column("t")[0].as_py()
+ datetime.time(12, 30)
+ """
+ return Expr(f.make_time(hour.expr, minute.expr, second.expr))
+
+
def translate(string: Expr, from_val: Expr, to_val: Expr) -> Expr:
"""Replaces the characters in ``from_val`` with the counterpart in ``to_val``.
diff --git a/python/tests/test_functions.py b/python/tests/test_functions.py
index 37d349c5..08420826 100644
--- a/python/tests/test_functions.py
+++ b/python/tests/test_functions.py
@@ -1107,6 +1107,39 @@ def test_today_alias_matches_current_date(df):
assert result.column(0) == result.column(1)
+def test_current_timestamp_alias_matches_now(df):
+ result = df.select(
+ f.now().alias("now"),
+ f.current_timestamp().alias("current_timestamp"),
+ ).collect()[0]
+
+ assert result.column(0) == result.column(1)
+
+
+def test_date_format_alias_matches_to_char(df):
+ result = df.select(
+ f.to_char(
+ f.to_timestamp(literal("2021-01-01T00:00:00")), literal("%Y/%m/%d")
+ ).alias("to_char"),
+ f.date_format(
+ f.to_timestamp(literal("2021-01-01T00:00:00")), literal("%Y/%m/%d")
+ ).alias("date_format"),
+ ).collect()[0]
+
+ assert result.column(0) == result.column(1)
+ assert result.column(0)[0].as_py() == "2021/01/01"
+
+
+def test_make_time(df):
+ ctx = SessionContext()
+ df_time = ctx.from_pydict({"h": [12], "m": [30], "s": [0]})
+ result = df_time.select(
+ f.make_time(column("h"), column("m"), column("s")).alias("t")
+ ).collect()[0]
+
+ assert result.column(0)[0].as_py() == time(12, 30)
+
+
def test_arrow_cast(df):
df = df.select(
# we use `string_literal` to return utf8 instead of `literal` which returns
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org