summaryrefslogtreecommitdiffstats
path: root/vendor/time/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/time/src')
-rw-r--r--vendor/time/src/date.rs13
-rw-r--r--vendor/time/src/date_time.rs78
-rw-r--r--vendor/time/src/duration.rs442
-rw-r--r--vendor/time/src/ext.rs37
-rw-r--r--vendor/time/src/format_description/mod.rs3
-rw-r--r--vendor/time/src/format_description/parse/ast.rs42
-rw-r--r--vendor/time/src/format_description/well_known/iso8601/adt_hack.rs9
-rw-r--r--vendor/time/src/formatting/formattable.rs7
-rw-r--r--vendor/time/src/formatting/iso8601.rs13
-rw-r--r--vendor/time/src/formatting/mod.rs5
-rw-r--r--vendor/time/src/lib.rs18
-rw-r--r--vendor/time/src/offset_date_time.rs24
-rw-r--r--vendor/time/src/parsing/component.rs13
-rw-r--r--vendor/time/src/parsing/iso8601.rs24
-rw-r--r--vendor/time/src/parsing/parsed.rs6
-rw-r--r--vendor/time/src/quickcheck.rs18
-rw-r--r--vendor/time/src/rand.rs17
-rw-r--r--vendor/time/src/serde/mod.rs146
-rw-r--r--vendor/time/src/shim.rs180
-rw-r--r--vendor/time/src/sys/local_offset_at/wasm_js.rs3
-rw-r--r--vendor/time/src/sys/local_offset_at/windows.rs3
-rw-r--r--vendor/time/src/time.rs154
-rw-r--r--vendor/time/src/utc_offset.rs29
-rw-r--r--vendor/time/src/util.rs22
-rw-r--r--vendor/time/src/weekday.rs22
25 files changed, 836 insertions, 492 deletions
diff --git a/vendor/time/src/date.rs b/vendor/time/src/date.rs
index b3023e0c0..9f194b434 100644
--- a/vendor/time/src/date.rs
+++ b/vendor/time/src/date.rs
@@ -6,6 +6,7 @@ use core::time::Duration as StdDuration;
#[cfg(feature = "formatting")]
use std::io;
+use crate::convert::*;
#[cfg(feature = "formatting")]
use crate::formatting::Formattable;
#[cfg(feature = "parsing")]
@@ -1013,8 +1014,10 @@ impl Add<StdDuration> for Date {
type Output = Self;
fn add(self, duration: StdDuration) -> Self::Output {
- Self::from_julian_day(self.to_julian_day() + (duration.as_secs() / 86_400) as i32)
- .expect("overflow adding duration to date")
+ Self::from_julian_day(
+ self.to_julian_day() + (duration.as_secs() / Second.per(Day) as u64) as i32,
+ )
+ .expect("overflow adding duration to date")
}
}
@@ -1033,8 +1036,10 @@ impl Sub<StdDuration> for Date {
type Output = Self;
fn sub(self, duration: StdDuration) -> Self::Output {
- Self::from_julian_day(self.to_julian_day() - (duration.as_secs() / 86_400) as i32)
- .expect("overflow subtracting duration from date")
+ Self::from_julian_day(
+ self.to_julian_day() - (duration.as_secs() / Second.per(Day) as u64) as i32,
+ )
+ .expect("overflow subtracting duration from date")
}
}
diff --git a/vendor/time/src/date_time.rs b/vendor/time/src/date_time.rs
index 592ced1fb..819f6d36b 100644
--- a/vendor/time/src/date_time.rs
+++ b/vendor/time/src/date_time.rs
@@ -16,6 +16,7 @@ use std::io;
#[cfg(feature = "std")]
use std::time::SystemTime;
+use crate::convert::*;
use crate::date::{MAX_YEAR, MIN_YEAR};
#[cfg(feature = "formatting")]
use crate::formatting::Formattable;
@@ -146,6 +147,7 @@ const fn maybe_offset_as_offset_opt<O: MaybeOffset>(
if O::STATIC_OFFSET.is_some() {
O::STATIC_OFFSET
} else if O::HAS_MEMORY_OFFSET {
+ #[repr(C)] // needed to guarantee they align at the start
union Convert<O: MaybeOffset> {
input: O::MemoryOffsetType,
output: UtcOffset,
@@ -171,6 +173,7 @@ const fn maybe_offset_as_offset<O: MaybeOffset + HasLogicalOffset>(
pub(crate) const fn maybe_offset_from_offset<O: MaybeOffset>(
offset: UtcOffset,
) -> O::MemoryOffsetType {
+ #[repr(C)] // needed to guarantee the types align at the start
union Convert<O: MaybeOffset> {
input: UtcOffset,
output: O::MemoryOffsetType,
@@ -257,14 +260,14 @@ impl<O: MaybeOffset> DateTime<O> {
// Use the unchecked method here, as the input validity has already been verified.
let date = Date::from_julian_day_unchecked(
- UNIX_EPOCH_JULIAN_DAY + div_floor!(timestamp, 86_400) as i32,
+ UNIX_EPOCH_JULIAN_DAY + div_floor!(timestamp, Second.per(Day) as i64) as i32,
);
- let seconds_within_day = timestamp.rem_euclid(86_400);
+ let seconds_within_day = timestamp.rem_euclid(Second.per(Day) as _);
let time = Time::__from_hms_nanos_unchecked(
- (seconds_within_day / 3_600) as _,
- ((seconds_within_day % 3_600) / 60) as _,
- (seconds_within_day % 60) as _,
+ (seconds_within_day / Second.per(Hour) as i64) as _,
+ ((seconds_within_day % Second.per(Hour) as i64) / Minute.per(Hour) as i64) as _,
+ (seconds_within_day % Second.per(Minute) as i64) as _,
0,
);
@@ -279,9 +282,10 @@ impl<O: MaybeOffset> DateTime<O> {
where
O: HasLogicalOffset,
{
- let datetime = const_try!(Self::from_unix_timestamp(
- div_floor!(timestamp, 1_000_000_000) as i64
- ));
+ let datetime = const_try!(Self::from_unix_timestamp(div_floor!(
+ timestamp,
+ Nanosecond.per(Second) as i128
+ ) as i64));
Ok(Self {
date: datetime.date,
@@ -289,7 +293,7 @@ impl<O: MaybeOffset> DateTime<O> {
datetime.hour(),
datetime.minute(),
datetime.second(),
- timestamp.rem_euclid(1_000_000_000) as u32,
+ timestamp.rem_euclid(Nanosecond.per(Second) as _) as u32,
),
offset: maybe_offset_from_offset::<O>(UtcOffset::UTC),
})
@@ -450,9 +454,10 @@ impl<O: MaybeOffset> DateTime<O> {
{
let offset = maybe_offset_as_offset::<O>(self.offset).whole_seconds() as i64;
- let days = (self.to_julian_day() as i64 - UNIX_EPOCH_JULIAN_DAY as i64) * 86_400;
- let hours = self.hour() as i64 * 3_600;
- let minutes = self.minute() as i64 * 60;
+ let days =
+ (self.to_julian_day() as i64 - UNIX_EPOCH_JULIAN_DAY as i64) * Second.per(Day) as i64;
+ let hours = self.hour() as i64 * Second.per(Hour) as i64;
+ let minutes = self.minute() as i64 * Second.per(Minute) as i64;
let seconds = self.second() as i64;
days + hours + minutes + seconds - offset
}
@@ -461,7 +466,7 @@ impl<O: MaybeOffset> DateTime<O> {
where
O: HasLogicalOffset,
{
- self.unix_timestamp() as i128 * 1_000_000_000 + self.nanosecond() as i128
+ self.unix_timestamp() as i128 * Nanosecond.per(Second) as i128 + self.nanosecond() as i128
}
// endregion unix timestamp getters
// endregion: getters
@@ -491,39 +496,49 @@ impl<O: MaybeOffset> DateTime<O> {
where
O: HasLogicalOffset,
{
+ expect_opt!(
+ self.checked_to_offset(offset),
+ "local datetime out of valid range"
+ )
+ }
+
+ pub const fn checked_to_offset(self, offset: UtcOffset) -> Option<DateTime<offset_kind::Fixed>>
+ where
+ O: HasLogicalOffset,
+ {
let self_offset = maybe_offset_as_offset::<O>(self.offset);
if self_offset.whole_hours() == offset.whole_hours()
&& self_offset.minutes_past_hour() == offset.minutes_past_hour()
&& self_offset.seconds_past_minute() == offset.seconds_past_minute()
{
- return DateTime {
+ return Some(DateTime {
date: self.date,
time: self.time,
offset,
- };
+ });
}
let (year, ordinal, time) = self.to_offset_raw(offset);
if year > MAX_YEAR || year < MIN_YEAR {
- panic!("local datetime out of valid range");
+ return None;
}
- DateTime {
+ Some(DateTime {
date: Date::__from_ordinal_date_unchecked(year, ordinal),
time,
offset,
- }
+ })
}
/// Equivalent to `.to_offset(UtcOffset::UTC)`, but returning the year, ordinal, and time. This
/// avoids constructing an invalid [`Date`] if the new value is out of range.
pub(crate) const fn to_offset_raw(self, offset: UtcOffset) -> (i32, u16, Time) {
- guard!(let Some(from) = maybe_offset_as_offset_opt::<O>(self.offset) else {
+ let Some(from) = maybe_offset_as_offset_opt::<O>(self.offset) else {
// No adjustment is needed because there is no offset.
return (self.year(), self.ordinal(), self.time);
- });
+ };
let to = offset;
// Fast path for when no conversion is necessary.
@@ -543,12 +558,12 @@ impl<O: MaybeOffset> DateTime<O> {
let mut ordinal = ordinal as i16;
// Cascade the values twice. This is needed because the values are adjusted twice above.
- cascade!(second in 0..60 => minute);
- cascade!(second in 0..60 => minute);
- cascade!(minute in 0..60 => hour);
- cascade!(minute in 0..60 => hour);
- cascade!(hour in 0..24 => ordinal);
- cascade!(hour in 0..24 => ordinal);
+ cascade!(second in 0..Second.per(Minute) as i16 => minute);
+ cascade!(second in 0..Second.per(Minute) as i16 => minute);
+ cascade!(minute in 0..Minute.per(Hour) as i16 => hour);
+ cascade!(minute in 0..Minute.per(Hour) as i16 => hour);
+ cascade!(hour in 0..Hour.per(Day) as i8 => ordinal);
+ cascade!(hour in 0..Hour.per(Day) as i8 => ordinal);
cascade!(ordinal => year);
debug_assert!(ordinal > 0);
@@ -807,7 +822,7 @@ impl<O: MaybeOffset> DateTime<O> {
}
let (year, ordinal, time) = self.to_offset_raw(UtcOffset::UTC);
- guard!(let Ok(date) = Date::from_ordinal_date(year, ordinal) else { return false });
+ let Ok(date) = Date::from_ordinal_date(year, ordinal) else { return false };
time.hour() == 23
&& time.minute() == 59
@@ -823,6 +838,7 @@ impl<O: MaybeOffset> DateTime<O> {
// `OffsetDateTime` is made an alias of `DateTime<Fixed>`. Consider hiding these methods from
// documentation in the future.
+ #[doc(hidden)]
#[allow(dead_code)] // while functionally private
#[deprecated(since = "0.3.18", note = "use `as_hms` instead")]
pub const fn to_hms(self) -> (u8, u8, u8)
@@ -832,6 +848,7 @@ impl<O: MaybeOffset> DateTime<O> {
self.time.as_hms()
}
+ #[doc(hidden)]
#[allow(dead_code)] // while functionally private
#[deprecated(since = "0.3.18", note = "use `as_hms_milli` instead")]
pub const fn to_hms_milli(self) -> (u8, u8, u8, u16)
@@ -841,6 +858,7 @@ impl<O: MaybeOffset> DateTime<O> {
self.time.as_hms_milli()
}
+ #[doc(hidden)]
#[allow(dead_code)] // while functionally private
#[deprecated(since = "0.3.18", note = "use `as_hms_micro` instead")]
pub const fn to_hms_micro(self) -> (u8, u8, u8, u32)
@@ -850,6 +868,7 @@ impl<O: MaybeOffset> DateTime<O> {
self.time.as_hms_micro()
}
+ #[doc(hidden)]
#[allow(dead_code)] // while functionally private
#[deprecated(since = "0.3.18", note = "use `as_hms_nano` instead")]
pub const fn to_hms_nano(self) -> (u8, u8, u8, u32)
@@ -1137,7 +1156,7 @@ impl From<DateTime<offset_kind::Fixed>> for SystemTime {
impl From<js_sys::Date> for DateTime<offset_kind::Fixed> {
fn from(js_date: js_sys::Date) -> Self {
// get_time() returns milliseconds
- let timestamp_nanos = (js_date.get_time() * 1_000_000.0) as i128;
+ let timestamp_nanos = (js_date.get_time() * Nanosecond.per(Millisecond) as f64) as i128;
Self::from_unix_timestamp_nanos(timestamp_nanos)
.expect("invalid timestamp: Timestamp cannot fit in range")
}
@@ -1151,7 +1170,8 @@ impl From<js_sys::Date> for DateTime<offset_kind::Fixed> {
impl From<DateTime<offset_kind::Fixed>> for js_sys::Date {
fn from(datetime: DateTime<offset_kind::Fixed>) -> Self {
// new Date() takes milliseconds
- let timestamp = (datetime.unix_timestamp_nanos() / 1_000_000) as f64;
+ let timestamp =
+ (datetime.unix_timestamp_nanos() / Nanosecond.per(Millisecond) as i128) as f64;
js_sys::Date::new(&timestamp.into())
}
}
diff --git a/vendor/time/src/duration.rs b/vendor/time/src/duration.rs
index 47c3f1516..453d2254d 100644
--- a/vendor/time/src/duration.rs
+++ b/vendor/time/src/duration.rs
@@ -6,6 +6,7 @@ use core::iter::Sum;
use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
use core::time::Duration as StdDuration;
+use crate::convert::*;
use crate::error;
#[cfg(feature = "std")]
use crate::Instant;
@@ -50,6 +51,124 @@ impl fmt::Debug for Duration {
}
}
+/// This is adapted from the `std` implementation, which uses mostly bit
+/// operations to ensure the highest precision:
+/// https://github.com/rust-lang/rust/blob/3a37c2f0523c87147b64f1b8099fc9df22e8c53e/library/core/src/time.rs#L1262-L1340
+/// Changes from `std` are marked and explained below.
+#[rustfmt::skip] // Skip `rustfmt` because it reformats the arguments of the macro weirdly.
+macro_rules! try_from_secs {
+ (
+ secs = $secs: expr,
+ mantissa_bits = $mant_bits: literal,
+ exponent_bits = $exp_bits: literal,
+ offset = $offset: literal,
+ bits_ty = $bits_ty:ty,
+ bits_ty_signed = $bits_ty_signed:ty,
+ double_ty = $double_ty:ty,
+ float_ty = $float_ty:ty,
+ is_nan = $is_nan:expr,
+ is_overflow = $is_overflow:expr,
+ ) => {{
+ 'value: {
+ const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
+ const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
+ const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
+
+ // Change from std: No error check for negative values necessary.
+
+ let bits = $secs.to_bits();
+ let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
+ let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
+
+ let (secs, nanos) = if exp < -31 {
+ // the input represents less than 1ns and can not be rounded to it
+ (0u64, 0u32)
+ } else if exp < 0 {
+ // the input is less than 1 second
+ let t = <$double_ty>::from(mant) << ($offset + exp);
+ let nanos_offset = $mant_bits + $offset;
+ let nanos_tmp = u128::from(Nanosecond.per(Second)) * u128::from(t);
+ let nanos = (nanos_tmp >> nanos_offset) as u32;
+
+ let rem_mask = (1 << nanos_offset) - 1;
+ let rem_msb_mask = 1 << (nanos_offset - 1);
+ let rem = nanos_tmp & rem_mask;
+ let is_tie = rem == rem_msb_mask;
+ let is_even = (nanos & 1) == 0;
+ let rem_msb = nanos_tmp & rem_msb_mask == 0;
+ let add_ns = !(rem_msb || (is_even && is_tie));
+
+ // f32 does not have enough precision to trigger the second branch
+ // since it can not represent numbers between 0.999_999_940_395 and 1.0.
+ let nanos = nanos + add_ns as u32;
+ if ($mant_bits == 23) || (nanos != Nanosecond.per(Second)) {
+ (0, nanos)
+ } else {
+ (1, 0)
+ }
+ } else if exp < $mant_bits {
+ let secs = u64::from(mant >> ($mant_bits - exp));
+ let t = <$double_ty>::from((mant << exp) & MANT_MASK);
+ let nanos_offset = $mant_bits;
+ let nanos_tmp = <$double_ty>::from(Nanosecond.per(Second)) * t;
+ let nanos = (nanos_tmp >> nanos_offset) as u32;
+
+ let rem_mask = (1 << nanos_offset) - 1;
+ let rem_msb_mask = 1 << (nanos_offset - 1);
+ let rem = nanos_tmp & rem_mask;
+ let is_tie = rem == rem_msb_mask;
+ let is_even = (nanos & 1) == 0;
+ let rem_msb = nanos_tmp & rem_msb_mask == 0;
+ let add_ns = !(rem_msb || (is_even && is_tie));
+
+ // f32 does not have enough precision to trigger the second branch.
+ // For example, it can not represent numbers between 1.999_999_880...
+ // and 2.0. Bigger values result in even smaller precision of the
+ // fractional part.
+ let nanos = nanos + add_ns as u32;
+ if ($mant_bits == 23) || (nanos != Nanosecond.per(Second)) {
+ (secs, nanos)
+ } else {
+ (secs + 1, 0)
+ }
+ } else if exp < 63 {
+ // Change from std: The exponent here is 63 instead of 64,
+ // because i64::MAX + 1 is 2^63.
+
+ // the input has no fractional part
+ let secs = u64::from(mant) << (exp - $mant_bits);
+ (secs, 0)
+ } else if bits == (i64::MIN as $float_ty).to_bits() {
+ // Change from std: Signed integers are asymmetrical in that
+ // iN::MIN is -iN::MAX - 1. So for example i8 covers the
+ // following numbers -128..=127. The check above (exp < 63)
+ // doesn't cover i64::MIN as that is -2^63, so we have this
+ // additional case to handle the asymmetry of iN::MIN.
+ break 'value Self::new_unchecked(i64::MIN, 0);
+ } else if $secs.is_nan() {
+ // Change from std: std doesn't differentiate between the error
+ // cases.
+ $is_nan
+ } else {
+ $is_overflow
+ };
+
+ // Change from std: All the code is mostly unmodified in that it
+ // simply calculates an unsigned integer. Here we extract the sign
+ // bit and assign it to the number. We basically manually do two's
+ // complement here, we could also use an if and just negate the
+ // numbers based on the sign, but it turns out to be quite a bit
+ // slower.
+ let mask = (bits as $bits_ty_signed) >> ($mant_bits + $exp_bits);
+ #[allow(trivial_numeric_casts)]
+ let secs_signed = ((secs as i64) ^ (mask as i64)) - (mask as i64);
+ #[allow(trivial_numeric_casts)]
+ let nanos_signed = ((nanos as i32) ^ (mask as i32)) - (mask as i32);
+ Self::new_unchecked(secs_signed, nanos_signed)
+ }
+ }};
+}
+
impl Duration {
// region: constants
/// Equivalent to `0.seconds()`.
@@ -125,10 +244,10 @@ impl Duration {
pub const WEEK: Self = Self::weeks(1);
/// The minimum possible duration. Adding any negative duration to this will cause an overflow.
- pub const MIN: Self = Self::new_unchecked(i64::MIN, -999_999_999);
+ pub const MIN: Self = Self::new_unchecked(i64::MIN, -((Nanosecond.per(Second) - 1) as i32));
/// The maximum possible duration. Adding any positive duration to this will cause an overflow.
- pub const MAX: Self = Self::new_unchecked(i64::MAX, 999_999_999);
+ pub const MAX: Self = Self::new_unchecked(i64::MAX, (Nanosecond.per(Second) - 1) as _);
// endregion constants
// region: is_{sign}
@@ -202,12 +321,12 @@ impl Duration {
pub(crate) const fn new_unchecked(seconds: i64, nanoseconds: i32) -> Self {
if seconds < 0 {
debug_assert!(nanoseconds <= 0);
- debug_assert!(nanoseconds > -1_000_000_000);
+ debug_assert!(nanoseconds > -(Nanosecond.per(Second) as i32));
} else if seconds > 0 {
debug_assert!(nanoseconds >= 0);
- debug_assert!(nanoseconds < 1_000_000_000);
+ debug_assert!(nanoseconds < Nanosecond.per(Second) as _);
} else {
- debug_assert!(nanoseconds.unsigned_abs() < 1_000_000_000);
+ debug_assert!(nanoseconds.unsigned_abs() < Nanosecond.per(Second));
}
Self {
@@ -228,19 +347,19 @@ impl Duration {
/// ```
pub const fn new(mut seconds: i64, mut nanoseconds: i32) -> Self {
seconds = expect_opt!(
- seconds.checked_add(nanoseconds as i64 / 1_000_000_000),
+ seconds.checked_add(nanoseconds as i64 / Nanosecond.per(Second) as i64),
"overflow constructing `time::Duration`"
);
- nanoseconds %= 1_000_000_000;
+ nanoseconds %= Nanosecond.per(Second) as i32;
if seconds > 0 && nanoseconds < 0 {
// `seconds` cannot overflow here because it is positive.
seconds -= 1;
- nanoseconds += 1_000_000_000;
+ nanoseconds += Nanosecond.per(Second) as i32;
} else if seconds < 0 && nanoseconds > 0 {
// `seconds` cannot overflow here because it is negative.
seconds += 1;
- nanoseconds -= 1_000_000_000;
+ nanoseconds -= Nanosecond.per(Second) as i32;
}
Self::new_unchecked(seconds, nanoseconds)
@@ -255,7 +374,7 @@ impl Duration {
/// ```
pub const fn weeks(weeks: i64) -> Self {
Self::seconds(expect_opt!(
- weeks.checked_mul(604_800),
+ weeks.checked_mul(Second.per(Week) as _),
"overflow constructing `time::Duration`"
))
}
@@ -269,7 +388,7 @@ impl Duration {
/// ```
pub const fn days(days: i64) -> Self {
Self::seconds(expect_opt!(
- days.checked_mul(86_400),
+ days.checked_mul(Second.per(Day) as _),
"overflow constructing `time::Duration`"
))
}
@@ -283,7 +402,7 @@ impl Duration {
/// ```
pub const fn hours(hours: i64) -> Self {
Self::seconds(expect_opt!(
- hours.checked_mul(3_600),
+ hours.checked_mul(Second.per(Hour) as _),
"overflow constructing `time::Duration`"
))
}
@@ -297,7 +416,7 @@ impl Duration {
/// ```
pub const fn minutes(minutes: i64) -> Self {
Self::seconds(expect_opt!(
- minutes.checked_mul(60),
+ minutes.checked_mul(Second.per(Minute) as _),
"overflow constructing `time::Duration`"
))
}
@@ -320,16 +439,18 @@ impl Duration {
/// assert_eq!(Duration::seconds_f64(-0.5), -0.5.seconds());
/// ```
pub fn seconds_f64(seconds: f64) -> Self {
- if seconds > i64::MAX as f64 || seconds < i64::MIN as f64 {
- crate::expect_failed("overflow constructing `time::Duration`");
- }
- if seconds.is_nan() {
- crate::expect_failed("passed NaN to `time::Duration::seconds_f64`");
- }
- let seconds_truncated = seconds as i64;
- // This only works because we handle the overflow condition above.
- let nanoseconds = ((seconds - seconds_truncated as f64) * 1_000_000_000.) as i32;
- Self::new_unchecked(seconds_truncated, nanoseconds)
+ try_from_secs!(
+ secs = seconds,
+ mantissa_bits = 52,
+ exponent_bits = 11,
+ offset = 44,
+ bits_ty = u64,
+ bits_ty_signed = i64,
+ double_ty = u128,
+ float_ty = f64,
+ is_nan = crate::expect_failed("passed NaN to `time::Duration::seconds_f64`"),
+ is_overflow = crate::expect_failed("overflow constructing `time::Duration`"),
+ )
}
/// Creates a new `Duration` from the specified number of seconds represented as `f32`.
@@ -340,16 +461,146 @@ impl Duration {
/// assert_eq!(Duration::seconds_f32(-0.5), (-0.5).seconds());
/// ```
pub fn seconds_f32(seconds: f32) -> Self {
- if seconds > i64::MAX as f32 || seconds < i64::MIN as f32 {
- crate::expect_failed("overflow constructing `time::Duration`");
- }
- if seconds.is_nan() {
- crate::expect_failed("passed NaN to `time::Duration::seconds_f32`");
- }
- let seconds_truncated = seconds as i64;
- // This only works because we handle the overflow condition above.
- let nanoseconds = ((seconds - seconds_truncated as f32) * 1_000_000_000.) as i32;
- Self::new_unchecked(seconds_truncated, nanoseconds)
+ try_from_secs!(
+ secs = seconds,
+ mantissa_bits = 23,
+ exponent_bits = 8,
+ offset = 41,
+ bits_ty = u32,
+ bits_ty_signed = i32,
+ double_ty = u64,
+ float_ty = f32,
+ is_nan = crate::expect_failed("passed NaN to `time::Duration::seconds_f32`"),
+ is_overflow = crate::expect_failed("overflow constructing `time::Duration`"),
+ )
+ }
+
+ /// Creates a new `Duration` from the specified number of seconds
+ /// represented as `f64`. Any values that are out of bounds are saturated at
+ /// the minimum or maximum respectively. `NaN` gets turned into a `Duration`
+ /// of 0 seconds.
+ ///
+ /// ```rust
+ /// # use time::{Duration, ext::NumericalDuration};
+ /// assert_eq!(Duration::saturating_seconds_f64(0.5), 0.5.seconds());
+ /// assert_eq!(Duration::saturating_seconds_f64(-0.5), -0.5.seconds());
+ /// assert_eq!(
+ /// Duration::saturating_seconds_f64(f64::NAN),
+ /// Duration::new(0, 0),
+ /// );
+ /// assert_eq!(
+ /// Duration::saturating_seconds_f64(f64::NEG_INFINITY),
+ /// Duration::MIN,
+ /// );
+ /// assert_eq!(
+ /// Duration::saturating_seconds_f64(f64::INFINITY),
+ /// Duration::MAX,
+ /// );
+ /// ```
+ pub fn saturating_seconds_f64(seconds: f64) -> Self {
+ try_from_secs!(
+ secs = seconds,
+ mantissa_bits = 52,
+ exponent_bits = 11,
+ offset = 44,
+ bits_ty = u64,
+ bits_ty_signed = i64,
+ double_ty = u128,
+ float_ty = f64,
+ is_nan = return Self::ZERO,
+ is_overflow = return if seconds < 0.0 { Self::MIN } else { Self::MAX },
+ )
+ }
+
+ /// Creates a new `Duration` from the specified number of seconds
+ /// represented as `f32`. Any values that are out of bounds are saturated at
+ /// the minimum or maximum respectively. `NaN` gets turned into a `Duration`
+ /// of 0 seconds.
+ ///
+ /// ```rust
+ /// # use time::{Duration, ext::NumericalDuration};
+ /// assert_eq!(Duration::saturating_seconds_f32(0.5), 0.5.seconds());
+ /// assert_eq!(Duration::saturating_seconds_f32(-0.5), (-0.5).seconds());
+ /// assert_eq!(
+ /// Duration::saturating_seconds_f32(f32::NAN),
+ /// Duration::new(0, 0),
+ /// );
+ /// assert_eq!(
+ /// Duration::saturating_seconds_f32(f32::NEG_INFINITY),
+ /// Duration::MIN,
+ /// );
+ /// assert_eq!(
+ /// Duration::saturating_seconds_f32(f32::INFINITY),
+ /// Duration::MAX,
+ /// );
+ /// ```
+ pub fn saturating_seconds_f32(seconds: f32) -> Self {
+ try_from_secs!(
+ secs = seconds,
+ mantissa_bits = 23,
+ exponent_bits = 8,
+ offset = 41,
+ bits_ty = u32,
+ bits_ty_signed = i32,
+ double_ty = u64,
+ float_ty = f32,
+ is_nan = return Self::ZERO,
+ is_overflow = return if seconds < 0.0 { Self::MIN } else { Self::MAX },
+ )
+ }
+
+ /// Creates a new `Duration` from the specified number of seconds
+ /// represented as `f64`. Returns `None` if the `Duration` can't be
+ /// represented.
+ ///
+ /// ```rust
+ /// # use time::{Duration, ext::NumericalDuration};
+ /// assert_eq!(Duration::checked_seconds_f64(0.5), Some(0.5.seconds()));
+ /// assert_eq!(Duration::checked_seconds_f64(-0.5), Some(-0.5.seconds()));
+ /// assert_eq!(Duration::checked_seconds_f64(f64::NAN), None);
+ /// assert_eq!(Duration::checked_seconds_f64(f64::NEG_INFINITY), None);
+ /// assert_eq!(Duration::checked_seconds_f64(f64::INFINITY), None);
+ /// ```
+ pub fn checked_seconds_f64(seconds: f64) -> Option<Self> {
+ Some(try_from_secs!(
+ secs = seconds,
+ mantissa_bits = 52,
+ exponent_bits = 11,
+ offset = 44,
+ bits_ty = u64,
+ bits_ty_signed = i64,
+ double_ty = u128,
+ float_ty = f64,
+ is_nan = return None,
+ is_overflow = return None,
+ ))
+ }
+
+ /// Creates a new `Duration` from the specified number of seconds
+ /// represented as `f32`. Returns `None` if the `Duration` can't be
+ /// represented.
+ ///
+ /// ```rust
+ /// # use time::{Duration, ext::NumericalDuration};
+ /// assert_eq!(Duration::checked_seconds_f32(0.5), Some(0.5.seconds()));
+ /// assert_eq!(Duration::checked_seconds_f32(-0.5), Some(-0.5.seconds()));
+ /// assert_eq!(Duration::checked_seconds_f32(f32::NAN), None);
+ /// assert_eq!(Duration::checked_seconds_f32(f32::NEG_INFINITY), None);
+ /// assert_eq!(Duration::checked_seconds_f32(f32::INFINITY), None);
+ /// ```
+ pub fn checked_seconds_f32(seconds: f32) -> Option<Self> {
+ Some(try_from_secs!(
+ secs = seconds,
+ mantissa_bits = 23,
+ exponent_bits = 8,
+ offset = 41,
+ bits_ty = u32,
+ bits_ty_signed = i32,
+ double_ty = u64,
+ float_ty = f32,
+ is_nan = return None,
+ is_overflow = return None,
+ ))
}
/// Create a new `Duration` with the given number of milliseconds.
@@ -361,8 +612,9 @@ impl Duration {
/// ```
pub const fn milliseconds(milliseconds: i64) -> Self {
Self::new_unchecked(
- milliseconds / 1_000,
- ((milliseconds % 1_000) * 1_000_000) as _,
+ milliseconds / Millisecond.per(Second) as i64,
+ (milliseconds % Millisecond.per(Second) as i64 * Nanosecond.per(Millisecond) as i64)
+ as _,
)
}
@@ -375,8 +627,9 @@ impl Duration {
/// ```
pub const fn microseconds(microseconds: i64) -> Self {
Self::new_unchecked(
- microseconds / 1_000_000,
- ((microseconds % 1_000_000) * 1_000) as _,
+ microseconds / Microsecond.per(Second) as i64,
+ (microseconds % Microsecond.per(Second) as i64 * Nanosecond.per(Microsecond) as i64)
+ as _,
)
}
@@ -389,8 +642,8 @@ impl Duration {
/// ```
pub const fn nanoseconds(nanoseconds: i64) -> Self {
Self::new_unchecked(
- nanoseconds / 1_000_000_000,
- (nanoseconds % 1_000_000_000) as _,
+ nanoseconds / Nanosecond.per(Second) as i64,
+ (nanoseconds % Nanosecond.per(Second) as i64) as _,
)
}
@@ -399,8 +652,8 @@ impl Duration {
/// As the input range cannot be fully mapped to the output, this should only be used where it's
/// known to result in a valid value.
pub(crate) const fn nanoseconds_i128(nanoseconds: i128) -> Self {
- let seconds = nanoseconds / 1_000_000_000;
- let nanoseconds = nanoseconds % 1_000_000_000;
+ let seconds = nanoseconds / Nanosecond.per(Second) as i128;
+ let nanoseconds = nanoseconds % Nanosecond.per(Second) as i128;
if seconds > i64::MAX as i128 || seconds < i64::MIN as i128 {
crate::expect_failed("overflow constructing `time::Duration`");
@@ -421,7 +674,7 @@ impl Duration {
/// assert_eq!((-6).days().whole_weeks(), 0);
/// ```
pub const fn whole_weeks(self) -> i64 {
- self.whole_seconds() / 604_800
+ self.whole_seconds() / Second.per(Week) as i64
}
/// Get the number of whole days in the duration.
@@ -434,7 +687,7 @@ impl Duration {
/// assert_eq!((-23).hours().whole_days(), 0);
/// ```
pub const fn whole_days(self) -> i64 {
- self.whole_seconds() / 86_400
+ self.whole_seconds() / Second.per(Day) as i64
}
/// Get the number of whole hours in the duration.
@@ -447,7 +700,7 @@ impl Duration {
/// assert_eq!((-59).minutes().whole_hours(), 0);
/// ```
pub const fn whole_hours(self) -> i64 {
- self.whole_seconds() / 3_600
+ self.whole_seconds() / Second.per(Hour) as i64
}
/// Get the number of whole minutes in the duration.
@@ -460,7 +713,7 @@ impl Duration {
/// assert_eq!((-59).seconds().whole_minutes(), 0);
/// ```
pub const fn whole_minutes(self) -> i64 {
- self.whole_seconds() / 60
+ self.whole_seconds() / Second.per(Minute) as i64
}
/// Get the number of whole seconds in the duration.
@@ -484,7 +737,7 @@ impl Duration {
/// assert_eq!((-1.5).seconds().as_seconds_f64(), -1.5);
/// ```
pub fn as_seconds_f64(self) -> f64 {
- self.seconds as f64 + self.nanoseconds as f64 / 1_000_000_000.
+ self.seconds as f64 + self.nanoseconds as f64 / Nanosecond.per(Second) as f64
}
/// Get the number of fractional seconds in the duration.
@@ -495,7 +748,7 @@ impl Duration {
/// assert_eq!((-1.5).seconds().as_seconds_f32(), -1.5);
/// ```
pub fn as_seconds_f32(self) -> f32 {
- self.seconds as f32 + self.nanoseconds as f32 / 1_000_000_000.
+ self.seconds as f32 + self.nanoseconds as f32 / Nanosecond.per(Second) as f32
}
/// Get the number of whole milliseconds in the duration.
@@ -508,7 +761,8 @@ impl Duration {
/// assert_eq!((-1).milliseconds().whole_milliseconds(), -1);
/// ```
pub const fn whole_milliseconds(self) -> i128 {
- self.seconds as i128 * 1_000 + self.nanoseconds as i128 / 1_000_000
+ self.seconds as i128 * Millisecond.per(Second) as i128
+ + self.nanoseconds as i128 / Nanosecond.per(Millisecond) as i128
}
/// Get the number of milliseconds past the number of whole seconds.
@@ -522,7 +776,7 @@ impl Duration {
/// ```
// Allow the lint, as the value is guaranteed to be less than 1000.
pub const fn subsec_milliseconds(self) -> i16 {
- (self.nanoseconds / 1_000_000) as _
+ (self.nanoseconds / Nanosecond.per(Millisecond) as i32) as _
}
/// Get the number of whole microseconds in the duration.
@@ -535,7 +789,8 @@ impl Duration {
/// assert_eq!((-1).microseconds().whole_microseconds(), -1);
/// ```
pub const fn whole_microseconds(self) -> i128 {
- self.seconds as i128 * 1_000_000 + self.nanoseconds as i128 / 1_000
+ self.seconds as i128 * Microsecond.per(Second) as i128
+ + self.nanoseconds as i128 / Nanosecond.per(Microsecond) as i128
}
/// Get the number of microseconds past the number of whole seconds.
@@ -548,7 +803,7 @@ impl Duration {
/// assert_eq!((-1.0004).seconds().subsec_microseconds(), -400);
/// ```
pub const fn subsec_microseconds(self) -> i32 {
- self.nanoseconds / 1_000
+ self.nanoseconds / Nanosecond.per(Microsecond) as i32
}
/// Get the number of nanoseconds in the duration.
@@ -561,7 +816,7 @@ impl Duration {
/// assert_eq!((-1).nanoseconds().whole_nanoseconds(), -1);
/// ```
pub const fn whole_nanoseconds(self) -> i128 {
- self.seconds as i128 * 1_000_000_000 + self.nanoseconds as i128
+ self.seconds as i128 * Nanosecond.per(Second) as i128 + self.nanoseconds as i128
}
/// Get the number of nanoseconds past the number of whole seconds.
@@ -591,11 +846,12 @@ impl Duration {
let mut seconds = const_try_opt!(self.seconds.checked_add(rhs.seconds));
let mut nanoseconds = self.nanoseconds + rhs.nanoseconds;
- if nanoseconds >= 1_000_000_000 || seconds < 0 && nanoseconds > 0 {
- nanoseconds -= 1_000_000_000;
+ if nanoseconds >= Nanosecond.per(Second) as _ || seconds < 0 && nanoseconds > 0 {
+ nanoseconds -= Nanosecond.per(Second) as i32;
seconds = const_try_opt!(seconds.checked_add(1));
- } else if nanoseconds <= -1_000_000_000 || seconds > 0 && nanoseconds < 0 {
- nanoseconds += 1_000_000_000;
+ } else if nanoseconds <= -(Nanosecond.per(Second) as i32) || seconds > 0 && nanoseconds < 0
+ {
+ nanoseconds += Nanosecond.per(Second) as i32;
seconds = const_try_opt!(seconds.checked_sub(1));
}
@@ -614,11 +870,12 @@ impl Duration {
let mut seconds = const_try_opt!(self.seconds.checked_sub(rhs.seconds));
let mut nanoseconds = self.nanoseconds - rhs.nanoseconds;
- if nanoseconds >= 1_000_000_000 || seconds < 0 && nanoseconds > 0 {
- nanoseconds -= 1_000_000_000;
+ if nanoseconds >= Nanosecond.per(Second) as _ || seconds < 0 && nanoseconds > 0 {
+ nanoseconds -= Nanosecond.per(Second) as i32;
seconds = const_try_opt!(seconds.checked_add(1));
- } else if nanoseconds <= -1_000_000_000 || seconds > 0 && nanoseconds < 0 {
- nanoseconds += 1_000_000_000;
+ } else if nanoseconds <= -(Nanosecond.per(Second) as i32) || seconds > 0 && nanoseconds < 0
+ {
+ nanoseconds += Nanosecond.per(Second) as i32;
seconds = const_try_opt!(seconds.checked_sub(1));
}
@@ -638,8 +895,8 @@ impl Duration {
pub const fn checked_mul(self, rhs: i32) -> Option<Self> {
// Multiply nanoseconds as i64, because it cannot overflow that way.
let total_nanos = self.nanoseconds as i64 * rhs as i64;
- let extra_secs = total_nanos / 1_000_000_000;
- let nanoseconds = (total_nanos % 1_000_000_000) as _;
+ let extra_secs = total_nanos / Nanosecond.per(Second) as i64;
+ let nanoseconds = (total_nanos % Nanosecond.per(Second) as i64) as _;
let seconds = const_try_opt!(
const_try_opt!(self.seconds.checked_mul(rhs as _)).checked_add(extra_secs)
);
@@ -658,7 +915,8 @@ impl Duration {
pub const fn checked_div(self, rhs: i32) -> Option<Self> {
let seconds = const_try_opt!(self.seconds.checked_div(rhs as i64));
let carry = self.seconds - seconds * (rhs as i64);
- let extra_nanos = const_try_opt!((carry * 1_000_000_000).checked_div(rhs as i64));
+ let extra_nanos =
+ const_try_opt!((carry * Nanosecond.per(Second) as i64).checked_div(rhs as i64));
let nanoseconds = const_try_opt!(self.nanoseconds.checked_div(rhs)) + (extra_nanos as i32);
Some(Self::new_unchecked(seconds, nanoseconds))
@@ -688,14 +946,15 @@ impl Duration {
}
let mut nanoseconds = self.nanoseconds + rhs.nanoseconds;
- if nanoseconds >= 1_000_000_000 || seconds < 0 && nanoseconds > 0 {
- nanoseconds -= 1_000_000_000;
+ if nanoseconds >= Nanosecond.per(Second) as _ || seconds < 0 && nanoseconds > 0 {
+ nanoseconds -= Nanosecond.per(Second) as i32;
seconds = match seconds.checked_add(1) {
Some(seconds) => seconds,
None => return Self::MAX,
};
- } else if nanoseconds <= -1_000_000_000 || seconds > 0 && nanoseconds < 0 {
- nanoseconds += 1_000_000_000;
+ } else if nanoseconds <= -(Nanosecond.per(Second) as i32) || seconds > 0 && nanoseconds < 0
+ {
+ nanoseconds += Nanosecond.per(Second) as i32;
seconds = match seconds.checked_sub(1) {
Some(seconds) => seconds,
None => return Self::MIN,
@@ -727,14 +986,15 @@ impl Duration {
}
let mut nanoseconds = self.nanoseconds - rhs.nanoseconds;
- if nanoseconds >= 1_000_000_000 || seconds < 0 && nanoseconds > 0 {
- nanoseconds -= 1_000_000_000;
+ if nanoseconds >= Nanosecond.per(Second) as _ || seconds < 0 && nanoseconds > 0 {
+ nanoseconds -= Nanosecond.per(Second) as i32;
seconds = match seconds.checked_add(1) {
Some(seconds) => seconds,
None => return Self::MAX,
};
- } else if nanoseconds <= -1_000_000_000 || seconds > 0 && nanoseconds < 0 {
- nanoseconds += 1_000_000_000;
+ } else if nanoseconds <= -(Nanosecond.per(Second) as i32) || seconds > 0 && nanoseconds < 0
+ {
+ nanoseconds += Nanosecond.per(Second) as i32;
seconds = match seconds.checked_sub(1) {
Some(seconds) => seconds,
None => return Self::MIN,
@@ -759,8 +1019,8 @@ impl Duration {
pub const fn saturating_mul(self, rhs: i32) -> Self {
// Multiply nanoseconds as i64, because it cannot overflow that way.
let total_nanos = self.nanoseconds as i64 * rhs as i64;
- let extra_secs = total_nanos / 1_000_000_000;
- let nanoseconds = (total_nanos % 1_000_000_000) as _;
+ let extra_secs = total_nanos / Nanosecond.per(Second) as i64;
+ let nanoseconds = (total_nanos % Nanosecond.per(Second) as i64) as _;
let (seconds, overflow1) = self.seconds.overflowing_mul(rhs as _);
if overflow1 {
if self.seconds > 0 && rhs > 0 || self.seconds < 0 && rhs < 0 {
@@ -834,13 +1094,13 @@ impl fmt::Display for Duration {
// Even if this produces a de-normal float, because we're rounding we don't really care.
let seconds = self.unsigned_abs().as_secs_f64();
- item!("d", seconds / 86_400.);
- item!("h", seconds / 3_600.);
- item!("m", seconds / 60.);
+ item!("d", seconds / Second.per(Day) as f64);
+ item!("h", seconds / Second.per(Hour) as f64);
+ item!("m", seconds / Second.per(Minute) as f64);
item!("s", seconds);
- item!("ms", seconds * 1_000.);
- item!("µs", seconds * 1_000_000.);
- item!("ns", seconds * 1_000_000_000.);
+ item!("ms", seconds * Millisecond.per(Second) as f64);
+ item!("µs", seconds * Microsecond.per(Second) as f64);
+ item!("ns", seconds * Nanosecond.per(Second) as f64);
} else {
// Precise, but verbose representation.
@@ -861,13 +1121,23 @@ impl fmt::Display for Duration {
let seconds = self.seconds.unsigned_abs();
let nanoseconds = self.nanoseconds.unsigned_abs();
- item!("d", seconds / 86_400)?;
- item!("h", seconds / 3_600 % 24)?;
- item!("m", seconds / 60 % 60)?;
- item!("s", seconds % 60)?;
- item!("ms", nanoseconds / 1_000_000)?;
- item!("µs", nanoseconds / 1_000 % 1_000)?;
- item!("ns", nanoseconds % 1_000)?;
+ item!("d", seconds / Second.per(Day) as u64)?;
+ item!(
+ "h",
+ seconds / Second.per(Hour) as u64 % Hour.per(Day) as u64
+ )?;
+ item!(
+ "m",
+ seconds / Second.per(Minute) as u64 % Minute.per(Hour) as u64
+ )?;
+ item!("s", seconds % Second.per(Minute) as u64)?;
+ item!("ms", nanoseconds / Nanosecond.per(Millisecond))?;
+ item!(
+ "µs",
+ nanoseconds / Nanosecond.per(Microsecond) as u32
+ % Microsecond.per(Millisecond) as u32
+ )?;
+ item!("ns", nanoseconds % Nanosecond.per(Microsecond) as u32)?;
}
Ok(())
diff --git a/vendor/time/src/ext.rs b/vendor/time/src/ext.rs
index 5a1393d86..8b7759d8e 100644
--- a/vendor/time/src/ext.rs
+++ b/vendor/time/src/ext.rs
@@ -2,6 +2,7 @@
use core::time::Duration as StdDuration;
+use crate::convert::*;
use crate::Duration;
/// Sealed trait to prevent downstream implementations.
@@ -116,31 +117,31 @@ impl NumericalDuration for f64 {
}
fn microseconds(self) -> Duration {
- Duration::nanoseconds((self * 1_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Microsecond) as Self) as _)
}
fn milliseconds(self) -> Duration {
- Duration::nanoseconds((self * 1_000_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Millisecond) as Self) as _)
}
fn seconds(self) -> Duration {
- Duration::nanoseconds((self * 1_000_000_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Second) as Self) as _)
}
fn minutes(self) -> Duration {
- Duration::nanoseconds((self * 60_000_000_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Minute) as Self) as _)
}
fn hours(self) -> Duration {
- Duration::nanoseconds((self * 3_600_000_000_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Hour) as Self) as _)
}
fn days(self) -> Duration {
- Duration::nanoseconds((self * 86_400_000_000_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Day) as Self) as _)
}
fn weeks(self) -> Duration {
- Duration::nanoseconds((self * 604_800_000_000_000.) as _)
+ Duration::nanoseconds((self * Nanosecond.per(Week) as Self) as _)
}
}
// endregion NumericalDuration
@@ -219,19 +220,19 @@ impl NumericalStdDuration for u64 {
}
fn std_minutes(self) -> StdDuration {
- StdDuration::from_secs(self * 60)
+ StdDuration::from_secs(self * Second.per(Minute) as Self)
}
fn std_hours(self) -> StdDuration {
- StdDuration::from_secs(self * 3_600)
+ StdDuration::from_secs(self * Second.per(Hour) as Self)
}
fn std_days(self) -> StdDuration {
- StdDuration::from_secs(self * 86_400)
+ StdDuration::from_secs(self * Second.per(Day) as Self)
}
fn std_weeks(self) -> StdDuration {
- StdDuration::from_secs(self * 604_800)
+ StdDuration::from_secs(self * Second.per(Week) as Self)
}
}
@@ -243,37 +244,37 @@ impl NumericalStdDuration for f64 {
fn std_microseconds(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 1_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Microsecond) as Self) as _)
}
fn std_milliseconds(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 1_000_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Millisecond) as Self) as _)
}
fn std_seconds(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 1_000_000_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Second) as Self) as _)
}
fn std_minutes(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 60_000_000_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Minute) as Self) as _)
}
fn std_hours(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 3_600_000_000_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Hour) as Self) as _)
}
fn std_days(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 86_400_000_000_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Day) as Self) as _)
}
fn std_weeks(self) -> StdDuration {
assert!(self >= 0.);
- StdDuration::from_nanos((self * 604_800_000_000_000.) as _)
+ StdDuration::from_nanos((self * Nanosecond.per(Week) as Self) as _)
}
}
// endregion NumericalStdDuration
diff --git a/vendor/time/src/format_description/mod.rs b/vendor/time/src/format_description/mod.rs
index 4d328f675..befae8b56 100644
--- a/vendor/time/src/format_description/mod.rs
+++ b/vendor/time/src/format_description/mod.rs
@@ -3,6 +3,9 @@
//! The formatted value will be output to the provided writer. Format descriptions can be
//! [well-known](crate::format_description::well_known) or obtained by using the
//! [`format_description!`](crate::macros::format_description) macro or a function listed below.
+//!
+//! For examples, see the implementors of [Formattable](crate::formatting::Formattable),
+//! e.g. [`well_known::Rfc3339`].
mod borrowed_format_item;
mod component;
diff --git a/vendor/time/src/format_description/parse/ast.rs b/vendor/time/src/format_description/parse/ast.rs
index f7b0ab78c..12fc5d55d 100644
--- a/vendor/time/src/format_description/parse/ast.rs
+++ b/vendor/time/src/format_description/parse/ast.rs
@@ -184,7 +184,7 @@ fn parse_component<
validate_version!(VERSION);
let leading_whitespace = tokens.next_if_whitespace();
- guard!(let Some(name) = tokens.next_if_not_whitespace() else {
+ let Some(name) = tokens.next_if_not_whitespace() else {
let span = match leading_whitespace {
Some(Spanned { value: _, span }) => span,
None => opening_bracket.to(opening_bracket),
@@ -195,10 +195,10 @@ fn parse_component<
index: span.start.byte as _,
},
});
- });
+ };
if *name == b"optional" {
- guard!(let Some(whitespace) = tokens.next_if_whitespace() else {
+ let Some(whitespace) = tokens.next_if_whitespace() else {
return Err(Error {
_inner: unused(name.span.error("expected whitespace after `optional`")),
public: crate::error::InvalidFormatDescription::Expected {
@@ -206,18 +206,18 @@ fn parse_component<
index: name.span.end.byte as _,
},
});
- });
+ };
let nested = parse_nested::<_, VERSION>(whitespace.span.end, tokens)?;
- guard!(let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
+ let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
return Err(Error {
_inner: unused(opening_bracket.error("unclosed bracket")),
public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket {
index: opening_bracket.byte as _,
},
});
- });
+ };
return Ok(Item::Optional {
opening_bracket,
@@ -230,7 +230,7 @@ fn parse_component<
}
if *name == b"first" {
- guard!(let Some(whitespace) = tokens.next_if_whitespace() else {
+ let Some(whitespace) = tokens.next_if_whitespace() else {
return Err(Error {
_inner: unused(name.span.error("expected whitespace after `first`")),
public: crate::error::InvalidFormatDescription::Expected {
@@ -238,21 +238,21 @@ fn parse_component<
index: name.span.end.byte as _,
},
});
- });
+ };
let mut nested_format_descriptions = Vec::new();
while let Ok(description) = parse_nested::<_, VERSION>(whitespace.span.end, tokens) {
nested_format_descriptions.push(description);
}
- guard!(let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
+ let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
return Err(Error {
_inner: unused(opening_bracket.error("unclosed bracket")),
public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket {
index: opening_bracket.byte as _,
},
});
- });
+ };
return Ok(Item::First {
opening_bracket,
@@ -266,7 +266,7 @@ fn parse_component<
let mut modifiers = Vec::new();
let trailing_whitespace = loop {
- guard!(let Some(whitespace) = tokens.next_if_whitespace() else { break None });
+ let Some(whitespace) = tokens.next_if_whitespace() else { break None };
// This is not necessary for proper parsing, but provides a much better error when a nested
// description is used where it's not allowed.
@@ -284,11 +284,11 @@ fn parse_component<
});
}
- guard!(let Some(Spanned { value, span }) = tokens.next_if_not_whitespace() else {
+ let Some(Spanned { value, span }) = tokens.next_if_not_whitespace() else {
break Some(whitespace);
- });
+ };
- guard!(let Some(colon_index) = value.iter().position(|&b| b == b':') else {
+ let Some(colon_index) = value.iter().position(|&b| b == b':') else {
return Err(Error {
_inner: unused(span.error("modifier must be of the form `key:value`")),
public: crate::error::InvalidFormatDescription::InvalidModifier {
@@ -296,7 +296,7 @@ fn parse_component<
index: span.start.byte as _,
},
});
- });
+ };
let key = &value[..colon_index];
let value = &value[colon_index + 1..];
@@ -327,14 +327,14 @@ fn parse_component<
});
};
- guard!(let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
+ let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
return Err(Error {
_inner: unused(opening_bracket.error("unclosed bracket")),
public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket {
index: opening_bracket.byte as _,
},
});
- });
+ };
Ok(Item::Component {
_opening_bracket: unused(opening_bracket),
@@ -352,7 +352,7 @@ fn parse_nested<'a, I: Iterator<Item = Result<lexer::Token<'a>, Error>>, const V
tokens: &mut lexer::Lexed<I>,
) -> Result<NestedFormatDescription<'a>, Error> {
validate_version!(VERSION);
- guard!(let Some(opening_bracket) = tokens.next_if_opening_bracket() else {
+ let Some(opening_bracket) = tokens.next_if_opening_bracket() else {
return Err(Error {
_inner: unused(last_location.error("expected opening bracket")),
public: crate::error::InvalidFormatDescription::Expected {
@@ -360,16 +360,16 @@ fn parse_nested<'a, I: Iterator<Item = Result<lexer::Token<'a>, Error>>, const V
index: last_location.byte as _,
},
});
- });
+ };
let items = parse_inner::<_, true, VERSION>(tokens).collect::<Result<_, _>>()?;
- guard!(let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
+ let Some(closing_bracket) = tokens.next_if_closing_bracket() else {
return Err(Error {
_inner: unused(opening_bracket.error("unclosed bracket")),
public: crate::error::InvalidFormatDescription::UnclosedOpeningBracket {
index: opening_bracket.byte as _,
},
});
- });
+ };
let trailing_whitespace = tokens.next_if_whitespace();
Ok(NestedFormatDescription {
diff --git a/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs b/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs
index 757a68b18..1fdecaf26 100644
--- a/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs
+++ b/vendor/time/src/format_description/well_known/iso8601/adt_hack.rs
@@ -11,7 +11,7 @@ use super::{Config, DateKind, FormattedComponents as FC, OffsetPrecision, TimePr
#[doc(hidden)]
pub type DoNotRelyOnWhatThisIs = u128;
-/// An encoded [`Config`] that can be used as a const parameter to [`Iso8601`].
+/// An encoded [`Config`] that can be used as a const parameter to [`Iso8601`](super::Iso8601).
///
/// The type this is aliased to must not be relied upon. It can change in any release without
/// notice.
@@ -49,10 +49,11 @@ impl<const CONFIG: EncodedConfig> Iso8601<CONFIG> {
}
impl Config {
- /// Encode the configuration, permitting it to be used as a const parameter of [`Iso8601`].
+ /// Encode the configuration, permitting it to be used as a const parameter of
+ /// [`Iso8601`](super::Iso8601).
///
- /// The value returned by this method must only be used as a const parameter to [`Iso8601`]. Any
- /// other usage is unspecified behavior.
+ /// The value returned by this method must only be used as a const parameter to
+ /// [`Iso8601`](super::Iso8601). Any other usage is unspecified behavior.
pub const fn encode(&self) -> EncodedConfig {
let mut bytes = [0; EncodedConfig::BITS as usize / 8];
diff --git a/vendor/time/src/formatting/formattable.rs b/vendor/time/src/formatting/formattable.rs
index 2c0d7badf..2b4b35088 100644
--- a/vendor/time/src/formatting/formattable.rs
+++ b/vendor/time/src/formatting/formattable.rs
@@ -11,7 +11,12 @@ use crate::formatting::{
};
use crate::{error, Date, Time, UtcOffset};
-/// A type that can be formatted.
+/// A type that describes a format.
+///
+/// Implementors of [`Formattable`] are [format descriptions](crate::format_description).
+///
+/// [`Date::format`] and [`Time::format`] each use a format description to generate
+/// a String from their data. See the respective methods for usage examples.
#[cfg_attr(__time_03_docs, doc(notable_trait))]
pub trait Formattable: sealed::Sealed {}
impl Formattable for FormatItem<'_> {}
diff --git a/vendor/time/src/formatting/iso8601.rs b/vendor/time/src/formatting/iso8601.rs
index 229a07ebc..29d443ef4 100644
--- a/vendor/time/src/formatting/iso8601.rs
+++ b/vendor/time/src/formatting/iso8601.rs
@@ -2,6 +2,7 @@
use std::io;
+use crate::convert::*;
use crate::format_description::well_known::iso8601::{
DateKind, EncodedConfig, OffsetPrecision, TimePrecision,
};
@@ -84,17 +85,17 @@ pub(super) fn format_time<const CONFIG: EncodedConfig>(
match Iso8601::<CONFIG>::TIME_PRECISION {
TimePrecision::Hour { decimal_digits } => {
let hours = (hours as f64)
- + (minutes as f64) / 60.
- + (seconds as f64) / 3_600.
- + (nanoseconds as f64) / 3_600. / 1_000_000_000.;
+ + (minutes as f64) / Minute.per(Hour) as f64
+ + (seconds as f64) / Second.per(Hour) as f64
+ + (nanoseconds as f64) / Nanosecond.per(Hour) as f64;
format_float(output, hours, 2, decimal_digits)?;
}
TimePrecision::Minute { decimal_digits } => {
bytes += format_number_pad_zero::<2>(output, hours)?;
bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?;
let minutes = (minutes as f64)
- + (seconds as f64) / 60.
- + (nanoseconds as f64) / 60. / 1_000_000_000.;
+ + (seconds as f64) / Second.per(Minute) as f64
+ + (nanoseconds as f64) / Nanosecond.per(Minute) as f64;
bytes += format_float(output, minutes, 2, decimal_digits)?;
}
TimePrecision::Second { decimal_digits } => {
@@ -102,7 +103,7 @@ pub(super) fn format_time<const CONFIG: EncodedConfig>(
bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?;
bytes += format_number_pad_zero::<2>(output, minutes)?;
bytes += write_if(output, Iso8601::<CONFIG>::USE_SEPARATORS, b":")?;
- let seconds = (seconds as f64) + (nanoseconds as f64) / 1_000_000_000.;
+ let seconds = (seconds as f64) + (nanoseconds as f64) / Nanosecond.per(Second) as f64;
bytes += format_float(output, seconds, 2, decimal_digits)?;
}
}
diff --git a/vendor/time/src/formatting/mod.rs b/vendor/time/src/formatting/mod.rs
index 1df4478a8..e5017063a 100644
--- a/vendor/time/src/formatting/mod.rs
+++ b/vendor/time/src/formatting/mod.rs
@@ -7,6 +7,7 @@ use core::num::NonZeroU8;
use std::io;
pub use self::formattable::Formattable;
+use crate::convert::*;
use crate::format_description::{modifier, Component};
use crate::{error, Date, OffsetDateTime, Time, UtcOffset};
@@ -531,11 +532,11 @@ fn fmt_unix_timestamp(
}
modifier::UnixTimestampPrecision::Millisecond => format_number_pad_none(
output,
- (date_time.unix_timestamp_nanos() / 1_000_000).unsigned_abs(),
+ (date_time.unix_timestamp_nanos() / Nanosecond.per(Millisecond) as i128).unsigned_abs(),
),
modifier::UnixTimestampPrecision::Microsecond => format_number_pad_none(
output,
- (date_time.unix_timestamp_nanos() / 1_000).unsigned_abs(),
+ (date_time.unix_timestamp_nanos() / Nanosecond.per(Microsecond) as i128).unsigned_abs(),
),
modifier::UnixTimestampPrecision::Nanosecond => {
format_number_pad_none(output, date_time.unix_timestamp_nanos().unsigned_abs())
diff --git a/vendor/time/src/lib.rs b/vendor/time/src/lib.rs
index ed4042e03..2ab59cf8e 100644
--- a/vendor/time/src/lib.rs
+++ b/vendor/time/src/lib.rs
@@ -204,13 +204,15 @@ macro_rules! cascade {
(@year year) => {};
// Cascade an out-of-bounds value from "from" to "to".
- ($from:ident in $min:literal.. $max:literal => $to:tt) => {
+ ($from:ident in $min:literal.. $max:expr => $to:tt) => {
#[allow(unused_comparisons, unused_assignments)]
- if $from >= $max {
- $from -= $max - $min;
+ let min = $min;
+ let max = $max;
+ if $from >= max {
+ $from -= max - min;
$to += 1;
- } else if $from < $min {
- $from += $max - $min;
+ } else if $from < min {
+ $from += max - min;
$to -= 1;
}
};
@@ -310,9 +312,6 @@ macro_rules! bug {
}
// endregion macros
-#[macro_use]
-mod shim;
-
mod date;
mod date_time;
mod duration;
@@ -346,6 +345,9 @@ mod utc_offset;
pub mod util;
mod weekday;
+// Not public yet.
+use time_core::convert;
+
pub use crate::date::Date;
use crate::date_time::DateTime;
pub use crate::duration::Duration;
diff --git a/vendor/time/src/offset_date_time.rs b/vendor/time/src/offset_date_time.rs
index 1e342ca8e..d979174e1 100644
--- a/vendor/time/src/offset_date_time.rs
+++ b/vendor/time/src/offset_date_time.rs
@@ -97,6 +97,30 @@ impl OffsetDateTime {
Self(self.0.to_offset(offset))
}
+ /// Convert the `OffsetDateTime` from the current [`UtcOffset`] to the provided [`UtcOffset`],
+ /// returning `None` if the date-time in the resulting offset is invalid.
+ ///
+ /// ```rust
+ /// # use time::PrimitiveDateTime;
+ /// # use time_macros::{datetime, offset};
+ /// assert_eq!(
+ /// datetime!(2000-01-01 0:00 UTC)
+ /// .checked_to_offset(offset!(-1))
+ /// .unwrap()
+ /// .year(),
+ /// 1999,
+ /// );
+ /// assert_eq!(
+ /// PrimitiveDateTime::MAX
+ /// .assume_utc()
+ /// .checked_to_offset(offset!(+1)),
+ /// None,
+ /// );
+ /// ```
+ pub const fn checked_to_offset(self, offset: UtcOffset) -> Option<Self> {
+ Some(Self(const_try_opt!(self.0.checked_to_offset(offset))))
+ }
+
// region: constructors
/// Create an `OffsetDateTime` from the provided Unix timestamp. Calling `.offset()` on the
/// resulting value is guaranteed to return UTC.
diff --git a/vendor/time/src/parsing/component.rs b/vendor/time/src/parsing/component.rs
index e7b852706..23035893e 100644
--- a/vendor/time/src/parsing/component.rs
+++ b/vendor/time/src/parsing/component.rs
@@ -2,6 +2,7 @@
use core::num::{NonZeroU16, NonZeroU8};
+use crate::convert::*;
use crate::format_description::modifier;
#[cfg(feature = "large-dates")]
use crate::parsing::combinator::n_to_m_digits_padded;
@@ -315,14 +316,12 @@ pub(crate) fn parse_unix_timestamp(
let ParsedItem(input, sign) = opt(sign)(input);
let ParsedItem(input, nano_timestamp) = match modifiers.precision {
modifier::UnixTimestampPrecision::Second => {
- n_to_m_digits::<1, 14, u128>(input)?.map(|val| val * 1_000_000_000)
- }
- modifier::UnixTimestampPrecision::Millisecond => {
- n_to_m_digits::<1, 17, u128>(input)?.map(|val| val * 1_000_000)
- }
- modifier::UnixTimestampPrecision::Microsecond => {
- n_to_m_digits::<1, 20, u128>(input)?.map(|val| val * 1_000)
+ n_to_m_digits::<1, 14, u128>(input)?.map(|val| val * Nanosecond.per(Second) as u128)
}
+ modifier::UnixTimestampPrecision::Millisecond => n_to_m_digits::<1, 17, u128>(input)?
+ .map(|val| val * Nanosecond.per(Millisecond) as u128),
+ modifier::UnixTimestampPrecision::Microsecond => n_to_m_digits::<1, 20, u128>(input)?
+ .map(|val| val * Nanosecond.per(Microsecond) as u128),
modifier::UnixTimestampPrecision::Nanosecond => n_to_m_digits::<1, 23, _>(input)?,
};
diff --git a/vendor/time/src/parsing/iso8601.rs b/vendor/time/src/parsing/iso8601.rs
index 21c89bab3..1afee4e31 100644
--- a/vendor/time/src/parsing/iso8601.rs
+++ b/vendor/time/src/parsing/iso8601.rs
@@ -1,5 +1,6 @@
//! Parse parts of an ISO 8601-formatted value.
+use crate::convert::*;
use crate::error;
use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
use crate::format_description::well_known::iso8601::EncodedConfig;
@@ -124,12 +125,16 @@ impl<const CONFIG: EncodedConfig> Iso8601<CONFIG> {
*parsed = parsed
.with_hour_24(hour)
.ok_or(InvalidComponent("hour"))?
- .with_minute((fractional_part * 60.0) as _)
+ .with_minute((fractional_part * Second.per(Minute) as f64) as _)
.ok_or(InvalidComponent("minute"))?
- .with_second((fractional_part * 3600.0 % 60.) as _)
+ .with_second(
+ (fractional_part * Second.per(Hour) as f64 % Minute.per(Hour) as f64)
+ as _,
+ )
.ok_or(InvalidComponent("second"))?
.with_subsecond(
- (fractional_part * 3_600. * 1_000_000_000. % 1_000_000_000.) as _,
+ (fractional_part * Nanosecond.per(Hour) as f64
+ % Nanosecond.per(Second) as f64) as _,
)
.ok_or(InvalidComponent("subsecond"))?;
return Ok(input);
@@ -157,10 +162,11 @@ impl<const CONFIG: EncodedConfig> Iso8601<CONFIG> {
*parsed = parsed
.with_minute(minute)
.ok_or(InvalidComponent("minute"))?
- .with_second((fractional_part * 60.) as _)
+ .with_second((fractional_part * Second.per(Minute) as f64) as _)
.ok_or(InvalidComponent("second"))?
.with_subsecond(
- (fractional_part * 60. * 1_000_000_000. % 1_000_000_000.) as _,
+ (fractional_part * Nanosecond.per(Minute) as f64
+ % Nanosecond.per(Second) as f64) as _,
)
.ok_or(InvalidComponent("subsecond"))?;
return Ok(input);
@@ -200,9 +206,11 @@ impl<const CONFIG: EncodedConfig> Iso8601<CONFIG> {
let (input, second, subsecond) = match float(input) {
Some(ParsedItem(input, (second, None))) => (input, second, 0),
- Some(ParsedItem(input, (second, Some(fractional_part)))) => {
- (input, second, round(fractional_part * 1_000_000_000.) as _)
- }
+ Some(ParsedItem(input, (second, Some(fractional_part)))) => (
+ input,
+ second,
+ round(fractional_part * Nanosecond.per(Second) as f64) as _,
+ ),
None if extended_kind.is_extended() => {
return Err(error::Parse::ParseFromDescription(InvalidComponent(
"second",
diff --git a/vendor/time/src/parsing/parsed.rs b/vendor/time/src/parsing/parsed.rs
index 26405cb11..04c74a720 100644
--- a/vendor/time/src/parsing/parsed.rs
+++ b/vendor/time/src/parsing/parsed.rs
@@ -423,6 +423,7 @@ impl Parsed {
}
/// Obtain the absolute value of the offset minute.
+ #[doc(hidden)]
#[deprecated(since = "0.3.8", note = "use `parsed.offset_minute_signed()` instead")]
pub const fn offset_minute(&self) -> Option<u8> {
Some(const_try_opt!(self.offset_minute_signed()).unsigned_abs())
@@ -447,6 +448,7 @@ impl Parsed {
}
/// Obtain the absolute value of the offset second.
+ #[doc(hidden)]
#[deprecated(since = "0.3.8", note = "use `parsed.offset_second_signed()` instead")]
pub const fn offset_second(&self) -> Option<u8> {
Some(const_try_opt!(self.offset_second_signed()).unsigned_abs())
@@ -523,6 +525,7 @@ impl Parsed {
}
/// Set the named component.
+ #[doc(hidden)]
#[deprecated(
since = "0.3.8",
note = "use `parsed.set_offset_minute_signed()` instead"
@@ -543,6 +546,7 @@ impl Parsed {
}
/// Set the named component.
+ #[doc(hidden)]
#[deprecated(
since = "0.3.8",
note = "use `parsed.set_offset_second_signed()` instead"
@@ -615,6 +619,7 @@ impl Parsed {
}
/// Set the named component and return `self`.
+ #[doc(hidden)]
#[deprecated(
since = "0.3.8",
note = "use `parsed.with_offset_minute_signed()` instead"
@@ -635,6 +640,7 @@ impl Parsed {
}
/// Set the named component and return `self`.
+ #[doc(hidden)]
#[deprecated(
since = "0.3.8",
note = "use `parsed.with_offset_second_signed()` instead"
diff --git a/vendor/time/src/quickcheck.rs b/vendor/time/src/quickcheck.rs
index 2304dc89e..4a788b517 100644
--- a/vendor/time/src/quickcheck.rs
+++ b/vendor/time/src/quickcheck.rs
@@ -38,6 +38,7 @@ use alloc::boxed::Box;
use quickcheck::{empty_shrinker, single_shrinker, Arbitrary, Gen};
+use crate::convert::*;
use crate::date_time::{DateTime, MaybeOffset};
use crate::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday};
@@ -99,10 +100,10 @@ impl Arbitrary for Duration {
impl Arbitrary for Time {
fn arbitrary(g: &mut Gen) -> Self {
Self::__from_hms_nanos_unchecked(
- arbitrary_between!(u8; g, 0, 23),
- arbitrary_between!(u8; g, 0, 59),
- arbitrary_between!(u8; g, 0, 59),
- arbitrary_between!(u32; g, 0, 999_999_999),
+ arbitrary_between!(u8; g, 0, Hour.per(Day) - 1),
+ arbitrary_between!(u8; g, 0, Minute.per(Hour) - 1),
+ arbitrary_between!(u8; g, 0, Second.per(Minute) - 1),
+ arbitrary_between!(u32; g, 0, Nanosecond.per(Second) - 1),
)
}
@@ -129,11 +130,12 @@ impl Arbitrary for PrimitiveDateTime {
impl Arbitrary for UtcOffset {
fn arbitrary(g: &mut Gen) -> Self {
- let seconds = arbitrary_between!(i32; g, -86_399, 86_399);
+ let seconds =
+ arbitrary_between!(i32; g, -(Second.per(Day) as i32 - 1), Second.per(Day) as i32 - 1);
Self::__from_hms_unchecked(
- (seconds / 3600) as _,
- ((seconds % 3600) / 60) as _,
- (seconds % 60) as _,
+ (seconds / Second.per(Hour) as i32) as _,
+ ((seconds % Second.per(Hour) as i32) / Minute.per(Hour) as i32) as _,
+ (seconds % Second.per(Minute) as i32) as _,
)
}
diff --git a/vendor/time/src/rand.rs b/vendor/time/src/rand.rs
index 8afefe507..e5181f9bd 100644
--- a/vendor/time/src/rand.rs
+++ b/vendor/time/src/rand.rs
@@ -3,15 +3,16 @@
use rand::distributions::{Distribution, Standard};
use rand::Rng;
+use crate::convert::*;
use crate::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday};
impl Distribution<Time> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Time {
Time::__from_hms_nanos_unchecked(
- rng.gen_range(0..24),
- rng.gen_range(0..60),
- rng.gen_range(0..60),
- rng.gen_range(0..1_000_000_000),
+ rng.gen_range(0..Hour.per(Day)),
+ rng.gen_range(0..Minute.per(Hour)),
+ rng.gen_range(0..Second.per(Minute)),
+ rng.gen_range(0..Nanosecond.per(Second)),
)
}
}
@@ -26,11 +27,11 @@ impl Distribution<Date> for Standard {
impl Distribution<UtcOffset> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UtcOffset {
- let seconds = rng.gen_range(-86399..=86399);
+ let seconds = rng.gen_range(-(Second.per(Day) as i32 - 1)..=(Second.per(Day) as i32 - 1));
UtcOffset::__from_hms_unchecked(
- (seconds / 3600) as _,
- ((seconds % 3600) / 60) as _,
- (seconds % 60) as _,
+ (seconds / Second.per(Hour) as i32) as _,
+ ((seconds % Second.per(Hour) as i32) / Minute.per(Hour) as i32) as _,
+ (seconds % Second.per(Minute) as i32) as _,
)
}
}
diff --git a/vendor/time/src/serde/mod.rs b/vendor/time/src/serde/mod.rs
index 248356e1a..844d7bdef 100644
--- a/vendor/time/src/serde/mod.rs
+++ b/vendor/time/src/serde/mod.rs
@@ -27,17 +27,31 @@ use core::marker::PhantomData;
#[cfg(feature = "serde-human-readable")]
use serde::ser::Error as _;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
-/// Generate a custom serializer and deserializer from the provided string.
+/// Generate a custom serializer and deserializer from a format string or an existing format.
///
/// The syntax accepted by this macro is the same as [`format_description::parse()`], which can
/// be found in [the book](https://time-rs.github.io/book/api/format-description.html).
///
/// # Usage
///
-/// Invoked as `serde::format_description!(mod_name, Date, "<format string>")`. This puts a
-/// module named `mod_name` in the current scope that can be used to format `Date` structs. A
-/// submodule (`mod_name::option`) is also generated for `Option<Date>`. Both modules are only
-/// visible in the current scope.
+/// Invoked as `serde::format_description!(mod_name, Date, FORMAT)` where `FORMAT` is either a
+/// `"<format string>"` or something that implements
+#[cfg_attr(
+ all(feature = "formatting", feature = "parsing"),
+ doc = "[`Formattable`](crate::formatting::Formattable) and \
+ [`Parsable`](crate::parsing::Parsable)."
+)]
+#[cfg_attr(
+ all(feature = "formatting", not(feature = "parsing")),
+ doc = "[`Formattable`](crate::formatting::Formattable)."
+)]
+#[cfg_attr(
+ all(not(feature = "formatting"), feature = "parsing"),
+ doc = "[`Parsable`](crate::parsing::Parsable)."
+)]
+/// This puts a module named `mod_name` in the current scope that can be used to format `Date`
+/// structs. A submodule (`mod_name::option`) is also generated for `Option<Date>`. Both
+/// modules are only visible in the current scope.
///
/// The returned `Option` will contain a deserialized value if present and `None` if the field
/// is present but the value is `null` (or the equivalent in other formats). To return `None`
@@ -45,6 +59,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
///
/// # Examples
///
+/// Using a format string:
+///
/// ```rust,no_run
/// # use time::OffsetDateTime;
#[cfg_attr(
@@ -63,6 +79,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
///
/// // Makes a module `mod my_format { ... }`.
/// serde::format_description!(my_format, OffsetDateTime, "hour=[hour], minute=[minute]");
+///
+/// # #[allow(dead_code)]
#[cfg_attr(
all(feature = "formatting", feature = "parsing"),
doc = "#[derive(Serialize, Deserialize)]"
@@ -75,13 +93,111 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
all(not(feature = "formatting"), feature = "parsing"),
doc = "#[derive(Deserialize)]"
)]
+/// struct SerializesWithCustom {
+/// #[serde(with = "my_format")]
+/// dt: OffsetDateTime,
+/// #[serde(with = "my_format::option")]
+/// maybe_dt: Option<OffsetDateTime>,
+/// }
+/// ```
+///
+/// Define the format separately to be used in multiple places:
+/// ```rust,no_run
+/// # use time::OffsetDateTime;
+#[cfg_attr(
+ all(feature = "formatting", feature = "parsing"),
+ doc = "use ::serde::{Serialize, Deserialize};"
+)]
+#[cfg_attr(
+ all(feature = "formatting", not(feature = "parsing")),
+ doc = "use ::serde::Serialize;"
+)]
+#[cfg_attr(
+ all(not(feature = "formatting"), feature = "parsing"),
+ doc = "use ::serde::Deserialize;"
+)]
+/// use time::serde;
+/// use time::format_description::FormatItem;
+///
+/// const DATE_TIME_FORMAT: &[FormatItem<'_>] = time::macros::format_description!(
+/// "hour=[hour], minute=[minute]"
+/// );
+///
+/// // Makes a module `mod my_format { ... }`.
+/// serde::format_description!(my_format, OffsetDateTime, DATE_TIME_FORMAT);
+///
/// # #[allow(dead_code)]
+#[cfg_attr(
+ all(feature = "formatting", feature = "parsing"),
+ doc = "#[derive(Serialize, Deserialize)]"
+)]
+#[cfg_attr(
+ all(feature = "formatting", not(feature = "parsing")),
+ doc = "#[derive(Serialize)]"
+)]
+#[cfg_attr(
+ all(not(feature = "formatting"), feature = "parsing"),
+ doc = "#[derive(Deserialize)]"
+)]
+/// struct SerializesWithCustom {
+/// #[serde(with = "my_format")]
+/// dt: OffsetDateTime,
+/// #[serde(with = "my_format::option")]
+/// maybe_dt: Option<OffsetDateTime>,
+/// }
+///
+/// fn main() {
+/// # #[allow(unused_variables)]
+/// let str_ts = OffsetDateTime::now_utc().format(DATE_TIME_FORMAT).unwrap();
+/// }
+/// ```
+///
+/// Customize the configuration of ISO 8601 formatting/parsing:
+/// ```rust,no_run
+/// # use time::OffsetDateTime;
+#[cfg_attr(
+ all(feature = "formatting", feature = "parsing"),
+ doc = "use ::serde::{Serialize, Deserialize};"
+)]
+#[cfg_attr(
+ all(feature = "formatting", not(feature = "parsing")),
+ doc = "use ::serde::Serialize;"
+)]
+#[cfg_attr(
+ all(not(feature = "formatting"), feature = "parsing"),
+ doc = "use ::serde::Deserialize;"
+)]
+/// use time::serde;
+/// use time::format_description::well_known::{iso8601, Iso8601};
+///
+/// const CONFIG: iso8601::EncodedConfig = iso8601::Config::DEFAULT
+/// .set_year_is_six_digits(false)
+/// .encode();
+/// const FORMAT: Iso8601<CONFIG> = Iso8601::<CONFIG>;
+///
+/// // Makes a module `mod my_format { ... }`.
+/// serde::format_description!(my_format, OffsetDateTime, FORMAT);
+///
+/// # #[allow(dead_code)]
+#[cfg_attr(
+ all(feature = "formatting", feature = "parsing"),
+ doc = "#[derive(Serialize, Deserialize)]"
+)]
+#[cfg_attr(
+ all(feature = "formatting", not(feature = "parsing")),
+ doc = "#[derive(Serialize)]"
+)]
+#[cfg_attr(
+ all(not(feature = "formatting"), feature = "parsing"),
+ doc = "#[derive(Deserialize)]"
+)]
/// struct SerializesWithCustom {
/// #[serde(with = "my_format")]
/// dt: OffsetDateTime,
/// #[serde(with = "my_format::option")]
/// maybe_dt: Option<OffsetDateTime>,
/// }
+/// # fn main() {}
/// ```
///
/// [`format_description::parse()`]: crate::format_description::parse()
@@ -108,9 +224,9 @@ impl Serialize for Date {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
#[cfg(feature = "serde-human-readable")]
if serializer.is_human_readable() {
- guard!(let Ok(s) = self.format(&DATE_FORMAT) else {
+ let Ok(s) = self.format(&DATE_FORMAT) else {
return Err(S::Error::custom("failed formatting `Date`"));
- });
+ };
return serializer.serialize_str(&s);
}
@@ -171,9 +287,9 @@ impl Serialize for OffsetDateTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
#[cfg(feature = "serde-human-readable")]
if serializer.is_human_readable() {
- guard!(let Ok(s) = self.format(&OFFSET_DATE_TIME_FORMAT) else {
+ let Ok(s) = self.format(&OFFSET_DATE_TIME_FORMAT) else {
return Err(S::Error::custom("failed formatting `OffsetDateTime`"));
- });
+ };
return serializer.serialize_str(&s);
}
@@ -216,9 +332,9 @@ impl Serialize for PrimitiveDateTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
#[cfg(feature = "serde-human-readable")]
if serializer.is_human_readable() {
- guard!(let Ok(s) = self.format(&PRIMITIVE_DATE_TIME_FORMAT) else {
+ let Ok(s) = self.format(&PRIMITIVE_DATE_TIME_FORMAT) else {
return Err(S::Error::custom("failed formatting `PrimitiveDateTime`"));
- });
+ };
return serializer.serialize_str(&s);
}
@@ -262,9 +378,9 @@ impl Serialize for Time {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
#[cfg(feature = "serde-human-readable")]
if serializer.is_human_readable() {
- guard!(let Ok(s) = self.format(&TIME_FORMAT) else {
+ let Ok(s) = self.format(&TIME_FORMAT) else {
return Err(S::Error::custom("failed formatting `Time`"));
- });
+ };
return serializer.serialize_str(&s);
}
@@ -298,9 +414,9 @@ impl Serialize for UtcOffset {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
#[cfg(feature = "serde-human-readable")]
if serializer.is_human_readable() {
- guard!(let Ok(s) = self.format(&UTC_OFFSET_FORMAT) else {
+ let Ok(s) = self.format(&UTC_OFFSET_FORMAT) else {
return Err(S::Error::custom("failed formatting `UtcOffset`"));
- });
+ };
return serializer.serialize_str(&s);
}
diff --git a/vendor/time/src/shim.rs b/vendor/time/src/shim.rs
deleted file mode 100644
index b9ac97a16..000000000
--- a/vendor/time/src/shim.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-//! Macro for simulating let-else on older compilers.
-//!
-//! This module and its macros will be removed once the MSRV is 1.65 (NET 2023-05-03).
-
-#![allow(unused_macros)]
-#![allow(clippy::missing_docs_in_private_items)]
-
-// The following code is copyright 2016 Alex Burka. Available under the MIT OR Apache-2.0 license.
-// Some adaptations have been made to the original code.
-
-pub(crate) enum LetElseBodyMustDiverge {}
-
-#[allow(clippy::missing_docs_in_private_items)]
-macro_rules! __guard_output {
- ((($($imms:ident)*) ($($muts:ident)*)),
- [($($pattern:tt)*) ($rhs:expr) ($diverge:expr)]) => {
- __guard_impl!(@as_stmt
- let ($($imms,)* $(mut $muts,)*) = {
- #[allow(unused_mut)]
- match $rhs {
- $($pattern)* => {
- ($($imms,)* $($muts,)*)
- },
- _ => {
- let _: $crate::shim::LetElseBodyMustDiverge = $diverge;
- },
- }
- }
- )
- };
-}
-
-macro_rules! __guard_impl {
- // 0. cast a series of token trees to a statement
- (@as_stmt $s:stmt) => { $s };
-
- // 1. output stage
- (@collect () -> $($rest:tt)*) => {
- __guard_output!($($rest)*)
- };
-
-
- // 2. identifier collection stage
- // The pattern is scanned destructively. Anything that looks like a capture (including
- // false positives, like un-namespaced/empty structs or enum variants) is copied into the
- // appropriate identifier list. Irrelevant symbols are discarded. The scanning descends
- // recursively into bracketed structures.
-
- // unwrap brackets and prepend their contents to the pattern remainder, in case there are captures inside
- (@collect (($($inside:tt)*) $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($inside)* $($tail)*) -> $idents, $thru)
- };
- (@collect ({$($inside:tt)*} $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($inside)* $($tail)*) -> $idents, $thru)
- };
- (@collect ([$($inside:tt)*] $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($inside)* $($tail)*) -> $idents, $thru)
- };
-
- // discard irrelevant symbols
- (@collect (, $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- (@collect (.. $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- (@collect (@ $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- (@collect (_ $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- (@collect (& $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
-
- // ignore generic parameters
- (@collect (:: <$($generic:tt),*> $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- // a path can't be a capture, and a path can't end with ::, so the ident after :: is never a capture
- (@collect (:: $pathend:ident $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
-
- // alternative patterns may be given with | as long as the same captures (including type) appear on each side
- // due to this property, if we see a | we've already parsed all the captures and can simply stop
- (@collect (| $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect () -> $idents, $thru) // discard the rest of the pattern, proceed to output stage
- };
-
- // throw away some identifiers that do not represent captures
-
- // an ident followed by a colon is the name of a structure member
- (@collect ($id:ident: $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- // paths do not represent captures
- (@collect ($pathcomp:ident :: $pathend:ident $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> $idents, $thru)
- };
- // an ident followed by parentheses is the name of a tuple-like struct or enum variant
- // (unwrap the parens to parse the contents)
- (@collect ($id:ident ($($inside:tt)*) $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($inside)* $($tail)*) -> $idents, $thru)
- };
- // an ident followed by curly braces is the name of a struct or struct-like enum variant
- // (unwrap the braces to parse the contents)
- (@collect ($id:ident {$($inside:tt)*} $($tail:tt)*) -> $idents:tt, $thru:tt) => {
- __guard_impl!(@collect ($($inside)* $($tail)*) -> $idents, $thru)
- };
-
- // actually identifier collection happens here!
-
- // capture by mutable reference!
- (@collect (ref mut $id:ident $($tail:tt)*) -> (($($imms:ident)*) $muts:tt), $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> (($($imms)* $id) $muts), $thru)
- };
- // capture by immutable reference!
- (@collect (ref $id:ident $($tail:tt)*) -> (($($imms:ident)*) $muts:tt), $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> (($($imms)* $id) $muts), $thru)
- };
- // capture by move into mutable binding!
- (@collect (mut $id:ident $($tail:tt)*) -> ($imms:tt ($($muts:ident)*)), $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> ($imms ($($muts)* $id)), $thru)
- };
- // capture by move into an immutable binding!
- (@collect ($id:ident $($tail:tt)*) -> (($($imms:ident)*) $muts:tt), $thru:tt) => {
- __guard_impl!(@collect ($($tail)*) -> (($($imms)* $id) $muts), $thru)
- };
-
- // 3. splitting (for new syntax)
-
- // done with pattern (and it's LPED=X)
- (@split (else { $($diverge:tt)* } = $($tail:tt)*) -> ($pat:tt)) => {
- __guard_impl!(@collect $pat -> (() ()), [$pat ($($tail)*) ({ $($diverge)* })])
- };
-
- // done with pattern (and it's LP=XED)
- (@split (= $($tail:tt)*) -> ($pat:tt)) => {
- __guard_impl!(@split expr ($($tail)*) -> ($pat ()))
- };
-
- // found a token in the pattern
- (@split ($head:tt $($tail:tt)*) -> (($($pat:tt)*))) => {
- __guard_impl!(@split ($($tail)*) -> (($($pat)* $head)))
- };
-
- // found an "else DIVERGE" in the expr
- (@split expr (else { $($tail:tt)* }) -> ($pat:tt $expr:tt)) => {
- __guard_impl!(@collect $pat -> (() ()), [$pat $expr ({ $($tail)* })])
- };
-
- // found an else in the expr with more stuff after it
- (@split expr (else { $($body:tt)* } $($tail:tt)*) -> ($pat:tt ($($expr:tt)*))) => {
- __guard_impl!(@split expr ($($tail)*) -> ($pat ($($expr)* else { $($body)* })))
- };
-
- // found another token in the expr
- (@split expr ($head:tt $($tail:tt)*) -> ($pat:tt ($($expr:tt)*))) => {
- __guard_impl!(@split expr ($($tail)*) -> ($pat ($($expr)* $head)))
- };
-
- // 4. entry points
-
- // new syntax
- (let $($tail:tt)*) => {
- __guard_impl!(@split ($($tail)*) -> (()))
- // | | |
- // | | ^ pattern
- // | ^ tail to be split into "PAT = EXPR else DIVERGE"
- // ^ first pass will do the parsing
- };
-}
-
-macro_rules! guard {
- ($($input:tt)*) => {
- __guard_impl!($($input)*)
- };
-}
diff --git a/vendor/time/src/sys/local_offset_at/wasm_js.rs b/vendor/time/src/sys/local_offset_at/wasm_js.rs
index fcea4b0f5..dfbe063a2 100644
--- a/vendor/time/src/sys/local_offset_at/wasm_js.rs
+++ b/vendor/time/src/sys/local_offset_at/wasm_js.rs
@@ -1,3 +1,4 @@
+use crate::convert::*;
use crate::{OffsetDateTime, UtcOffset};
/// Obtain the system's UTC offset.
@@ -6,7 +7,7 @@ pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> {
// The number of minutes returned by getTimezoneOffset() is positive if the local time zone
// is behind UTC, and negative if the local time zone is ahead of UTC. For example,
// for UTC+10, -600 will be returned.
- let timezone_offset = (js_date.get_timezone_offset() as i32) * -60;
+ let timezone_offset = (js_date.get_timezone_offset() as i32) * -(Minute.per(Hour) as i32);
UtcOffset::from_whole_seconds(timezone_offset).ok()
}
diff --git a/vendor/time/src/sys/local_offset_at/windows.rs b/vendor/time/src/sys/local_offset_at/windows.rs
index 69b422314..a4d5882d6 100644
--- a/vendor/time/src/sys/local_offset_at/windows.rs
+++ b/vendor/time/src/sys/local_offset_at/windows.rs
@@ -2,6 +2,7 @@
use core::mem::MaybeUninit;
+use crate::convert::*;
use crate::{OffsetDateTime, UtcOffset};
// ffi: WINAPI FILETIME struct
@@ -56,7 +57,7 @@ fn systemtime_to_filetime(systime: &SystemTime) -> Option<FileTime> {
/// Convert a `FILETIME` to an `i64`, representing a number of seconds.
fn filetime_to_secs(filetime: &FileTime) -> i64 {
/// FILETIME represents 100-nanosecond intervals
- const FT_TO_SECS: i64 = 10_000_000;
+ const FT_TO_SECS: i64 = Nanosecond.per(Second) as i64 / 100;
((filetime.dwHighDateTime as i64) << 32 | filetime.dwLowDateTime as i64) / FT_TO_SECS
}
diff --git a/vendor/time/src/time.rs b/vendor/time/src/time.rs
index 32fa97790..87b465bb9 100644
--- a/vendor/time/src/time.rs
+++ b/vendor/time/src/time.rs
@@ -6,6 +6,7 @@ use core::time::Duration as StdDuration;
#[cfg(feature = "formatting")]
use std::io;
+use crate::convert::*;
#[cfg(feature = "formatting")]
use crate::formatting::Formattable;
#[cfg(feature = "parsing")]
@@ -71,10 +72,10 @@ impl Time {
second: u8,
nanosecond: u32,
) -> Self {
- debug_assert!(hour < 24);
- debug_assert!(minute < 60);
- debug_assert!(second < 60);
- debug_assert!(nanosecond < 1_000_000_000);
+ debug_assert!(hour < Hour.per(Day));
+ debug_assert!(minute < Minute.per(Hour));
+ debug_assert!(second < Second.per(Minute));
+ debug_assert!(nanosecond < Nanosecond.per(Second));
Self {
hour,
@@ -99,9 +100,9 @@ impl Time {
/// assert!(Time::from_hms(0, 0, 60).is_err()); // 60 isn't a valid second.
/// ```
pub const fn from_hms(hour: u8, minute: u8, second: u8) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(hour in 0 => 23);
- ensure_value_in_range!(minute in 0 => 59);
- ensure_value_in_range!(second in 0 => 59);
+ ensure_value_in_range!(hour in 0 => Hour.per(Day) - 1);
+ ensure_value_in_range!(minute in 0 => Minute.per(Hour) - 1);
+ ensure_value_in_range!(second in 0 => Second.per(Minute) - 1);
Ok(Self::__from_hms_nanos_unchecked(hour, minute, second, 0))
}
@@ -125,15 +126,15 @@ impl Time {
second: u8,
millisecond: u16,
) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(hour in 0 => 23);
- ensure_value_in_range!(minute in 0 => 59);
- ensure_value_in_range!(second in 0 => 59);
- ensure_value_in_range!(millisecond in 0 => 999);
+ ensure_value_in_range!(hour in 0 => Hour.per(Day) - 1);
+ ensure_value_in_range!(minute in 0 => Minute.per(Hour) - 1);
+ ensure_value_in_range!(second in 0 => Second.per(Minute) - 1);
+ ensure_value_in_range!(millisecond in 0 => Millisecond.per(Second) - 1);
Ok(Self::__from_hms_nanos_unchecked(
hour,
minute,
second,
- millisecond as u32 * 1_000_000,
+ millisecond as u32 * Nanosecond.per(Millisecond),
))
}
@@ -157,15 +158,15 @@ impl Time {
second: u8,
microsecond: u32,
) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(hour in 0 => 23);
- ensure_value_in_range!(minute in 0 => 59);
- ensure_value_in_range!(second in 0 => 59);
- ensure_value_in_range!(microsecond in 0 => 999_999);
+ ensure_value_in_range!(hour in 0 => Hour.per(Day) - 1);
+ ensure_value_in_range!(minute in 0 => Minute.per(Hour) - 1);
+ ensure_value_in_range!(second in 0 => Second.per(Minute) - 1);
+ ensure_value_in_range!(microsecond in 0 => Microsecond.per(Second) - 1);
Ok(Self::__from_hms_nanos_unchecked(
hour,
minute,
second,
- microsecond * 1_000,
+ microsecond * Nanosecond.per(Microsecond) as u32,
))
}
@@ -189,10 +190,10 @@ impl Time {
second: u8,
nanosecond: u32,
) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(hour in 0 => 23);
- ensure_value_in_range!(minute in 0 => 59);
- ensure_value_in_range!(second in 0 => 59);
- ensure_value_in_range!(nanosecond in 0 => 999_999_999);
+ ensure_value_in_range!(hour in 0 => Hour.per(Day) - 1);
+ ensure_value_in_range!(minute in 0 => Minute.per(Hour) - 1);
+ ensure_value_in_range!(second in 0 => Second.per(Minute) - 1);
+ ensure_value_in_range!(nanosecond in 0 => Nanosecond.per(Second) - 1);
Ok(Self::__from_hms_nanos_unchecked(
hour, minute, second, nanosecond,
))
@@ -223,7 +224,7 @@ impl Time {
self.hour,
self.minute,
self.second,
- (self.nanosecond / 1_000_000) as u16,
+ (self.nanosecond / Nanosecond.per(Millisecond)) as u16,
)
}
@@ -238,7 +239,12 @@ impl Time {
/// );
/// ```
pub const fn as_hms_micro(self) -> (u8, u8, u8, u32) {
- (self.hour, self.minute, self.second, self.nanosecond / 1_000)
+ (
+ self.hour,
+ self.minute,
+ self.second,
+ self.nanosecond / Nanosecond.per(Microsecond) as u32,
+ )
}
/// Get the clock hour, minute, second, and nanosecond.
@@ -304,7 +310,7 @@ impl Time {
/// assert_eq!(time!(23:59:59.999).millisecond(), 999);
/// ```
pub const fn millisecond(self) -> u16 {
- (self.nanosecond / 1_000_000) as _
+ (self.nanosecond / Nanosecond.per(Millisecond)) as _
}
/// Get the microseconds within the second.
@@ -317,7 +323,7 @@ impl Time {
/// assert_eq!(time!(23:59:59.999_999).microsecond(), 999_999);
/// ```
pub const fn microsecond(self) -> u32 {
- self.nanosecond / 1_000
+ self.nanosecond / Nanosecond.per(Microsecond) as u32
}
/// Get the nanoseconds within the second.
@@ -339,19 +345,21 @@ impl Time {
/// the date is different.
pub(crate) const fn adjusting_add(self, duration: Duration) -> (DateAdjustment, Self) {
let mut nanoseconds = self.nanosecond as i32 + duration.subsec_nanoseconds();
- let mut seconds = self.second as i8 + (duration.whole_seconds() % 60) as i8;
- let mut minutes = self.minute as i8 + (duration.whole_minutes() % 60) as i8;
- let mut hours = self.hour as i8 + (duration.whole_hours() % 24) as i8;
+ let mut seconds =
+ self.second as i8 + (duration.whole_seconds() % Second.per(Minute) as i64) as i8;
+ let mut minutes =
+ self.minute as i8 + (duration.whole_minutes() % Minute.per(Hour) as i64) as i8;
+ let mut hours = self.hour as i8 + (duration.whole_hours() % Hour.per(Day) as i64) as i8;
let mut date_adjustment = DateAdjustment::None;
- cascade!(nanoseconds in 0..1_000_000_000 => seconds);
- cascade!(seconds in 0..60 => minutes);
- cascade!(minutes in 0..60 => hours);
- if hours >= 24 {
- hours -= 24;
+ cascade!(nanoseconds in 0..Nanosecond.per(Second) as _ => seconds);
+ cascade!(seconds in 0..Second.per(Minute) as _ => minutes);
+ cascade!(minutes in 0..Minute.per(Hour) as _ => hours);
+ if hours >= Hour.per(Day) as _ {
+ hours -= Hour.per(Day) as i8;
date_adjustment = DateAdjustment::Next;
} else if hours < 0 {
- hours += 24;
+ hours += Hour.per(Day) as i8;
date_adjustment = DateAdjustment::Previous;
}
@@ -370,19 +378,21 @@ impl Time {
/// whether the date is different.
pub(crate) const fn adjusting_sub(self, duration: Duration) -> (DateAdjustment, Self) {
let mut nanoseconds = self.nanosecond as i32 - duration.subsec_nanoseconds();
- let mut seconds = self.second as i8 - (duration.whole_seconds() % 60) as i8;
- let mut minutes = self.minute as i8 - (duration.whole_minutes() % 60) as i8;
- let mut hours = self.hour as i8 - (duration.whole_hours() % 24) as i8;
+ let mut seconds =
+ self.second as i8 - (duration.whole_seconds() % Second.per(Minute) as i64) as i8;
+ let mut minutes =
+ self.minute as i8 - (duration.whole_minutes() % Minute.per(Hour) as i64) as i8;
+ let mut hours = self.hour as i8 - (duration.whole_hours() % Hour.per(Day) as i64) as i8;
let mut date_adjustment = DateAdjustment::None;
- cascade!(nanoseconds in 0..1_000_000_000 => seconds);
- cascade!(seconds in 0..60 => minutes);
- cascade!(minutes in 0..60 => hours);
- if hours >= 24 {
- hours -= 24;
+ cascade!(nanoseconds in 0..Nanosecond.per(Second) as _ => seconds);
+ cascade!(seconds in 0..Second.per(Minute) as _ => minutes);
+ cascade!(minutes in 0..Minute.per(Hour) as _ => hours);
+ if hours >= Hour.per(Day) as _ {
+ hours -= Hour.per(Day) as i8;
date_adjustment = DateAdjustment::Next;
} else if hours < 0 {
- hours += 24;
+ hours += Hour.per(Day) as i8;
date_adjustment = DateAdjustment::Previous;
}
@@ -401,16 +411,18 @@ impl Time {
/// returning whether the date is the previous date as the first element of the tuple.
pub(crate) const fn adjusting_add_std(self, duration: StdDuration) -> (bool, Self) {
let mut nanosecond = self.nanosecond + duration.subsec_nanos();
- let mut second = self.second + (duration.as_secs() % 60) as u8;
- let mut minute = self.minute + ((duration.as_secs() / 60) % 60) as u8;
- let mut hour = self.hour + ((duration.as_secs() / 3_600) % 24) as u8;
+ let mut second = self.second + (duration.as_secs() % Second.per(Minute) as u64) as u8;
+ let mut minute = self.minute
+ + ((duration.as_secs() / Second.per(Minute) as u64) % Minute.per(Hour) as u64) as u8;
+ let mut hour = self.hour
+ + ((duration.as_secs() / Second.per(Hour) as u64) % Hour.per(Day) as u64) as u8;
let mut is_next_day = false;
- cascade!(nanosecond in 0..1_000_000_000 => second);
- cascade!(second in 0..60 => minute);
- cascade!(minute in 0..60 => hour);
- if hour >= 24 {
- hour -= 24;
+ cascade!(nanosecond in 0..Nanosecond.per(Second) => second);
+ cascade!(second in 0..Second.per(Minute) => minute);
+ cascade!(minute in 0..Minute.per(Hour) => hour);
+ if hour >= Hour.per(Day) {
+ hour -= Hour.per(Day);
is_next_day = true;
}
@@ -424,16 +436,18 @@ impl Time {
/// returning whether the date is the previous date as the first element of the tuple.
pub(crate) const fn adjusting_sub_std(self, duration: StdDuration) -> (bool, Self) {
let mut nanosecond = self.nanosecond as i32 - duration.subsec_nanos() as i32;
- let mut second = self.second as i8 - (duration.as_secs() % 60) as i8;
- let mut minute = self.minute as i8 - ((duration.as_secs() / 60) % 60) as i8;
- let mut hour = self.hour as i8 - ((duration.as_secs() / 3_600) % 24) as i8;
+ let mut second = self.second as i8 - (duration.as_secs() % Second.per(Minute) as u64) as i8;
+ let mut minute = self.minute as i8
+ - ((duration.as_secs() / Second.per(Minute) as u64) % Minute.per(Hour) as u64) as i8;
+ let mut hour = self.hour as i8
+ - ((duration.as_secs() / Second.per(Hour) as u64) % Hour.per(Day) as u64) as i8;
let mut is_previous_day = false;
- cascade!(nanosecond in 0..1_000_000_000 => second);
- cascade!(second in 0..60 => minute);
- cascade!(minute in 0..60 => hour);
+ cascade!(nanosecond in 0..Nanosecond.per(Second) as _ => second);
+ cascade!(second in 0..Second.per(Minute) as _ => minute);
+ cascade!(minute in 0..Minute.per(Hour) as _ => hour);
if hour < 0 {
- hour += 24;
+ hour += Hour.per(Day) as i8;
is_previous_day = true;
}
@@ -457,7 +471,7 @@ impl Time {
/// ```
#[must_use = "This method does not mutate the original `Time`."]
pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(hour in 0 => 23);
+ ensure_value_in_range!(hour in 0 => Hour.per(Day) - 1);
Ok(Self::__from_hms_nanos_unchecked(
hour,
self.minute,
@@ -478,7 +492,7 @@ impl Time {
/// ```
#[must_use = "This method does not mutate the original `Time`."]
pub const fn replace_minute(self, minute: u8) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(minute in 0 => 59);
+ ensure_value_in_range!(minute in 0 => Minute.per(Hour) - 1);
Ok(Self::__from_hms_nanos_unchecked(
self.hour,
minute,
@@ -499,7 +513,7 @@ impl Time {
/// ```
#[must_use = "This method does not mutate the original `Time`."]
pub const fn replace_second(self, second: u8) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(second in 0 => 59);
+ ensure_value_in_range!(second in 0 => Second.per(Minute) - 1);
Ok(Self::__from_hms_nanos_unchecked(
self.hour,
self.minute,
@@ -523,12 +537,12 @@ impl Time {
self,
millisecond: u16,
) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(millisecond in 0 => 999);
+ ensure_value_in_range!(millisecond in 0 => Millisecond.per(Second) - 1);
Ok(Self::__from_hms_nanos_unchecked(
self.hour,
self.minute,
self.second,
- millisecond as u32 * 1_000_000,
+ millisecond as u32 * Nanosecond.per(Millisecond),
))
}
@@ -547,12 +561,12 @@ impl Time {
self,
microsecond: u32,
) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(microsecond in 0 => 999_999);
+ ensure_value_in_range!(microsecond in 0 => Microsecond.per(Second) - 1);
Ok(Self::__from_hms_nanos_unchecked(
self.hour,
self.minute,
self.second,
- microsecond * 1000,
+ microsecond * Nanosecond.per(Microsecond) as u32,
))
}
@@ -568,7 +582,7 @@ impl Time {
/// ```
#[must_use = "This method does not mutate the original `Time`."]
pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(nanosecond in 0 => 999_999_999);
+ ensure_value_in_range!(nanosecond in 0 => Nanosecond.per(Second) - 1);
Ok(Self::__from_hms_nanos_unchecked(
self.hour,
self.minute,
@@ -745,12 +759,14 @@ impl Sub for Time {
let second_diff = (self.second as i8) - (rhs.second as i8);
let nanosecond_diff = (self.nanosecond as i32) - (rhs.nanosecond as i32);
- let seconds = hour_diff as i64 * 3_600 + minute_diff as i64 * 60 + second_diff as i64;
+ let seconds = hour_diff as i64 * Second.per(Hour) as i64
+ + minute_diff as i64 * Second.per(Minute) as i64
+ + second_diff as i64;
let (seconds, nanoseconds) = if seconds > 0 && nanosecond_diff < 0 {
- (seconds - 1, nanosecond_diff + 1_000_000_000)
+ (seconds - 1, nanosecond_diff + Nanosecond.per(Second) as i32)
} else if seconds < 0 && nanosecond_diff > 0 {
- (seconds + 1, nanosecond_diff - 1_000_000_000)
+ (seconds + 1, nanosecond_diff - Nanosecond.per(Second) as i32)
} else {
(seconds, nanosecond_diff)
};
diff --git a/vendor/time/src/utc_offset.rs b/vendor/time/src/utc_offset.rs
index d69f0c1e3..af7fd1bf7 100644
--- a/vendor/time/src/utc_offset.rs
+++ b/vendor/time/src/utc_offset.rs
@@ -5,6 +5,7 @@ use core::ops::Neg;
#[cfg(feature = "formatting")]
use std::io;
+use crate::convert::*;
use crate::error;
#[cfg(feature = "formatting")]
use crate::formatting::Formattable;
@@ -59,8 +60,8 @@ impl UtcOffset {
debug_assert!(seconds >= 0);
}
debug_assert!(hours.unsigned_abs() < 24);
- debug_assert!(minutes.unsigned_abs() < 60);
- debug_assert!(seconds.unsigned_abs() < 60);
+ debug_assert!(minutes.unsigned_abs() < Minute.per(Hour));
+ debug_assert!(seconds.unsigned_abs() < Second.per(Minute));
Self {
hours,
@@ -87,8 +88,12 @@ impl UtcOffset {
mut seconds: i8,
) -> Result<Self, error::ComponentRange> {
ensure_value_in_range!(hours in -23 => 23);
- ensure_value_in_range!(minutes in -59 => 59);
- ensure_value_in_range!(seconds in -59 => 59);
+ ensure_value_in_range!(
+ minutes in -(Minute.per(Hour) as i8 - 1) => Minute.per(Hour) as i8 - 1
+ );
+ ensure_value_in_range!(
+ seconds in -(Second.per(Minute) as i8 - 1) => Second.per(Minute) as i8 - 1
+ );
if (hours > 0 && minutes < 0) || (hours < 0 && minutes > 0) {
minutes *= -1;
@@ -112,12 +117,14 @@ impl UtcOffset {
/// # Ok::<_, time::Error>(())
/// ```
pub const fn from_whole_seconds(seconds: i32) -> Result<Self, error::ComponentRange> {
- ensure_value_in_range!(seconds in -86_399 => 86_399);
+ ensure_value_in_range!(
+ seconds in -24 * Second.per(Hour) as i32 - 1 => 24 * Second.per(Hour) as i32 - 1
+ );
Ok(Self::__from_hms_unchecked(
- (seconds / 3_600) as _,
- ((seconds / 60) % 60) as _,
- (seconds % 60) as _,
+ (seconds / Second.per(Hour) as i32) as _,
+ ((seconds % Second.per(Hour) as i32) / Minute.per(Hour) as i32) as _,
+ (seconds % Second.per(Minute) as i32) as _,
))
}
// endregion constructors
@@ -156,7 +163,7 @@ impl UtcOffset {
/// assert_eq!(offset!(-1:02:03).whole_minutes(), -62);
/// ```
pub const fn whole_minutes(self) -> i16 {
- self.hours as i16 * 60 + self.minutes as i16
+ self.hours as i16 * Minute.per(Hour) as i16 + self.minutes as i16
}
/// Obtain the number of minutes past the hour the offset is from UTC. A positive value
@@ -182,7 +189,9 @@ impl UtcOffset {
// This may be useful for anyone manually implementing arithmetic, as it
// would let them construct a `Duration` directly.
pub const fn whole_seconds(self) -> i32 {
- self.hours as i32 * 3_600 + self.minutes as i32 * 60 + self.seconds as i32
+ self.hours as i32 * Second.per(Hour) as i32
+ + self.minutes as i32 * Second.per(Minute) as i32
+ + self.seconds as i32
}
/// Obtain the number of seconds past the minute the offset is from UTC. A positive value
diff --git a/vendor/time/src/util.rs b/vendor/time/src/util.rs
index b41068384..857f5f20b 100644
--- a/vendor/time/src/util.rs
+++ b/vendor/time/src/util.rs
@@ -44,30 +44,40 @@ pub mod local_offset {
/// Obtaining the local UTC offset is required to be sound. Undefined behavior will never
/// occur. This is the default.
Sound,
- /// Obtaining the local UTC offset is allowed to invoke undefined behavior. Setting this
- /// value is strongly discouraged. To do so, you must comply with the safety requirements
+ /// Obtaining the local UTC offset is allowed to invoke undefined behavior. **Setting this
+ /// value is strongly discouraged.** To do so, you must comply with the safety requirements
/// of [`time::local_offset::set_soundness`](set_soundness).
Unsound,
}
- /// Set whether obtaining the local UTC offset is allowed to invoke undefined behavior.
+ /// Set whether obtaining the local UTC offset is allowed to invoke undefined behavior. **Use of
+ /// this function is heavily discouraged.**
///
/// # Safety
///
/// If this method is called with [`Soundness::Sound`], the call is always sound. If this method
/// is called with [`Soundness::Unsound`], the following conditions apply.
///
- /// - If the operating system is not Unix-like, the call is sound.
+ /// - If the operating system provides a thread-safe environment, the call is sound.
/// - If the process is single-threaded, the call is sound.
/// - If the process is multi-threaded, no other thread may mutate the environment in any way at
/// the same time a call to a method that obtains the local UTC offset. This includes adding,
/// removing, or modifying an environment variable.
///
+ /// The first two conditions are automatically checked by `time`, such that you do not need to
+ /// declare your code unsound. Currently, the only known operating systems that does _not_
+ /// provide a thread-safe environment are some Unix-like OS's. All other operating systems
+ /// should succeed when attempting to obtain the local UTC offset.
+ ///
/// Note that you must not only verify this safety condition for your code, but for **all** code
/// that will be included in the final binary. Notably, it applies to both direct and transitive
- /// dependencies and to both Rust and non-Rust code. For this reason it is not possible to
+ /// dependencies and to both Rust and non-Rust code. **For this reason it is not possible to
/// soundly pass [`Soundness::Unsound`] to this method if you are writing a library that may
- /// used by others.
+ /// used by others.**
+ ///
+ /// If using this method is absolutely necessary, it is recommended to keep the time between
+ /// setting the soundness to [`Soundness::Unsound`] and setting it back to [`Soundness::Sound`]
+ /// as short as possible.
///
/// The following methods currently obtain the local UTC offset:
///
diff --git a/vendor/time/src/weekday.rs b/vendor/time/src/weekday.rs
index f499c30ee..d530a2e4d 100644
--- a/vendor/time/src/weekday.rs
+++ b/vendor/time/src/weekday.rs
@@ -66,6 +66,28 @@ impl Weekday {
}
}
+ /// Get n-th next day.
+ ///
+ /// ```rust
+ /// # use time::Weekday;
+ /// assert_eq!(Weekday::Monday.nth_next(1), Weekday::Tuesday);
+ /// assert_eq!(Weekday::Sunday.nth_next(10), Weekday::Wednesday);
+ /// ```
+ pub const fn nth_next(self, n: u8) -> Self {
+ match (self.number_days_from_monday() + n % 7) % 7 {
+ 0 => Monday,
+ 1 => Tuesday,
+ 2 => Wednesday,
+ 3 => Thursday,
+ 4 => Friday,
+ 5 => Saturday,
+ val => {
+ debug_assert!(val == 6);
+ Sunday
+ }
+ }
+ }
+
/// Get the one-indexed number of days from Monday.
///
/// ```rust