summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/time.rs231
-rw-r--r--src/timezone.rs2
2 files changed, 229 insertions, 4 deletions
diff --git a/src/time.rs b/src/time.rs
index e0a919c..49dba51 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -1,5 +1,6 @@
use core::cmp::Ordering;
use core::fmt::Display;
+use core::panic;
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Time {
@@ -123,6 +124,234 @@ impl Time {
pub const fn nanosecond(self) -> u32 {
self.nanosecond
}
+
+ /// Adds the specified number of hours to the time.
+ /// This returns a tuple of the addition result and a boolean indicating
+ /// if overflow happened.
+ #[must_use]
+ pub const fn add_hours_overflowing(self, hours: isize) -> (Self, bool) {
+ let total_hours = self.hour as isize + hours;
+ let overflow = 0 > total_hours || total_hours >= 24;
+ let total_hours = total_hours % 24 + (24 * total_hours.is_negative() as isize);
+
+ let time = Self {
+ hour: total_hours as u8,
+ minute: self.minute,
+ second: self.second,
+ nanosecond: self.nanosecond,
+ };
+
+ (time, overflow)
+ }
+
+ /// Adds the specified number of minutes to the time.
+ /// This returns a tuple of the addition result and a boolean indicating
+ /// if overflow happened.
+ #[must_use]
+ pub const fn add_minutes_overflowing(self, minutes: isize) -> (Self, bool) {
+ let total_minutes = (self.minute as isize + minutes) % 60;
+ let total_minutes = total_minutes + (60 * total_minutes.is_negative() as isize);
+ let added_hours = (self.hour as isize + minutes) / 60;
+ let total_hours = self.hour as isize + added_hours;
+ let overflow = 0 > total_hours || total_hours >= 24;
+ let total_hours = total_hours % 24 + (24 * total_hours.is_negative() as isize);
+
+ let time = Self {
+ hour: total_hours as u8,
+ minute: total_minutes as u8,
+ second: self.second,
+ nanosecond: self.nanosecond,
+ };
+
+ (time, overflow)
+ }
+
+ /// Adds the specified number of seconds to the time.
+ /// This returns a tuple of the addition result and a boolean indicating
+ /// if overflow happened.
+ /// Leap seconds are not included in this calculation.
+ #[must_use]
+ pub const fn add_seconds_overflowing(self, seconds: isize) -> (Self, bool) {
+ let total_seconds = (self.second as isize + seconds) % 60;
+ let total_seconds = total_seconds + (60 * total_seconds.is_negative() as isize);
+ let added_minutes = (self.second as isize + seconds) / 60;
+ let total_minutes = (self.minute as isize + added_minutes) % 60;
+ let total_minutes = total_minutes + (60 * total_minutes.is_negative() as isize);
+ let added_hours = (self.hour as isize + added_minutes) / 60;
+ let total_hours = self.hour as isize + added_hours;
+ let overflow = 0 > total_hours || total_hours >= 24;
+ let total_hours = total_hours % 24 + (24 * total_hours.is_negative() as isize);
+
+ let time = Self {
+ hour: total_hours as u8,
+ minute: total_minutes as u8,
+ second: total_seconds as u8,
+ nanosecond: self.nanosecond,
+ };
+
+ (time, overflow)
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// This returns a tuple of the addition result and a boolean indicating
+ /// if overflow happened.
+ /// Leap seconds are not included in this calculation.
+ #[must_use]
+ pub const fn add_nanoseconds_overflowing(self, nanoseconds: isize) -> (Self, bool) {
+ let total_nanos = (self.nanosecond as isize + nanoseconds) % 1_000_000_000;
+ let total_nanos = total_nanos + (1_000_000_000 * total_nanos.is_negative() as isize);
+ let added_seconds = (self.nanosecond as isize + nanoseconds) / 1_000_000_000;
+ let total_seconds = (self.second as isize + added_seconds) % 60;
+ let total_seconds = total_seconds + (60 * total_seconds.is_negative() as isize);
+ let added_minutes = (self.second as isize + added_seconds) / 60;
+ let total_minutes = (self.minute as isize + added_minutes) % 60;
+ let total_minutes = total_minutes + (60 * total_minutes.is_negative() as isize);
+ let added_hours = (self.minute as isize + added_minutes) / 60;
+ let total_hours = self.hour as isize + added_hours;
+ let overflow = 0 > total_hours || total_hours >= 24;
+ let total_hours = total_hours % 24 + (24 * total_hours.is_negative() as isize);
+
+ let time = Self {
+ hour: total_hours as u8,
+ minute: total_minutes as u8,
+ second: total_seconds as u8,
+ nanosecond: total_nanos as u32,
+ };
+
+ (time, overflow)
+ }
+
+ /// Adds the specified number of hours to the time.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_hours_checked(self, hours: isize) -> Option<Self> {
+ let (time, overflow) = self.add_hours_overflowing(hours);
+
+ if overflow {
+ None
+ } else {
+ Some(time)
+ }
+ }
+
+ /// Adds the specified number of minutes to the time.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_minutes_checked(self, minutes: isize) -> Option<Self> {
+ let (time, overflow) = self.add_minutes_overflowing(minutes);
+
+ if overflow {
+ None
+ } else {
+ Some(time)
+ }
+ }
+
+ /// Adds the specified number of seconds to the time.
+ /// Leap seconds are not included in this calculation.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_seconds_checked(self, seconds: isize) -> Option<Self> {
+ let (time, overflow) = self.add_seconds_overflowing(seconds);
+
+ if overflow {
+ None
+ } else {
+ Some(time)
+ }
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// Leap seconds are not included in this calculation.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_nanoseconds_checked(self, nanoseconds: isize) -> Option<Self> {
+ let (time, overflow) = self.add_nanoseconds_overflowing(nanoseconds);
+
+ if overflow {
+ None
+ } else {
+ Some(time)
+ }
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// Leap seconds are not included in this calculation.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_hours_wrapping(self, hours: isize) -> Self {
+ self.add_hours_overflowing(hours).0
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// Leap seconds are not included in this calculation.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_minutes_wrapping(self, minutes: isize) -> Self {
+ self.add_minutes_overflowing(minutes).0
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// Leap seconds are not included in this calculation.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_seconds_wrapping(self, seconds: isize) -> Self {
+ self.add_seconds_overflowing(seconds).0
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// Leap seconds are not included in this calculation.
+ /// Returns `None` if overflow occurs.
+ #[must_use]
+ pub const fn add_nanoseconds_wrapping(self, nanoseconds: isize) -> Self {
+ self.add_nanoseconds_overflowing(nanoseconds).0
+ }
+
+ /// Adds the specified number of hours to the time.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting time is 24 hours or more
+ #[must_use]
+ pub fn add_hours(self, hours: isize) -> Self {
+ self.add_hours_checked(hours)
+ .unwrap_or_else(|| panic!("Overflow when adding {hours} hours to {self}"))
+ }
+
+ /// Adds the specified number of minutes to the time
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting time is 24 hours or more
+ #[must_use]
+ pub fn add_minutes(self, minutes: isize) -> Self {
+ self.add_minutes_checked(minutes)
+ .unwrap_or_else(|| panic!("Overflow when adding {minutes} minutes to {self}"))
+ }
+
+ /// Adds the specified number of seconds to the time.
+ /// Leap seconds are not included in this calculation
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting time is 24 hours or more
+ #[must_use]
+ pub fn add_seconds(self, seconds: isize) -> Self {
+ self.add_seconds_checked(seconds)
+ .unwrap_or_else(|| panic!("Overflow when adding {seconds} seconds to {self}"))
+ }
+
+ /// Adds the specified number of nanoseconds to the time.
+ /// Leap seconds are not included in this calculation
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting time is 24 hours or more
+ #[must_use]
+ pub fn add_nanoseconds(self, nanoseconds: isize) -> Self {
+ self.add_nanoseconds_checked(nanoseconds)
+ .unwrap_or_else(|| panic!("Overflow when adding {nanoseconds} nanoseconds to {self}"))
+ }
}
impl PartialOrd for Time {
@@ -167,8 +396,6 @@ impl Ord for Time {
}
}
-// TODO addition
-
impl Display for Time {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let seconds = self.second as f64 + (self.nanosecond as f64 / 1_000_000_000.0);
diff --git a/src/timezone.rs b/src/timezone.rs
index 3319b12..20405bf 100644
--- a/src/timezone.rs
+++ b/src/timezone.rs
@@ -46,8 +46,6 @@ 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.