Skip to content

Commit 95ebedd

Browse files
committed
Fix validation bug
1 parent 32d197f commit 95ebedd

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/components/duration.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use crate::{
44
components::{timezone::TzProvider, PlainDateTime, PlainTime},
55
iso::{IsoDateTime, IsoTime},
66
options::{
7-
ArithmeticOverflow, RelativeTo, ResolvedRoundingOptions, RoundingIncrement,
8-
RoundingOptions, TemporalUnit, ToStringRoundingOptions,
7+
ArithmeticOverflow, RelativeTo, ResolvedRoundingOptions, RoundingIncrement, RoundingOptions, TemporalUnit, ToStringRoundingOptions
98
},
109
parsers::{FormattableDuration, Precision},
1110
primitive::FiniteF64,
@@ -144,13 +143,18 @@ impl Duration {
144143
duration_record.normalized_time_duration(),
145144
largest_unit,
146145
)?;
147-
let date = DateDuration::new(
146+
Self::new(
148147
duration_record.date().years,
149148
duration_record.date().months,
150149
duration_record.date().weeks,
151150
duration_record.date().days.checked_add(&overflow_day)?,
152-
)?;
153-
Ok(Self::new_unchecked(date, time))
151+
time.hours,
152+
time.minutes,
153+
time.seconds,
154+
time.milliseconds,
155+
time.microseconds,
156+
time.nanoseconds,
157+
)
154158
}
155159

156160
/// Returns the a `Vec` of the fields values.
@@ -744,6 +748,8 @@ impl Duration {
744748

745749
// TODO: Update, optimize, and fix the below. is_valid_duration should probably be generic over a T.
746750

751+
const TWO_POWER_FIFTY_THREE: i128 = 9_007_199_254_740_992;
752+
747753
// NOTE: Can FiniteF64 optimize the duration_validation
748754
/// Utility function to check whether the `Duration` fields are valid.
749755
#[inline]
@@ -809,21 +815,13 @@ pub(crate) fn is_valid_duration(
809815
// in C++ with an implementation of core::remquo() with sufficient bits in the quotient.
810816
// String manipulation will also give an exact result, since the multiplication is by a power of 10.
811817
// Seconds part
812-
let normalized_seconds = days.0.mul_add(
813-
86_400.0,
814-
hours.0.mul_add(3600.0, minutes.0.mul_add(60.0, seconds.0)),
815-
);
818+
let normalized_seconds = (days.0 as i128 * 86_400) + (hours.0 as i128) * 3600 + minutes.0 as i128 * 60 + seconds.0 as i128;
816819
// Subseconds part
817-
let normalized_subseconds_parts = milliseconds.0.mul_add(
818-
10e-3,
819-
microseconds
820-
.0
821-
.mul_add(10e-6, nanoseconds.0.mul_add(10e-9, 0.0)),
822-
);
820+
let normalized_subseconds_parts = (milliseconds.0 as i128 / 1_000) + (microseconds.0 as i128 / 1_000_000) + (nanoseconds.0 as i128 / 1_000_000_000);
823821

824822
let normalized_seconds = normalized_seconds + normalized_subseconds_parts;
825823
// 8. If abs(normalizedSeconds) ≥ 2**53, return false.
826-
if normalized_seconds.abs() >= 2e53 {
824+
if normalized_seconds.abs() >= TWO_POWER_FIFTY_THREE {
827825
return false;
828826
}
829827

src/primitive.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ use num_traits::{AsPrimitive, FromPrimitive, PrimInt};
66
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
77
pub struct FiniteF64(pub(crate) f64);
88

9+
impl core::fmt::Display for FiniteF64 {
10+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11+
f.write_fmt(format_args!("{}", self.0))
12+
}
13+
}
14+
915
impl FiniteF64 {
1016
#[inline]
1117
pub fn as_inner(&self) -> f64 {

0 commit comments

Comments
 (0)