datafusion_functions/datetime/mod.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! date & time DataFusion functions
19
20use std::sync::Arc;
21
22use datafusion_expr::ScalarUDF;
23
24pub mod common;
25pub mod current_date;
26pub mod current_time;
27pub mod date_bin;
28pub mod date_part;
29pub mod date_trunc;
30pub mod from_unixtime;
31pub mod make_date;
32pub mod now;
33pub mod to_char;
34pub mod to_date;
35pub mod to_local_time;
36pub mod to_timestamp;
37pub mod to_unixtime;
38
39// create UDFs
40make_udf_function!(current_date::CurrentDateFunc, current_date);
41make_udf_function!(current_time::CurrentTimeFunc, current_time);
42make_udf_function!(date_bin::DateBinFunc, date_bin);
43make_udf_function!(date_part::DatePartFunc, date_part);
44make_udf_function!(date_trunc::DateTruncFunc, date_trunc);
45make_udf_function!(make_date::MakeDateFunc, make_date);
46make_udf_function!(from_unixtime::FromUnixtimeFunc, from_unixtime);
47make_udf_function!(now::NowFunc, now);
48make_udf_function!(to_char::ToCharFunc, to_char);
49make_udf_function!(to_date::ToDateFunc, to_date);
50make_udf_function!(to_local_time::ToLocalTimeFunc, to_local_time);
51make_udf_function!(to_unixtime::ToUnixtimeFunc, to_unixtime);
52make_udf_function!(to_timestamp::ToTimestampFunc, to_timestamp);
53make_udf_function!(to_timestamp::ToTimestampSecondsFunc, to_timestamp_seconds);
54make_udf_function!(to_timestamp::ToTimestampMillisFunc, to_timestamp_millis);
55make_udf_function!(to_timestamp::ToTimestampMicrosFunc, to_timestamp_micros);
56make_udf_function!(to_timestamp::ToTimestampNanosFunc, to_timestamp_nanos);
57
58// we cannot currently use the export_functions macro since it doesn't handle
59// functions with varargs currently
60
61pub mod expr_fn {
62 use datafusion_expr::Expr;
63
64 export_functions!((
65 current_date,
66 "returns current UTC date as a Date32 value",
67 ),(
68 current_time,
69 "returns current UTC time as a Time64 value",
70 ),(
71 from_unixtime,
72 "converts an integer to RFC3339 timestamp format string",
73 unixtime
74 ),(
75 date_bin,
76 "coerces an arbitrary timestamp to the start of the nearest specified interval",
77 stride source origin
78 ),(
79 date_part,
80 "extracts a subfield from the date",
81 part date
82 ),(
83 date_trunc,
84 "truncates the date to a specified level of precision",
85 part date
86 ),(
87 make_date,
88 "make a date from year, month and day component parts",
89 year month day
90 ),(
91 now,
92 "returns the current timestamp in nanoseconds, using the same value for all instances of now() in same statement",
93 ),
94 (
95 to_local_time,
96 "converts a timezone-aware timestamp to local time (with no offset or timezone information), i.e. strips off the timezone from the timestamp",
97 args,
98 ),
99 (
100 to_unixtime,
101 "converts a string and optional formats to a Unixtime",
102 args,
103 ),(
104 to_timestamp,
105 "converts a string and optional formats to a `Timestamp(Nanoseconds, None)`",
106 args,
107 ),(
108 to_timestamp_seconds,
109 "converts a string and optional formats to a `Timestamp(Seconds, None)`",
110 args,
111 ),(
112 to_timestamp_millis,
113 "converts a string and optional formats to a `Timestamp(Milliseconds, None)`",
114 args,
115 ),(
116 to_timestamp_micros,
117 "converts a string and optional formats to a `Timestamp(Microseconds, None)`",
118 args,
119 ),(
120 to_timestamp_nanos,
121 "converts a string and optional formats to a `Timestamp(Nanoseconds, None)`",
122 args,
123 ));
124
125 /// Returns a string representation of a date, time, timestamp or duration based
126 /// on a Chrono pattern.
127 ///
128 /// The syntax for the patterns can be found at
129 /// <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>
130 ///
131 /// # Examples
132 ///
133 /// ```ignore
134 /// # use chrono::prelude::*;
135 /// # use datafusion::prelude::*;
136 /// # use datafusion::error::Result;
137 /// # use datafusion_common::ScalarValue::TimestampNanosecond;
138 /// # use std::sync::Arc;
139 /// # use arrow::array::{Date32Array, RecordBatch, StringArray};
140 /// # use arrow::datatypes::{DataType, Field, Schema};
141 /// # #[tokio::main]
142 /// # async fn main() -> Result<()> {
143 /// let schema = Arc::new(Schema::new(vec![
144 /// Field::new("values", DataType::Date32, false),
145 /// Field::new("patterns", DataType::Utf8, false),
146 /// ]));
147 ///
148 /// let batch = RecordBatch::try_new(
149 /// schema,
150 /// vec![
151 /// Arc::new(Date32Array::from(vec![
152 /// 18506,
153 /// 18507,
154 /// 18508,
155 /// 18509,
156 /// ])),
157 /// Arc::new(StringArray::from(vec![
158 /// "%Y-%m-%d",
159 /// "%Y:%m:%d",
160 /// "%Y%m%d",
161 /// "%d-%m-%Y",
162 /// ])),
163 /// ],
164 /// )?;
165 ///
166 /// let ctx = SessionContext::new();
167 /// ctx.register_batch("t", batch)?;
168 /// let df = ctx.table("t").await?;
169 ///
170 /// // use the to_char function to convert col 'values',
171 /// // to strings using patterns in col 'patterns'
172 /// let df = df.with_column(
173 /// "date_str",
174 /// to_char(col("values"), col("patterns"))
175 /// )?;
176 /// // Note that providing a scalar value for the pattern
177 /// // is more performant
178 /// let df = df.with_column(
179 /// "date_str2",
180 /// to_char(col("values"), lit("%d-%m-%Y"))
181 /// )?;
182 /// // literals can be used as well with dataframe calls
183 /// let timestamp = "2026-07-08T09:10:11"
184 /// .parse::<NaiveDateTime>()
185 /// .unwrap()
186 /// .with_nanosecond(56789)
187 /// .unwrap()
188 /// .timestamp_nanos_opt()
189 /// .unwrap();
190 /// let df = df.with_column(
191 /// "timestamp_str",
192 /// to_char(lit(TimestampNanosecond(Some(timestamp), None)), lit("%d-%m-%Y %H:%M:%S"))
193 /// )?;
194 ///
195 /// df.show().await?;
196 ///
197 /// # Ok(())
198 /// # }
199 /// ```
200 pub fn to_char(datetime: Expr, format: Expr) -> Expr {
201 super::to_char().call(vec![datetime, format])
202 }
203
204 /// ```ignore
205 /// # use std::sync::Arc;
206 ///
207 /// # use datafusion_common::Result;
208 ///
209 /// # #[tokio::main]
210 /// # async fn main() -> Result<()> {
211 /// # use arrow::array::StringArray;
212 /// # use arrow::datatypes::{DataType, Field, Schema};
213 /// # use arrow::record_batch::RecordBatch;
214 /// # use datafusion_expr::col;
215 /// # use datafusion::prelude::*;
216 /// # use datafusion_functions::expr_fn::to_date;
217 ///
218 /// // define a schema.
219 /// let schema = Arc::new(Schema::new(vec![Field::new("a", DataType::Utf8, false)]));
220 ///
221 /// // define data.
222 /// let batch = RecordBatch::try_new(
223 /// schema,
224 /// vec![Arc::new(StringArray::from(vec![
225 /// "2020-09-08T13:42:29Z",
226 /// "2020-09-08T13:42:29.190855-05:00",
227 /// "2020-08-09 12:13:29",
228 /// "2020-01-02",
229 /// ]))],
230 /// )?;
231 ///
232 /// // declare a new context. In spark API, this corresponds to a new spark SQLsession
233 /// let ctx = SessionContext::new();
234 ///
235 /// // declare a table in memory. In spark API, this corresponds to createDataFrame(...).
236 /// ctx.register_batch("t", batch)?;
237 /// let df = ctx.table("t").await?;
238 ///
239 /// // use to_date function to convert col 'a' to timestamp type using the default parsing
240 /// let df = df.with_column("a", to_date(vec![col("a")]))?;
241 ///
242 /// let df = df.select_columns(&["a"])?;
243 ///
244 /// // print the results
245 /// df.show().await?;
246 ///
247 /// # Ok(())
248 /// # }
249 /// ```
250 pub fn to_date(args: Vec<Expr>) -> Expr {
251 super::to_date().call(args)
252 }
253}
254
255/// Returns all DataFusion functions defined in this package
256pub fn functions() -> Vec<Arc<ScalarUDF>> {
257 vec![
258 current_date(),
259 current_time(),
260 date_bin(),
261 date_part(),
262 date_trunc(),
263 from_unixtime(),
264 make_date(),
265 now(),
266 to_char(),
267 to_date(),
268 to_local_time(),
269 to_unixtime(),
270 to_timestamp(),
271 to_timestamp_seconds(),
272 to_timestamp_millis(),
273 to_timestamp_micros(),
274 to_timestamp_nanos(),
275 ]
276}