jiff Integration
Enable with features = ["jiff"]. Bundles the IANA timezone database (tzdb-bundle-always) β no system tzdata required. Coexists with the time feature.
Enable with features = ["jiff"]. Bundles the IANA timezone database (tzdb-bundle-always) β no system tzdata required. Coexists with the time feature.
πType mapping
| Rust type | R type | Notes |
|---|---|---|
jiff::Timestamp | POSIXct (UTC) | Nanosecond precision |
jiff::Zoned | POSIXct + tzone attr | IANA name round-tripped |
jiff::civil::Date | Date | Days since 1970-01-01 |
jiff::SignedDuration | difftime (secs) | Signed, nanosecond precision |
jiff::Span | ExternalPtr | Via RSpan adapter trait |
jiff::civil::DateTime | ExternalPtr | Via RDateTime adapter trait |
jiff::civil::Time | ExternalPtr | Via RTime adapter trait |
All scalar types support Option<T>, Vec<T>, and Vec<Option<T>> variants.
πTimezone policy
Zonedβ R: writes the IANA name fromtime_zone().iana_name()into thetzoneattribute. Fixed-offset zones without an IANA name fall back to"UTC".- R β
Zoned: unknowntzoneβSexpError::InvalidValue. No silent UTC fallback β unlike thetimefeature, jiff can represent real IANA zones, so losing them is an error. - Empty or missing
tzone: treated as UTC. Vec<Zoned>β R: a singletzoneattribute applies to the whole vector; the first elementβs timezone is used. Mixed-timezone vectors log a warning (requireslogfeature).
πFractional seconds
Floor-based split into whole seconds + nanoseconds, matching time_impl.rs. Correct for negative timestamps: -1.2s β -2s + 800_000_000ns.
πAdapter traits
For types with no base-R scalar analog, wrap in #[derive(ExternalPtr)] and implement the relevant trait:
RSpanβ component getters (years/months/weeks/days/hours/minutes/seconds/ms/Β΅s/ns),is_zero,is_negative,negate,absRDateTimeβ year/month/day/hour/minute/second,to_date,to_time,in_tzRTimeβ hour/minute/second/subsec_nanosecond,onRTimestampβas_second,as_millisecond,subsec_nanosecond,to_zoned_in,strftimeRZonedβ year/month/day/hour/minute/second,iana_name,in_tz,start_of_day,strftimeRDateβ year/month/day/weekday/day_of_year,first_of_month,last_of_month,tomorrow,yesterday,strftimeRSignedDurationβas_seconds_f64,as_milliseconds,whole_seconds/minutes/hours/days,subsec_nanoseconds,is_negative,is_zero,abs
πALTREP
JiffTimestampVec β lazy REALSXP backed by Arc<Vec<Timestamp>>. Elements are projected to seconds-since-epoch on access; no upfront conversion. Apply POSIXct class after construction.
JiffZonedVec β lazy REALSXP backed by Arc<Vec<Zoned>>, single-timezone strict. Constructor (JiffZonedVec::new) validates that all elements share the same IANA timezone name; returns Err if any element differs. On success, into_sexp() produces a POSIXct ALTREP with class = c("POSIXct", "POSIXt") and tzone = <iana>. TryFromSexp reconstructs each element using the SEXPβs tzone attribute.
πvctrs rcrd constructors
Requires features = ["jiff", "vctrs"]. Public helpers in jiff_impl::vctrs_support:
span_vec_to_rcrd(&[Span]) -> SEXPβ fields: years/months/weeks/days/hours/minutes/seconds/ms/Β΅s/ns (all INTSXP)zoned_vec_to_rcrd(&[Zoned]) -> SEXPβ fields: timestamp (REALSXP, seconds-since-epoch), tz (STRSXP)datetime_vec_to_rcrd(&[DateTime]) -> SEXPβ fields: year/month/day/hour/minute/second/subsec_nanosecondtime_vec_to_rcrd(&[Time]) -> SEXPβ fields: hour/minute/second/subsec_nanosecond
All constructors return vctrs rcrd SEXPs with class c("<type>", "vctrs_rcrd", "vctrs_vctr").
πFollow-ups
- #305 β expand adapter-trait test coverage (formatting/arithmetic methods, ALTREP laziness counter)