Skip to content

Commit 4675216

Browse files
alambviirya
andauthored
Minor: Make date_trunc code easier to understand (apache#6789)
* Minor: Make `date_trunc` code easier to understand * add a commentg * Update datafusion/physical-expr/src/datetime_expressions.rs Co-authored-by: Liang-Chi Hsieh <[email protected]> --------- Co-authored-by: Liang-Chi Hsieh <[email protected]>
1 parent 6c8df1a commit 4675216

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

datafusion/physical-expr/src/datetime_expressions.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -219,42 +219,51 @@ fn quarter_month(date: &NaiveDateTime) -> u32 {
219219
/// account that some granularities are not uniform durations of time
220220
/// (e.g. months are not always the same lengths, leap seconds, etc)
221221
fn date_trunc_coarse(granularity: &str, value: i64) -> Result<i64> {
222-
if granularity == "millisecond" || granularity == "microsecond" {
223-
return Ok(value);
224-
}
222+
// Use chrono NaiveDateTime to clear the various fields
223+
// correctly accounting for non uniform granularities
224+
let value = timestamp_ns_to_datetime(value).ok_or_else(|| {
225+
DataFusionError::Execution(format!("Timestamp {value} out of range"))
226+
})?;
227+
228+
let value = Some(value);
225229

226-
let value = timestamp_ns_to_datetime(value)
227-
.ok_or_else(|| {
228-
DataFusionError::Execution(format!("Timestamp {value} out of range"))
229-
})?
230-
.with_nanosecond(0);
231230
let value = match granularity {
232-
"second" => value,
233-
"minute" => value.and_then(|d| d.with_second(0)),
231+
"millisecond" => value,
232+
"microsecond" => value,
233+
"second" => value.and_then(|d| d.with_nanosecond(0)),
234+
"minute" => value
235+
.and_then(|d| d.with_nanosecond(0))
236+
.and_then(|d| d.with_second(0)),
234237
"hour" => value
238+
.and_then(|d| d.with_nanosecond(0))
235239
.and_then(|d| d.with_second(0))
236240
.and_then(|d| d.with_minute(0)),
237241
"day" => value
242+
.and_then(|d| d.with_nanosecond(0))
238243
.and_then(|d| d.with_second(0))
239244
.and_then(|d| d.with_minute(0))
240245
.and_then(|d| d.with_hour(0)),
241246
"week" => value
247+
.and_then(|d| d.with_nanosecond(0))
242248
.and_then(|d| d.with_second(0))
243249
.and_then(|d| d.with_minute(0))
244250
.and_then(|d| d.with_hour(0))
245251
.map(|d| d - Duration::seconds(60 * 60 * 24 * d.weekday() as i64)),
246252
"month" => value
253+
.and_then(|d| d.with_nanosecond(0))
247254
.and_then(|d| d.with_second(0))
248255
.and_then(|d| d.with_minute(0))
249256
.and_then(|d| d.with_hour(0))
250257
.and_then(|d| d.with_day0(0)),
251258
"quarter" => value
259+
.and_then(|d| d.with_nanosecond(0))
252260
.and_then(|d| d.with_second(0))
253261
.and_then(|d| d.with_minute(0))
254262
.and_then(|d| d.with_hour(0))
255263
.and_then(|d| d.with_day0(0))
256264
.and_then(|d| d.with_month(quarter_month(&d))),
257265
"year" => value
266+
.and_then(|d| d.with_nanosecond(0))
258267
.and_then(|d| d.with_second(0))
259268
.and_then(|d| d.with_minute(0))
260269
.and_then(|d| d.with_hour(0))

0 commit comments

Comments
 (0)