From d4c16d0a6967666574eba5ab919b0d1e60f0558d Mon Sep 17 00:00:00 2001 From: Botahamec Date: Mon, 17 Jan 2022 14:34:34 -0500 Subject: Basic timezones --- src/lib.rs | 1 + src/timezone.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/timezone.rs diff --git a/src/lib.rs b/src/lib.rs index d3b0e30..12b7225 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod date; mod datetime; mod month; mod time; +pub mod timezone; mod weekday; mod year; diff --git a/src/timezone.rs b/src/timezone.rs new file mode 100644 index 0000000..8401631 --- /dev/null +++ b/src/timezone.rs @@ -0,0 +1,80 @@ +use crate::NaiveDateTime; +use core::convert::Infallible; + +/// A type that can be used to represent a TimeZone +pub trait TimeZone { + type Err; + + fn utc_offset(&self, date_time: NaiveDateTime) -> Result; +} + +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +/// The UTC time zone +pub struct Utc; + +impl TimeZone for Utc { + type Err = Infallible; + + fn utc_offset(&self, _: NaiveDateTime) -> Result { + Ok(UtcOffset::UTC) + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +/// A timezone with a fixed offset from UTC +pub struct UtcOffset { + offset_seconds: i32, +} + +impl UtcOffset { + /// The UTC Timezone, represented as an offset + pub const UTC: Self = Self { offset_seconds: 0 }; + + // TODO validation + + /// Makes a new `UtcOffset` timezone with the given timezone difference. + /// A positive number is the Eastern hemisphere. A negative number is the + /// Western hemisphere. + /// + /// # Safety + /// + /// A value with an absolute value greater than or equal to 86,400 results + /// in undefined behavior + pub const unsafe fn from_seconds_unchecked(seconds: i32) -> Self { + Self { + offset_seconds: seconds, + } + } + + /// Makes a new `UtcOffset` timezone with the given timezone difference. + /// A positive number is the Eastern hemisphere. A negative number is the + /// Western hemisphere. + /// + /// # Safety + /// + /// A value with an absolute value greater than or equal to 24 results + /// in undefined behavior + pub const unsafe fn from_hours_unchecked(hours: i8) -> Self { + Self::from_seconds_unchecked(hours as i32 * 3600) + } + + /// The number of hours this timezone is ahead of UTC. THis number is + /// negative if the timezone is in the Western hemisphere + pub fn hours_ahead(self) -> f32 { + self.offset_seconds as f32 / 3600.0 + } + + /// The number of seconds this timezone is ahead of UTC. This number is + /// negative if the timezone is in the Western hemisphere + pub const fn seconds_ahead(self) -> i32 { + self.offset_seconds + } +} + +impl TimeZone for UtcOffset { + type Err = Infallible; + + fn utc_offset(&self, _: NaiveDateTime) -> Result { + Ok(*self) + } +} -- cgit v1.2.3