Skip to content

Commit

Permalink
The date_add_month kernels should keep the time portion unchanged
Browse files Browse the repository at this point in the history
  • Loading branch information
jhorstmann committed Nov 3, 2023
1 parent 69e1936 commit 04e7e42
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [0.3.1](https://github.com/jhorstmann/packedtime-rs/tree/0.3.1) (2023-11-03)

- The `date_add_month` kernels should leave the time part unchanged

## [0.3.0](https://github.com/jhorstmann/packedtime-rs/tree/0.3.0) (2023-11-01)

- Support calculating the difference between dates in units of years or months
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "packedtime-rs"
description = "Utilities for efficiently storing, parsing, formatting and truncating timestamps"
authors = ["Jörn Horstmann <[email protected]>"]
version = "0.3.0"
version = "0.3.1"
edition = "2021"

repository = "https://github.com/jhorstmann/packedtime-rs"
Expand Down
57 changes: 34 additions & 23 deletions src/kernels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,46 +77,57 @@ pub fn date_trunc_quarter_timestamp_millis_float(ts: f64) -> f64 {
}

#[inline]
pub fn date_add_month_timestamp_millis(ts: i64, months: i32) -> i64 {
pub fn date_part_year_timestamp_millis(ts: i64) -> i32 {
let epoch_days = EpochDays::from_timestamp_millis(ts);
let new_epoch_days = epoch_days.add_months(months);
new_epoch_days.to_timestamp_millis()
epoch_days.extract_year()
}

#[inline]
pub fn date_add_month_timestamp_millis_float(ts: f64, months: i32) -> f64 {
let epoch_days = EpochDays::from_timestamp_millis_float(ts);
let new_epoch_days = epoch_days.add_months(months);
new_epoch_days.to_timestamp_millis_float()
pub fn date_part_month_timestamp_millis(ts: i64) -> i32 {
let epoch_days = EpochDays::from_timestamp_millis(ts);
epoch_days.extract_month()
}

#[inline]
pub fn date_part_year_timestamp_millis(ts: i64) -> i32 {
let epoch_days = EpochDays::from_timestamp_millis(ts);
epoch_days.extract_year()
fn timestamp_to_epoch_days_and_remainder(ts: i64) -> (EpochDays, i64) {
let (days, millis) = (ts.div_euclid(MILLIS_PER_DAY), ts.rem_euclid(MILLIS_PER_DAY));
(EpochDays::new(days as i32), millis)
}

#[inline]
pub fn date_part_month_timestamp_millis(ts: i64) -> i32 {
let epoch_days = EpochDays::from_timestamp_millis(ts);
epoch_days.extract_month()
fn timestamp_to_epoch_days_and_remainder_float(ts: f64) -> (EpochDays, f64) {
let days = (ts * (1.0 / MILLIS_PER_DAY as f64)).floor();
let millis = ts - days * (MILLIS_PER_DAY as f64);
(EpochDays::new(unsafe { days.to_int_unchecked() }), millis)
}

#[inline]
pub fn date_add_month_timestamp_millis(ts: i64, months: i32) -> i64 {
let (epoch_days, millis) = timestamp_to_epoch_days_and_remainder(ts);
let new_epoch_days = epoch_days.add_months(months);
new_epoch_days.to_timestamp_millis() + millis
}

#[inline]
pub fn date_add_month_timestamp_millis_float(ts: f64, months: i32) -> f64 {
let (epoch_days, millis) = timestamp_to_epoch_days_and_remainder_float(ts);
let new_epoch_days = epoch_days.add_months(months);
new_epoch_days.to_timestamp_millis_float() + millis
}

#[inline]
fn timestamp_to_year_month_millis_of_month(ts: i64) -> (i32, i32, i64) {
let (days, millis) = (ts.div_euclid(MILLIS_PER_DAY), ts.rem_euclid(MILLIS_PER_DAY));
let (year, month, d0) = EpochDays::new(days as i32).to_ymd();
let millis_of_month = (d0 as i64)*MILLIS_PER_DAY + millis;
let (ed, millis) = timestamp_to_epoch_days_and_remainder(ts);
let (year, month, day) = ed.to_ymd();
let millis_of_month = (day as i64)*MILLIS_PER_DAY + millis;
(year, month, millis_of_month)
}

#[inline]
fn timestamp_to_year_month_millis_of_month_float(ts: f64) -> (i32, i32, f64) {
let days = (ts * (1.0 / MILLIS_PER_DAY as f64)).floor();
let epoch_days = EpochDays::new(unsafe { days.to_int_unchecked() });
let millis = ts - days * (MILLIS_PER_DAY as f64);
let (year, month, d0) = epoch_days.to_ymd();
let millis_of_month = (d0 as f64)*(MILLIS_PER_DAY as f64) + millis;
let (ed, millis) = timestamp_to_epoch_days_and_remainder_float(ts);
let (year, month, day) = ed.to_ymd();
let millis_of_month = (day as f64)*(MILLIS_PER_DAY as f64) + millis;
(year, month, millis_of_month)
}

Expand Down Expand Up @@ -265,11 +276,11 @@ mod tests {
fn test_date_add_months_timestamp_millis() {
assert_eq!(
date_add_month_timestamp_millis(1661102969_000, 1),
1663718400_000
1663781369000
);
assert_eq!(
date_add_month_timestamp_millis(1661102969_000, 12),
1692576000_000
1692638969000
);
}

Expand Down

0 comments on commit 04e7e42

Please sign in to comment.