Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions crates/tick/src/fmt/iso_8601.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,13 @@ impl Iso8601 {

/// The smallest value that can be represented by `Iso8601`.
///
/// This represents a Unix system time of `1 January 1970 00:00:00 UTC` (Unix epoch).
pub const MIN: Self = Self(Timestamp::UNIX_EPOCH);
/// This represents a Unix system time of `1 January -9999 00:00:00 UTC`.
pub const MIN: Self = Self(Timestamp::MIN);

pub(super) fn to_unix_epoch_duration(self) -> Duration {
self.0.duration_since(Timestamp::UNIX_EPOCH).unsigned_abs()
}
/// The Unix epoch represented as an `Iso8601` timestamp.
///
/// This represents a Unix system time of `1 January 1970 00:00:00 UTC` (Unix epoch).
pub const UNIX_EPOCH: Self = Self(Timestamp::UNIX_EPOCH);
}

impl FromStr for Iso8601 {
Expand Down Expand Up @@ -199,14 +200,25 @@ mod tests {
}

#[test]
fn parse_min() {
fn parse_unix_epoch() {
let iso: Iso8601 = "1970-01-01T00:00:00Z".parse().unwrap();

assert_eq!(iso, Iso8601::MIN);
assert_eq!(iso, Iso8601::UNIX_EPOCH);
let system_time: SystemTime = iso.into();
assert_eq!(system_time, SystemTime::UNIX_EPOCH);
}

#[test]
fn parse_min() {
// MIN represents year -9999, which cannot be parsed in standard ISO 8601 format
// but we can verify MIN constant exists and can be converted to SystemTime
let min_system_time: SystemTime = Iso8601::MIN.into();
let unix_epoch_time: SystemTime = Iso8601::UNIX_EPOCH.into();

// MIN should be before UNIX_EPOCH
assert!(min_system_time < unix_epoch_time);
}

#[test]
fn parse_then_display() {
let stamp: Iso8601 = "1970-01-01T01:00:00Z".parse().unwrap();
Expand Down
27 changes: 23 additions & 4 deletions crates/tick/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,13 @@ mod tests {

#[test]
fn min_values_are_aligned() {
// All MIN values should represent Unix epoch (1 January 1970 00:00:00 UTC)
// All MIN values should represent the minimum timestamp (1 January -9999 00:00:00 UTC)
let iso_min: SystemTime = Iso8601::MIN.into();
let rfc_min: SystemTime = Rfc2822::MIN.into();
let unix_min: SystemTime = UnixSeconds::MIN.into();

assert_eq!(iso_min, SystemTime::UNIX_EPOCH, "Iso8601::MIN should be Unix epoch");
assert_eq!(rfc_min, SystemTime::UNIX_EPOCH, "Rfc2822::MIN should be Unix epoch");
assert_eq!(unix_min, SystemTime::UNIX_EPOCH, "UnixSeconds::MIN should be Unix epoch");
assert_eq!(iso_min, rfc_min, "Iso8601::MIN and Rfc2822::MIN should be equal");
assert_eq!(iso_min, unix_min, "Iso8601::MIN and UnixSeconds::MIN should be equal");

// Cross-format conversions at MIN should preserve the value
assert_eq!(Iso8601::from(Rfc2822::MIN), Iso8601::MIN);
Expand All @@ -140,6 +139,26 @@ mod tests {
assert_eq!(UnixSeconds::from(Rfc2822::MIN), UnixSeconds::MIN);
}

#[test]
fn unix_epoch_values_are_aligned() {
// All UNIX_EPOCH values should represent Unix epoch (1 January 1970 00:00:00 UTC)
let iso_epoch: SystemTime = Iso8601::UNIX_EPOCH.into();
let rfc_epoch: SystemTime = Rfc2822::UNIX_EPOCH.into();
let unix_epoch: SystemTime = UnixSeconds::UNIX_EPOCH.into();

assert_eq!(iso_epoch, SystemTime::UNIX_EPOCH, "Iso8601::UNIX_EPOCH should be Unix epoch");
assert_eq!(rfc_epoch, SystemTime::UNIX_EPOCH, "Rfc2822::UNIX_EPOCH should be Unix epoch");
assert_eq!(unix_epoch, SystemTime::UNIX_EPOCH, "UnixSeconds::UNIX_EPOCH should be Unix epoch");

// Cross-format conversions at UNIX_EPOCH should preserve the value
assert_eq!(Iso8601::from(Rfc2822::UNIX_EPOCH), Iso8601::UNIX_EPOCH);
assert_eq!(Iso8601::from(UnixSeconds::UNIX_EPOCH), Iso8601::UNIX_EPOCH);
assert_eq!(Rfc2822::from(Iso8601::UNIX_EPOCH), Rfc2822::UNIX_EPOCH);
assert_eq!(Rfc2822::from(UnixSeconds::UNIX_EPOCH), Rfc2822::UNIX_EPOCH);
assert_eq!(UnixSeconds::from(Iso8601::UNIX_EPOCH), UnixSeconds::UNIX_EPOCH);
assert_eq!(UnixSeconds::from(Rfc2822::UNIX_EPOCH), UnixSeconds::UNIX_EPOCH);
}

#[test]
fn max_values_are_aligned() {
// All MAX values should represent 31 December 9999 23:59:59 UTC
Expand Down
28 changes: 21 additions & 7 deletions crates/tick/src/fmt/rfc_2822.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::fmt::{self, Debug, Display, Formatter};
use std::str::FromStr;
use std::time::{Duration, SystemTime};
use std::time::SystemTime;

use jiff::Timestamp;
use jiff::fmt::rfc2822;
Expand Down Expand Up @@ -92,12 +92,13 @@ impl Rfc2822 {

/// The smallest value that can be represented by `Rfc2822`.
///
/// This represents a Unix system time at `1 January 1970 00:00:00 UTC` (Unix epoch).
pub const MIN: Self = Self(Timestamp::UNIX_EPOCH);
/// This represents a Unix system time at `1 January -9999 00:00:00 UTC`.
pub const MIN: Self = Self(Timestamp::MIN);

pub(super) fn to_unix_epoch_duration(self) -> Duration {
self.0.duration_since(Timestamp::UNIX_EPOCH).unsigned_abs()
}
/// The Unix epoch represented as an `Rfc2822` timestamp.
///
/// This represents a Unix system time at `1 January 1970 00:00:00 UTC` (Unix epoch).
pub const UNIX_EPOCH: Self = Self(Timestamp::UNIX_EPOCH);
}

impl FromStr for Rfc2822 {
Expand Down Expand Up @@ -175,6 +176,7 @@ impl<'de> serde_core::Deserialize<'de> for Rfc2822 {
#[cfg(test)]
mod tests {
use std::hash::Hash;
use std::time::Duration;

use super::*;
static_assertions::assert_impl_all!(Rfc2822: Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TryFrom<SystemTime>, From<Iso8601>, FromStr);
Expand All @@ -185,11 +187,23 @@ mod tests {
}

#[test]
fn parse_min() {
fn parse_unix_epoch() {
let stamp: Rfc2822 = "Thu, 1 Jan 1970 00:00:00 GMT".parse().unwrap();
assert_eq!(stamp, Rfc2822::UNIX_EPOCH);
assert_eq!(SystemTime::from(stamp), SystemTime::UNIX_EPOCH);
}

#[test]
fn parse_min() {
// RFC 2822 format cannot represent year -9999, but we can verify MIN constant exists
// and can be converted to SystemTime
let min_system_time: SystemTime = Rfc2822::MIN.into();
let unix_epoch_time: SystemTime = Rfc2822::UNIX_EPOCH.into();

// MIN should be before UNIX_EPOCH
assert!(min_system_time < unix_epoch_time);
}

#[test]
fn to_system_time() {
let stamp: Rfc2822 = "Thu, 1 Jan 1970 00:00:01 GMT".parse().unwrap();
Expand Down
Loading