summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/date.rs38
-rw-r--r--src/datetime.rs68
-rw-r--r--src/month.rs2
-rw-r--r--src/time.rs45
-rw-r--r--src/weekday.rs2
5 files changed, 150 insertions, 5 deletions
diff --git a/src/date.rs b/src/date.rs
index bc2d7dd..ff1805b 100644
--- a/src/date.rs
+++ b/src/date.rs
@@ -1,5 +1,7 @@
use crate::{Month, Year};
+use core::cmp::Ordering;
+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Date {
year: Year,
@@ -52,4 +54,40 @@ impl Date {
}
}
+impl PartialOrd for Date {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let year_ordering = self.year.cmp(&other.year);
+ let month_ordering = self.month.cmp(&other.month);
+ let day_ordering = self.day.cmp(&other.day);
+
+ if year_ordering != Ordering::Equal {
+ Some(year_ordering)
+ } else if month_ordering != Ordering::Equal {
+ Some(month_ordering)
+ } else if day_ordering != Ordering::Equal {
+ Some(day_ordering)
+ } else {
+ Some(Ordering::Equal)
+ }
+ }
+}
+
+impl Ord for Date {
+ fn cmp(&self, other: &Self) -> Ordering {
+ let year_ordering = self.year.cmp(&other.year);
+ let month_ordering = self.month.cmp(&other.month);
+ let day_ordering = self.day.cmp(&other.day);
+
+ if year_ordering != Ordering::Equal {
+ year_ordering
+ } else if month_ordering != Ordering::Equal {
+ month_ordering
+ } else if day_ordering != Ordering::Equal {
+ day_ordering
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
// TODO addition
diff --git a/src/datetime.rs b/src/datetime.rs
index c739d46..282a56b 100644
--- a/src/datetime.rs
+++ b/src/datetime.rs
@@ -1,4 +1,9 @@
-use crate::{timezone::UtcOffset, Date, Month, Time, TimeZone, Year};
+use crate::{
+ timezone::{Utc, UtcOffset},
+ Date, Month, Time, TimeZone, Year,
+};
+
+use core::{cmp::Ordering, hash::Hash};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct NaiveDateTime {
@@ -6,7 +11,7 @@ pub struct NaiveDateTime {
time: Time,
}
-#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+#[derive(Copy, Clone, Eq, Debug)]
pub struct DateTime<Tz: TimeZone> {
utc_datetime: NaiveDateTime,
timezone: Tz,
@@ -14,6 +19,7 @@ pub struct DateTime<Tz: TimeZone> {
impl<Tz: TimeZone> DateTime<Tz> {
// TODO unix epoch constant
+ // TODO docs
pub fn from_utc(utc_datetime: NaiveDateTime, timezone: Tz) -> Self {
Self {
@@ -23,7 +29,8 @@ impl<Tz: TimeZone> DateTime<Tz> {
}
pub fn offset(&self) -> UtcOffset {
- self.timezone.utc_offset(self.utc_datetime)
+ let utc = DateTime::<Utc>::from_utc(self.utc_datetime, Utc);
+ self.timezone.utc_offset(utc)
}
pub fn timezone(&self) -> &Tz {
@@ -87,4 +94,59 @@ impl NaiveDateTime {
}
}
+impl PartialOrd for NaiveDateTime {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let date_ordering = self.date.cmp(&other.date);
+ let time_ordering = self.time.cmp(&other.time);
+
+ if date_ordering != Ordering::Equal {
+ Some(date_ordering)
+ } else if time_ordering != Ordering::Equal {
+ Some(time_ordering)
+ } else {
+ Some(Ordering::Equal)
+ }
+ }
+}
+
+impl Ord for NaiveDateTime {
+ fn cmp(&self, other: &Self) -> Ordering {
+ let date_ordering = self.date.cmp(&other.date);
+ let time_ordering = self.time.cmp(&other.time);
+
+ if date_ordering != Ordering::Equal {
+ date_ordering
+ } else if time_ordering != Ordering::Equal {
+ time_ordering
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// TODO think harder about the fact that we don't consider timezone (how will UtcOffset work)
+impl<Tz: TimeZone, Other: TimeZone> PartialEq<DateTime<Other>> for DateTime<Tz> {
+ fn eq(&self, other: &DateTime<Other>) -> bool {
+ self.utc_datetime == other.utc_datetime
+ }
+}
+
+impl<Tz: TimeZone> Hash for DateTime<Tz> {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.utc_datetime.hash(state)
+ }
+}
+
+impl<Tz: TimeZone, Other: TimeZone> PartialOrd<DateTime<Other>> for DateTime<Tz> {
+ fn partial_cmp(&self, other: &DateTime<Other>) -> Option<Ordering> {
+ self.utc_datetime.partial_cmp(&other.utc_datetime)
+ }
+}
+
+impl<Tz: TimeZone> Ord for DateTime<Tz> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.utc_datetime.cmp(&other.utc_datetime)
+ }
+}
+
// TODO addition
diff --git a/src/month.rs b/src/month.rs
index ebb95e1..4d988b8 100644
--- a/src/month.rs
+++ b/src/month.rs
@@ -7,7 +7,7 @@ use self::Month::*;
use core::str::FromStr;
/// Months of the year
-#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display, PartialOrd, Ord)]
#[repr(u8)]
pub enum Month {
January = 1,
diff --git a/src/time.rs b/src/time.rs
index 94f7cd8..e80e532 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -1,3 +1,6 @@
+use core::cmp::Ordering;
+use core::fmt::Display;
+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Time {
hour: u8,
@@ -122,4 +125,46 @@ impl Time {
}
}
+impl PartialOrd for Time {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let hour_ordering = self.hour.cmp(&other.hour);
+ let minute_ordering = self.minute.cmp(&other.minute);
+ let second_ordering = self.second.cmp(&other.second);
+ let nano_ordering = self.nanosecond.cmp(&other.nanosecond);
+
+ if hour_ordering != Ordering::Equal {
+ Some(hour_ordering)
+ } else if minute_ordering != Ordering::Equal {
+ Some(minute_ordering)
+ } else if second_ordering != Ordering::Equal {
+ Some(second_ordering)
+ } else if nano_ordering != Ordering::Equal {
+ Some(nano_ordering)
+ } else {
+ Some(Ordering::Equal)
+ }
+ }
+}
+
+impl Ord for Time {
+ fn cmp(&self, other: &Self) -> Ordering {
+ let hour_ordering = self.hour.cmp(&other.hour);
+ let minute_ordering = self.minute.cmp(&other.minute);
+ let second_ordering = self.second.cmp(&other.second);
+ let nano_ordering = self.nanosecond.cmp(&other.nanosecond);
+
+ if hour_ordering != Ordering::Equal {
+ hour_ordering
+ } else if minute_ordering != Ordering::Equal {
+ minute_ordering
+ } else if second_ordering != Ordering::Equal {
+ second_ordering
+ } else if nano_ordering != Ordering::Equal {
+ nano_ordering
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
// TODO addition
diff --git a/src/weekday.rs b/src/weekday.rs
index b5e3f32..d678b9f 100644
--- a/src/weekday.rs
+++ b/src/weekday.rs
@@ -1,4 +1,4 @@
-use std::str::FromStr;
+use core::str::FromStr;
use derive_more::Display;