Skip to content

Commit b942063

Browse files
committed
Compare datetimes with signed integers
1 parent dcdfbf6 commit b942063

File tree

5 files changed

+31
-12
lines changed

5 files changed

+31
-12
lines changed

tests/offset_date_time.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,10 @@ fn ord() {
602602
let t1 = datetime!(2019-01-01 0:00 UTC);
603603
let t2 = datetime!(2019-01-01 0:00:00.000_000_001 UTC);
604604
assert!(t2 > t1);
605+
606+
let t1 = datetime!(-0001-01-01 0:00 UTC);
607+
let t2 = datetime!(0001-01-01 0:00 UTC);
608+
assert!(t2 > t1);
605609
}
606610

607611
#[test]

tests/primitive_date_time.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,10 @@ fn ord() {
596596
datetime!(2019-01-01 0:00:00.000_000_001).partial_cmp(&datetime!(2019-01-01 0:00)),
597597
Some(Greater)
598598
);
599+
assert_eq!(
600+
datetime!(-0001-01-01 0:00).partial_cmp(&datetime!(0001-01-01 0:00)),
601+
Some(Less)
602+
);
599603
}
600604

601605
#[test]

time/src/date.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,15 @@ pub struct Date {
5858
}
5959

6060
impl Date {
61-
/// Provide a representation of `Date` as a `u32`. This value can be used for equality, hashing,
61+
/// Provide a representation of `Date` as a `i32`. This value can be used for equality, hashing,
6262
/// and ordering.
63+
///
64+
/// **Note**: This value is explicitly signed, so do not cast this to or treat this as an
65+
/// unsigned integer. Doing so will lead to incorrect results for values with differing
66+
/// signs.
6367
#[inline]
64-
pub(crate) const fn as_u32(self) -> u32 {
65-
self.value.get() as u32
68+
pub(crate) const fn as_i32(self) -> i32 {
69+
self.value.get()
6670
}
6771

6872
/// The Unix epoch: 1970-01-01

time/src/offset_date_time.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ impl Hash for OffsetDateTime {
6868
}
6969
}
7070

71+
/// **Note**: This value is explicitly signed, so do not cast this to or treat this as an
72+
/// unsigned integer. Doing so will lead to incorrect results for values with differing
73+
/// signs.
7174
#[inline]
72-
const fn raw_to_bits((year, ordinal, time): (i32, u16, Time)) -> u128 {
73-
((year as u128) << 74) | ((ordinal as u128) << 64) | (time.as_u64() as u128)
75+
const fn raw_to_bits((year, ordinal, time): (i32, u16, Time)) -> i128 {
76+
((year as i128) << 74) | ((ordinal as i128) << 64) | (time.as_u64() as i128)
7477
}
7578

7679
impl OffsetDateTime {

time/src/primitive_date_time.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ pub struct PrimitiveDateTime {
4444
impl Hash for PrimitiveDateTime {
4545
#[inline]
4646
fn hash<H: Hasher>(&self, state: &mut H) {
47-
self.as_u128().hash(state);
47+
self.as_i128().hash(state);
4848
}
4949
}
5050

5151
impl PartialEq for PrimitiveDateTime {
5252
#[inline]
5353
fn eq(&self, other: &Self) -> bool {
54-
self.as_u128().eq(&other.as_u128())
54+
self.as_i128().eq(&other.as_i128())
5555
}
5656
}
5757

@@ -65,17 +65,21 @@ impl PartialOrd for PrimitiveDateTime {
6565
impl Ord for PrimitiveDateTime {
6666
#[inline]
6767
fn cmp(&self, other: &Self) -> Ordering {
68-
self.as_u128().cmp(&other.as_u128())
68+
self.as_i128().cmp(&other.as_i128())
6969
}
7070
}
7171

7272
impl PrimitiveDateTime {
73-
/// Provide a representation of `PrimitiveDateTime` as a `u128`. This value can be used for
73+
/// Provide a representation of `PrimitiveDateTime` as a `i128`. This value can be used for
7474
/// equality, hashing, and ordering.
75+
///
76+
/// **Note**: This value is explicitly signed, so do not cast this to or treat this as an
77+
/// unsigned integer. Doing so will lead to incorrect results for values with differing
78+
/// signs.
7579
#[inline]
76-
const fn as_u128(self) -> u128 {
77-
let time = self.time.as_u64() as u128;
78-
let date = self.date.as_u32() as u128;
80+
const fn as_i128(self) -> i128 {
81+
let time = self.time.as_u64() as i128;
82+
let date = self.date.as_i32() as i128;
7983
(date << 64) | time
8084
}
8185

0 commit comments

Comments
 (0)