Extract a date part from microseconds since epoch
(field: &str, timestamp: i64)
| 399 | |
| 400 | /// Extract a date part from microseconds since epoch |
| 401 | fn extract_date_part(field: &str, timestamp: i64) -> Result<f64> { |
| 402 | let secs = timestamp / 1_000_000; |
| 403 | let micros = timestamp % 1_000_000; |
| 404 | let nanos = (micros * 1000) as u32; |
| 405 | |
| 406 | let datetime = DateTime::from_timestamp(secs, nanos) |
| 407 | .ok_or_else(|| Error::UserFunctionError("Invalid timestamp".into()))?; |
| 408 | |
| 409 | match field.to_lowercase().as_str() { |
| 410 | "year" => Ok(datetime.year() as f64), |
| 411 | "month" => Ok(datetime.month() as f64), |
| 412 | "day" => Ok(datetime.day() as f64), |
| 413 | "hour" => Ok(datetime.hour() as f64), |
| 414 | "minute" => Ok(datetime.minute() as f64), |
| 415 | "second" => Ok(datetime.second() as f64 + (datetime.nanosecond() as f64 / 1_000_000_000.0)), |
| 416 | "microseconds" => Ok(datetime.nanosecond() as f64 / 1000.0), |
| 417 | "milliseconds" => Ok(datetime.nanosecond() as f64 / 1_000_000.0), |
| 418 | "epoch" => Ok(timestamp as f64 / 1_000_000.0), // Return seconds for epoch |
| 419 | "dow" | "dayofweek" => Ok(datetime.weekday().num_days_from_sunday() as f64), |
| 420 | "doy" | "dayofyear" => Ok(datetime.ordinal() as f64), |
| 421 | "quarter" => Ok(((datetime.month() - 1) / 3 + 1) as f64), |
| 422 | "week" => Ok(datetime.iso_week().week() as f64), |
| 423 | "isoyear" => Ok(datetime.iso_week().year() as f64), |
| 424 | "decade" => Ok((datetime.year() / 10) as f64), |
| 425 | "century" => Ok(((datetime.year() - 1) / 100 + 1) as f64), |
| 426 | "millennium" => Ok(((datetime.year() - 1) / 1000 + 1) as f64), |
| 427 | _ => Err(Error::UserFunctionError( |
| 428 | format!("Unknown date part: {field}").into() |
| 429 | )) |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | /// Truncate microseconds since epoch to the specified precision |
| 434 | fn truncate_date(field: &str, timestamp: i64) -> Result<i64> { |
no outgoing calls
no test coverage detected