Skip to content

Commit

Permalink
impl Display for Time, Date, and Timestamp (#683)
Browse files Browse the repository at this point in the history
Jiff has [an extensive
discussion](https://github.com/BurntSushi/jiff/blob/master/COMPARE.md)
of how it compares to other time libraries.

I think we should consider my choice of Jiff as tentative. I haven't
given extensive thought to the complexities of handling time and why one
library is better than another. Jiff seems to make reasonable choices
(like using the local timezone database when available and supporting
(de)serialization of named timezones).

Further works towards completing #670.
  • Loading branch information
danking authored Aug 27, 2024
1 parent 81d529c commit f846c4b
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 4 deletions.
28 changes: 28 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ homedir = "0.3.3"
humansize = "2.1.3"
indicatif = "0.17.8"
itertools = "0.13.0"
jiff = "0.1.8"
lazy_static = "1.4.0"
leb128 = "0.2.5"
log = "0.4.21"
Expand Down
1 change: 1 addition & 0 deletions vortex-datetime-dtype/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rust-version = { workspace = true }

[dependencies]
arrow-schema = { workspace = true, optional = true }
jiff = { workspace = true }
lazy_static = { workspace = true }
num_enum = { workspace = true }
serde = { workspace = true, features = ["derive"] }
Expand Down
56 changes: 54 additions & 2 deletions vortex-datetime-dtype/src/temporal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use std::fmt::Display;

use jiff::civil::{Date, Time};
use jiff::{Timestamp, Zoned};
use lazy_static::lazy_static;
use vortex_dtype::ExtID;

use crate::unit::TimeUnit;

lazy_static! {
pub static ref DATE_ID: ExtID = ExtID::from("vortex.date");
pub static ref TIME_ID: ExtID = ExtID::from("vortex.time");
pub static ref DATE_ID: ExtID = ExtID::from("vortex.date");
pub static ref TIMESTAMP_ID: ExtID = ExtID::from("vortex.timestamp");
}

Expand All @@ -23,6 +27,24 @@ pub enum TemporalMetadata {
Timestamp(TimeUnit, Option<String>),
}

pub enum TemporalJiff {
Time(Time),
Date(Date),
Timestamp(Timestamp),
Zoned(Zoned),
}

impl Display for TemporalJiff {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TemporalJiff::Time(x) => write!(f, "{}", x),
TemporalJiff::Date(x) => write!(f, "{}", x),
TemporalJiff::Timestamp(x) => write!(f, "{}", x),
TemporalJiff::Zoned(x) => write!(f, "{}", x),
}
}
}

impl TemporalMetadata {
/// Retrieve the time unit associated with the array.
///
Expand All @@ -43,6 +65,36 @@ impl TemporalMetadata {
None
}
}

pub fn to_jiff(&self, v: i64) -> VortexResult<TemporalJiff> {
match self {
TemporalMetadata::Time(TimeUnit::D) => {
vortex_bail!("Invalid TimeUnit TimeUnit::D for TemporalMetadata::Time")
}
TemporalMetadata::Time(unit) => Ok(TemporalJiff::Time(
Time::MIN.checked_add(unit.to_jiff_span(v)?)?,
)),
TemporalMetadata::Date(unit) => match unit {
TimeUnit::D | TimeUnit::Ms => Ok(TemporalJiff::Date(
Date::new(1970, 1, 1)?.checked_add(unit.to_jiff_span(v)?)?,
)),
_ => {
vortex_bail!("Invalid TimeUnit {} for TemporalMetadata::Time", unit)
}
},
TemporalMetadata::Timestamp(TimeUnit::D, _) => {
vortex_bail!("Invalid TimeUnit TimeUnit::D for TemporalMetadata::Timestamp")
}
TemporalMetadata::Timestamp(unit, None) => Ok(TemporalJiff::Timestamp(
Timestamp::UNIX_EPOCH.checked_add(unit.to_jiff_span(v)?)?,
)),
TemporalMetadata::Timestamp(unit, Some(tz)) => Ok(TemporalJiff::Zoned(
Timestamp::UNIX_EPOCH
.checked_add(unit.to_jiff_span(v)?)?
.intz(tz)?,
)),
}
}
}

use vortex_dtype::{ExtDType, ExtMetadata};
Expand All @@ -60,7 +112,7 @@ impl TryFrom<&ExtDType> for TemporalMetadata {
x if x == DATE_ID.as_ref() => decode_date_metadata(metadata),
x if x == TIMESTAMP_ID.as_ref() => decode_timestamp_metadata(metadata),
_ => {
vortex_bail!(InvalidArgument: "ExtDType must be one of the known temporal types")
vortex_bail!("ExtDType must be one of the known temporal types")
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions vortex-datetime-dtype/src/unit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::fmt::{Display, Formatter};

use jiff::Span;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use serde::{Deserialize, Serialize};
use vortex_error::VortexResult;

#[derive(
Debug,
Expand All @@ -26,6 +28,18 @@ pub enum TimeUnit {
D,
}

impl TimeUnit {
pub fn to_jiff_span(&self, v: i64) -> VortexResult<Span> {
Ok(match self {
TimeUnit::Ns => Span::new().try_nanoseconds(v)?,
TimeUnit::Us => Span::new().try_microseconds(v)?,
TimeUnit::Ms => Span::new().try_milliseconds(v)?,
TimeUnit::S => Span::new().try_seconds(v)?,
TimeUnit::D => Span::new().try_days(v)?,
})
}
}

impl Display for TimeUnit {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Expand Down
1 change: 1 addition & 0 deletions vortex-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ arrow-schema = { workspace = true }
datafusion-common = { workspace = true, optional = true }
flatbuffers = { workspace = true, optional = true }
flexbuffers = { workspace = true, optional = true }
jiff = { workspace = true }
object_store = { workspace = true, optional = true }
parquet = { workspace = true, optional = true }
thiserror = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions vortex-error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ pub enum VortexError {
#[backtrace]
object_store::Error,
),
#[error(transparent)]
JiffError(
#[from]
#[backtrace]
jiff::Error,
),
}

pub type VortexResult<T> = Result<T, VortexError>;
Expand Down
1 change: 1 addition & 0 deletions vortex-scalar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ datafusion-common = { workspace = true, optional = true }
flatbuffers = { workspace = true, optional = true }
flexbuffers = { workspace = true, optional = true }
itertools = { workspace = true }
jiff = { workspace = true }
num-traits = { workspace = true }
paste = { workspace = true }
prost = { workspace = true, optional = true }
Expand Down
Loading

0 comments on commit f846c4b

Please sign in to comment.