From 261b28db2236afc1dcc25318ec7f3bc1650a5068 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 6 Feb 2024 09:58:43 +0100 Subject: [PATCH 01/75] ci: use codecov token --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd37b4d..281a34e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,7 +125,7 @@ jobs: uses: codecov/codecov-action@v4 # if: steps.vars.outputs.HAS_CODECOV_TOKEN with: - # token: ${{ secrets.CODECOV_TOKEN }} + token: ${{ secrets.CODECOV_TOKEN }} file: ${{ steps.coverage.outputs.report }} ## flags: IntegrationTests, UnitTests, ${{ steps.vars.outputs.CODECOV_FLAGS }} flags: ${{ steps.vars.outputs.CODECOV_FLAGS }} From 0dddb4b72664b070b94bbea9186df737e9c2fd03 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 05:16:50 +0000 Subject: [PATCH 02/75] fix(deps): update rust crate regex to 1.10.4 --- fuzz/Cargo.lock | 4 ++-- fuzz/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index bb78b87..024e5c2 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 7e5c2f2..ab7bfb4 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -9,7 +9,7 @@ cargo-fuzz = true [dependencies] rand = "0.8.5" libfuzzer-sys = "0.4" -regex = "1.10.3" +regex = "1.10.4" chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] } [dependencies.parse_datetime] From 85957480b390391537bc7b97296358e62cfae795 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 24 Mar 2024 16:52:29 +0100 Subject: [PATCH 03/75] clippy: fix warnings from zero_prefixed_literal --- src/lib.rs | 2 +- src/parse_time_only_str.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 56bd14a..b98d608 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -401,7 +401,7 @@ mod tests { #[test] fn test_weekday() { // add some constant hours and minutes and seconds to check its reset - let date = Local.with_ymd_and_hms(2023, 02, 28, 10, 12, 3).unwrap(); + let date = Local.with_ymd_and_hms(2023, 2, 28, 10, 12, 3).unwrap(); // 2023-2-28 is tuesday assert_eq!( diff --git a/src/parse_time_only_str.rs b/src/parse_time_only_str.rs index 69ad488..e909216 100644 --- a/src/parse_time_only_str.rs +++ b/src/parse_time_only_str.rs @@ -52,7 +52,7 @@ mod tests { use std::env; fn get_test_date() -> DateTime { - Local.with_ymd_and_hms(2024, 03, 03, 0, 0, 0).unwrap() + Local.with_ymd_and_hms(2024, 3, 3, 0, 0, 0).unwrap() } #[test] From 5b81981a8a6ac50402dff71cc8f4f9a566bd3dc6 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 24 Mar 2024 16:54:43 +0100 Subject: [PATCH 04/75] clippy: fix warning from bool_assert_comparison --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b98d608..7921961 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -382,7 +382,7 @@ mod tests { ]; for relative_time in relative_times { - assert_eq!(parse_datetime(relative_time).is_ok(), true); + assert!(parse_datetime(relative_time).is_ok()); } } } From 113100e669d76177c032080f0d2b4ad6c911d028 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 10:08:38 +0000 Subject: [PATCH 05/75] fix(deps): update rust crate libfuzzer-sys to 0.4.7 --- fuzz/Cargo.lock | 4 ++-- fuzz/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 024e5c2..f5e3e7b 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -148,9 +148,9 @@ checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libfuzzer-sys" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb09950ae85a0a94b27676cccf37da5ff13f27076aa1adbc6545dd0d0e1bd4e" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" dependencies = [ "arbitrary", "cc", diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index ab7bfb4..d8d56b8 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -8,7 +8,7 @@ cargo-fuzz = true [dependencies] rand = "0.8.5" -libfuzzer-sys = "0.4" +libfuzzer-sys = "0.4.7" regex = "1.10.4" chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] } From 04494f6ddb30b4418465f02bf3177f17ab2d2829 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 11:32:23 +0000 Subject: [PATCH 06/75] fix(deps): update rust crate regex to 1.10.4 --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb10320..93e3909 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.0" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -190,9 +190,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.0" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d58da636bd923eae52b7e9120271cbefb16f399069ee566ca5ebf9c30e32238" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "syn" diff --git a/Cargo.toml b/Cargo.toml index a9649b5..eacf8df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,6 @@ repository = "https://github.com/uutils/parse_datetime" readme = "README.md" [dependencies] -regex = "1.10" +regex = "1.10.4" chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] } nom = "7.1.3" From be45c2734d9f4ac04d651155e388158d5d61000a Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 3 May 2024 15:33:11 +0200 Subject: [PATCH 07/75] ci: use clippy --all-targets --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 281a34e..cca0070 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: rustup component add clippy - - run: cargo clippy -- -D warnings + - run: cargo clippy --all-targets -- -D warnings coverage: name: Code Coverage From fc148543949d7920719d44a46e61784996d0de0d Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 3 May 2024 15:35:24 +0200 Subject: [PATCH 08/75] clippy: fix warnings from zero_prefixed_literal --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index dac5bfd..b0e7a00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -476,7 +476,7 @@ mod tests { #[test] fn test_time_only() { env::set_var("TZ", "UTC"); - let test_date = Local.with_ymd_and_hms(2024, 03, 03, 0, 0, 0).unwrap(); + let test_date = Local.with_ymd_and_hms(2024, 3, 3, 0, 0, 0).unwrap(); let parsed_time = parse_datetime_at_date(test_date, "9:04:30 PM +0530") .unwrap() .timestamp(); From 1bb93d7fe936aca546f63ad99401eba11a451fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Sat, 18 May 2024 11:11:05 +0200 Subject: [PATCH 09/75] Fix single digit date parsing --- src/lib.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b0e7a00..4d634f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -204,10 +204,10 @@ pub fn parse_datetime_at_date + Clone>( } } - let ts = s.as_ref().to_owned() + "0000"; + let ts = s.as_ref().to_owned() + " 0000"; // Parse date only formats - assume midnight local timezone for fmt in [format::ISO_8601, format::ISO_8601_NO_SEP] { - let f = fmt.to_owned() + "%H%M"; + let f = fmt.to_owned() + " %H%M"; if let Ok(parsed) = NaiveDateTime::parse_from_str(&ts, &f) { if let Ok(dt) = naive_dt_to_fixed_offset(date, parsed) { return Ok(dt); @@ -327,6 +327,23 @@ mod tests { } } + #[cfg(test)] + mod formats { + use crate::parse_datetime; + use chrono::{DateTime, Local, TimeZone}; + + #[test] + fn single_digit_month_day() { + let x = Local.with_ymd_and_hms(1987, 5, 7, 0, 0, 0).unwrap(); + let expected = DateTime::fixed_offset(&x); + + assert_eq!(Ok(expected), parse_datetime("1987-05-07")); + assert_eq!(Ok(expected), parse_datetime("1987-5-07")); + assert_eq!(Ok(expected), parse_datetime("1987-05-7")); + assert_eq!(Ok(expected), parse_datetime("1987-5-7")); + } + } + #[cfg(test)] mod offsets { use chrono::Local; From a75107c69d5e62588c6f55490f50efa77aae55b7 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 20 May 2024 18:40:34 +0200 Subject: [PATCH 10/75] Bump version to 0.6.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93e3909..2acde75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,7 +151,7 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "parse_datetime" -version = "0.5.0" +version = "0.6.0" dependencies = [ "chrono", "nom", diff --git a/Cargo.toml b/Cargo.toml index eacf8df..f7148f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parse_datetime" description = "parsing human-readable time strings and converting them to a DateTime" -version = "0.5.0" +version = "0.6.0" edition = "2021" license = "MIT" repository = "https://github.com/uutils/parse_datetime" From e1aa18d2631aa9c83cb69663fe26f93c6d3d0922 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 21 May 2024 07:22:43 +0200 Subject: [PATCH 11/75] readme: bump version to 0.6.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f3b031..e52af2b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -parse_datetime = "0.5.0" +parse_datetime = "0.6.0" ``` Then, import the crate and use the `parse_datetime_at_date` function: From db8c1d364fc7def123fbbbda2fc2ab47e996c84e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 9 Jun 2024 13:29:07 +0000 Subject: [PATCH 12/75] fix(deps): update rust crate regex to v1.10.5 --- Cargo.lock | 4 ++-- fuzz/Cargo.lock | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2acde75..7946238 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index f5e3e7b..7158c39 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -202,7 +202,7 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "parse_datetime" -version = "0.5.0" +version = "0.6.0" dependencies = [ "chrono", "nom", @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", From f7f789913a0a762ce1d95330ca5c6dbe76a21952 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:04:11 +0000 Subject: [PATCH 13/75] fix(deps): update rust crate regex to v1.10.6 --- Cargo.lock | 4 ++-- fuzz/Cargo.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7946238..4b1ce71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 7158c39..79eef27 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", From d4f67bbde0ab1c0191c289b50350afd09fe622ec Mon Sep 17 00:00:00 2001 From: ysthakur <45539777+ysthakur@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:51:10 -0400 Subject: [PATCH 14/75] Don't use Durations for calculating relative times --- src/parse_relative_time.rs | 308 ++++++++++++++++++++++--------------- 1 file changed, 185 insertions(+), 123 deletions(-) diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index 7bc0840..62f3d1c 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -1,7 +1,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. use crate::ParseDateTimeError; -use chrono::{Duration, Local, NaiveDate, Utc}; +use chrono::{DateTime, Days, Duration, Months, Utc}; use regex::Regex; /// Parses a relative time string and returns a `Duration` representing the /// relative time. @@ -40,7 +40,9 @@ use regex::Regex; /// /// ``` pub fn parse_relative_time(s: &str) -> Result { - parse_relative_time_at_date(Utc::now().date_naive(), s) + let now = Utc::now(); + let parsed = parse_relative_time_at_date(now, s)?; + Ok(parsed - now) } /// Parses a duration string and returns a `Duration` instance, with the duration @@ -56,10 +58,10 @@ pub fn parse_relative_time(s: &str) -> Result { /// This function will return `Err(ParseDateTimeError::InvalidInput)` if the input string /// cannot be parsed as a relative time. /// ``` -pub fn parse_relative_time_at_date( - date: NaiveDate, +fn parse_relative_time_at_date( + mut datetime: DateTime, s: &str, -) -> Result { +) -> Result, ParseDateTimeError> { let time_pattern: Regex = Regex::new( r"(?x) (?:(?P[-+]?\d*)\s*)? @@ -69,7 +71,6 @@ pub fn parse_relative_time_at_date( (\s*(?Pago)?)?", )?; - let mut total_duration = Duration::seconds(0); let mut is_ago = s.contains(" ago"); let mut captures_processed = 0; let mut total_length = 0; @@ -104,26 +105,28 @@ pub fn parse_relative_time_at_date( is_ago = true; } - let duration = match unit { - "years" | "year" => Duration::days(value * 365), - "months" | "month" => Duration::days(value * 30), - "fortnights" | "fortnight" => Duration::weeks(value * 2), - "weeks" | "week" => Duration::weeks(value), - "days" | "day" => Duration::days(value), - "hours" | "hour" | "h" => Duration::hours(value), - "minutes" | "minute" | "mins" | "min" | "m" => Duration::minutes(value), - "seconds" | "second" | "secs" | "sec" | "s" => Duration::seconds(value), - "yesterday" => Duration::days(-1), - "tomorrow" => Duration::days(1), - "now" | "today" => Duration::zero(), + let new_datetime = match unit { + "years" | "year" => add_months(datetime, value * 12, is_ago), + "months" | "month" => add_months(datetime, value, is_ago), + "fortnights" | "fortnight" => add_days(datetime, value * 14, is_ago), + "weeks" | "week" => add_days(datetime, value * 7, is_ago), + "days" | "day" => add_days(datetime, value, is_ago), + "hours" | "hour" | "h" => add_duration(datetime, Duration::hours(value), is_ago), + "minutes" | "minute" | "mins" | "min" | "m" => { + add_duration(datetime, Duration::minutes(value), is_ago) + } + "seconds" | "second" | "secs" | "sec" | "s" => { + add_duration(datetime, Duration::seconds(value), is_ago) + } + "yesterday" => add_days(datetime, 1, true), + "tomorrow" => add_days(datetime, 1, false), + "now" | "today" => Some(datetime), _ => return Err(ParseDateTimeError::InvalidInput), }; - let neg_duration = -duration; - total_duration = - match total_duration.checked_add(if is_ago { &neg_duration } else { &duration }) { - Some(duration) => duration, - None => return Err(ParseDateTimeError::InvalidInput), - }; + datetime = match new_datetime { + Some(dt) => dt, + None => return Err(ParseDateTimeError::InvalidInput), + }; // Calculate the total length of the matched substring if let Some(m) = capture.get(0) { @@ -139,61 +142,102 @@ pub fn parse_relative_time_at_date( if captures_processed == 0 { Err(ParseDateTimeError::InvalidInput) } else { - let time_now = Local::now().date_naive(); - let date_duration = date - time_now; + Ok(datetime) + } +} + +fn add_months(datetime: DateTime, months: i64, mut is_ago: bool) -> Option> { + let months = if months < 0 { + is_ago = !is_ago; + u32::try_from(-months).ok()? + } else { + u32::try_from(months).ok()? + }; + if is_ago { + datetime.checked_sub_months(Months::new(months)) + } else { + datetime.checked_add_months(Months::new(months)) + } +} - Ok(total_duration + date_duration) +fn add_days(datetime: DateTime, days: i64, mut is_ago: bool) -> Option> { + let days = if days < 0 { + is_ago = !is_ago; + u64::try_from(-days).ok()? + } else { + u64::try_from(days).ok()? + }; + if is_ago { + datetime.checked_sub_days(Days::new(days)) + } else { + datetime.checked_add_days(Days::new(days)) } } +fn add_duration( + datetime: DateTime, + duration: Duration, + is_ago: bool, +) -> Option> { + let duration = if is_ago { -duration } else { duration }; + datetime.checked_add_signed(duration) +} + #[cfg(test)] mod tests { - use super::ParseDateTimeError; use super::{parse_relative_time, parse_relative_time_at_date}; - use chrono::{Duration, Local, NaiveDate, Utc}; + use chrono::{Days, Duration, Months, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc}; #[test] fn test_years() { + let now = Utc::now(); assert_eq!( - parse_relative_time("1 year").unwrap(), - Duration::seconds(31_536_000) + now + parse_relative_time("1 year").unwrap(), + now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!( - parse_relative_time("-2 years").unwrap(), - Duration::seconds(-63_072_000) + now + parse_relative_time("-2 years").unwrap(), + now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - parse_relative_time("2 years ago").unwrap(), - Duration::seconds(-63_072_000) + now + parse_relative_time("2 years ago").unwrap(), + now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - parse_relative_time("year").unwrap(), - Duration::seconds(31_536_000) + now + parse_relative_time("year").unwrap(), + now.checked_add_months(Months::new(12)).unwrap() ); } #[test] fn test_months() { + let now = Utc::now(); assert_eq!( - parse_relative_time("1 month").unwrap(), - Duration::seconds(2_592_000) + now + parse_relative_time("1 month").unwrap(), + now.checked_add_months(Months::new(1)).unwrap() ); assert_eq!( - parse_relative_time("1 month and 2 weeks").unwrap(), - Duration::seconds(3_801_600) + now + parse_relative_time("1 month and 2 weeks").unwrap(), + now.checked_add_months(Months::new(1)) + .unwrap() + .checked_add_days(Days::new(14)) + .unwrap() ); assert_eq!( - parse_relative_time("1 month and 2 weeks ago").unwrap(), - Duration::seconds(-3_801_600) + now + parse_relative_time("1 month and 2 weeks ago").unwrap(), + now.checked_sub_months(Months::new(1)) + .unwrap() + .checked_sub_days(Days::new(14)) + .unwrap() ); assert_eq!( - parse_relative_time("2 months").unwrap(), - Duration::seconds(5_184_000) + now + parse_relative_time("2 months").unwrap(), + now.checked_add_months(Months::new(2)).unwrap() ); assert_eq!( - parse_relative_time("month").unwrap(), - Duration::seconds(2_592_000) + now + parse_relative_time("month").unwrap(), + now.checked_add_months(Months::new(1)).unwrap() ); } @@ -323,6 +367,7 @@ mod tests { #[test] fn test_no_spaces() { + let now = Utc::now(); assert_eq!(parse_relative_time("-1hour").unwrap(), Duration::hours(-1)); assert_eq!(parse_relative_time("+3days").unwrap(), Duration::days(3)); assert_eq!(parse_relative_time("2weeks").unwrap(), Duration::weeks(2)); @@ -335,12 +380,12 @@ mod tests { Duration::seconds(-1_213_200) ); assert_eq!( - parse_relative_time("+4months").unwrap(), - Duration::days(4 * 30) + now + parse_relative_time("+4months").unwrap(), + now.checked_add_months(Months::new(4)).unwrap() ); assert_eq!( - parse_relative_time("-2years").unwrap(), - Duration::days(-2 * 365) + now + parse_relative_time("-2years").unwrap(), + now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( parse_relative_time("15minutes").unwrap(), @@ -374,131 +419,139 @@ mod tests { #[test] fn test_parse_relative_time_at_date() { - let date = NaiveDate::from_ymd_opt(2014, 9, 5).unwrap(); - let now = Local::now().date_naive(); - let days_diff = (date - now).num_days(); + let datetime = Utc.from_utc_datetime(&NaiveDateTime::new( + NaiveDate::from_ymd_opt(2014, 9, 5).unwrap(), + NaiveTime::from_hms_opt(0, 2, 3).unwrap(), + )); + let now = Utc::now(); + let diff = datetime - now; assert_eq!( - parse_relative_time_at_date(date, "1 day").unwrap(), - Duration::days(days_diff + 1) + parse_relative_time_at_date(datetime, "1 day").unwrap(), + now + diff + Duration::days(1) ); assert_eq!( - parse_relative_time_at_date(date, "2 hours").unwrap(), - Duration::days(days_diff) + Duration::hours(2) + parse_relative_time_at_date(datetime, "2 hours").unwrap(), + now + diff + Duration::hours(2) ); } - #[test] - fn test_invalid_input_at_date() { - let date = NaiveDate::from_ymd_opt(2014, 9, 5).unwrap(); - assert!(matches!( - parse_relative_time_at_date(date, "invalid"), - Err(ParseDateTimeError::InvalidInput) - )); - } - #[test] fn test_direction() { + let now = Utc::now(); assert_eq!( parse_relative_time("last hour").unwrap(), Duration::seconds(-3600) ); assert_eq!( - parse_relative_time("next year").unwrap(), - Duration::days(365) + now + parse_relative_time("next year").unwrap(), + now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!(parse_relative_time("next week").unwrap(), Duration::days(7)); assert_eq!( - parse_relative_time("last month").unwrap(), - Duration::days(-30) + now + parse_relative_time("last month").unwrap(), + now.checked_sub_months(Months::new(1)).unwrap() ); } #[test] fn test_duration_parsing() { + let now = Utc::now(); assert_eq!( - parse_relative_time("1 year").unwrap(), - Duration::seconds(31_536_000) + now + parse_relative_time("1 year").unwrap(), + now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!( - parse_relative_time("-2 years").unwrap(), - Duration::seconds(-63_072_000) + now + parse_relative_time("-2 years").unwrap(), + now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - parse_relative_time("2 years ago").unwrap(), - Duration::seconds(-63_072_000) + now + parse_relative_time("2 years ago").unwrap(), + now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - parse_relative_time("year").unwrap(), - Duration::seconds(31_536_000) + now + parse_relative_time("year").unwrap(), + now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!( - parse_relative_time("1 month").unwrap(), - Duration::seconds(2_592_000) + now + parse_relative_time("1 month").unwrap(), + now.checked_add_months(Months::new(1)).unwrap() ); assert_eq!( - parse_relative_time("1 month and 2 weeks").unwrap(), - Duration::seconds(3_801_600) + now + parse_relative_time("1 month and 2 weeks").unwrap(), + now.checked_add_months(Months::new(1)) + .unwrap() + .checked_add_days(Days::new(14)) + .unwrap() ); assert_eq!( - parse_relative_time("1 month, 2 weeks").unwrap(), - Duration::seconds(3_801_600) + now + parse_relative_time("1 month, 2 weeks").unwrap(), + now.checked_add_months(Months::new(1)) + .unwrap() + .checked_add_days(Days::new(14)) + .unwrap() ); assert_eq!( - parse_relative_time("1 months 2 weeks").unwrap(), - Duration::seconds(3_801_600) + now + parse_relative_time("1 months 2 weeks").unwrap(), + now.checked_add_months(Months::new(1)) + .unwrap() + .checked_add_days(Days::new(14)) + .unwrap() ); assert_eq!( - parse_relative_time("1 month and 2 weeks ago").unwrap(), - Duration::seconds(-3_801_600) + now + parse_relative_time("1 month and 2 weeks ago").unwrap(), + now.checked_sub_months(Months::new(1)) + .unwrap() + .checked_sub_days(Days::new(14)) + .unwrap() ); assert_eq!( - parse_relative_time("2 months").unwrap(), - Duration::seconds(5_184_000) + now + parse_relative_time("2 months").unwrap(), + now.checked_add_months(Months::new(2)).unwrap() ); assert_eq!( - parse_relative_time("month").unwrap(), - Duration::seconds(2_592_000) + now + parse_relative_time("month").unwrap(), + now.checked_add_months(Months::new(1)).unwrap() ); assert_eq!( - parse_relative_time("1 fortnight").unwrap(), - Duration::seconds(1_209_600) + now + parse_relative_time("1 fortnight").unwrap(), + now.checked_add_days(Days::new(14)).unwrap() ); assert_eq!( - parse_relative_time("3 fortnights").unwrap(), - Duration::seconds(3_628_800) + now + parse_relative_time("3 fortnights").unwrap(), + now.checked_add_days(Days::new(3 * 14)).unwrap() ); assert_eq!( - parse_relative_time("fortnight").unwrap(), - Duration::seconds(1_209_600) + now + parse_relative_time("fortnight").unwrap(), + now.checked_add_days(Days::new(14)).unwrap() ); assert_eq!( - parse_relative_time("1 week").unwrap(), - Duration::seconds(604_800) + now + parse_relative_time("1 week").unwrap(), + now.checked_add_days(Days::new(7)).unwrap() ); assert_eq!( - parse_relative_time("1 week 3 days").unwrap(), - Duration::seconds(864_000) + now + parse_relative_time("1 week 3 days").unwrap(), + now.checked_add_days(Days::new(7 + 3)).unwrap() ); assert_eq!( - parse_relative_time("1 week 3 days ago").unwrap(), - Duration::seconds(-864_000) + now + parse_relative_time("1 week 3 days ago").unwrap(), + now.checked_sub_days(Days::new(7 + 3)).unwrap() ); assert_eq!( - parse_relative_time("-2 weeks").unwrap(), - Duration::seconds(-1_209_600) + now + parse_relative_time("-2 weeks").unwrap(), + now.checked_sub_days(Days::new(14)).unwrap() ); assert_eq!( - parse_relative_time("2 weeks ago").unwrap(), - Duration::seconds(-1_209_600) + now + parse_relative_time("2 weeks ago").unwrap(), + now.checked_sub_days(Days::new(14)).unwrap() ); assert_eq!( - parse_relative_time("week").unwrap(), - Duration::seconds(604_800) + now + parse_relative_time("week").unwrap(), + now.checked_add_days(Days::new(7)).unwrap() ); assert_eq!( @@ -572,12 +625,22 @@ mod tests { assert_eq!(parse_relative_time("today").unwrap(), Duration::seconds(0)); assert_eq!( - parse_relative_time("1 year 2 months 4 weeks 3 days and 2 seconds").unwrap(), - Duration::seconds(39_398_402) + now + parse_relative_time("1 year 2 months 4 weeks 3 days and 2 seconds").unwrap(), + now.checked_add_months(Months::new(12 + 2)) + .unwrap() + .checked_add_days(Days::new(4 * 7 + 3)) + .unwrap() + .checked_add_signed(Duration::seconds(2)) + .unwrap() ); assert_eq!( - parse_relative_time("1 year 2 months 4 weeks 3 days and 2 seconds ago").unwrap(), - Duration::seconds(-39_398_402) + now + parse_relative_time("1 year 2 months 4 weeks 3 days and 2 seconds ago").unwrap(), + now.checked_sub_months(Months::new(12 + 2)) + .unwrap() + .checked_sub_days(Days::new(4 * 7 + 3)) + .unwrap() + .checked_sub_signed(Duration::seconds(2)) + .unwrap() ); } @@ -601,22 +664,21 @@ mod tests { #[test] fn test_parse_relative_time_at_date_day() { - let today = Utc::now().date_naive(); - let yesterday = today - Duration::days(1); + let now = Utc::now(); + let now_yesterday = now - Duration::days(1); assert_eq!( - parse_relative_time_at_date(yesterday, "2 days").unwrap(), - Duration::days(1) + parse_relative_time_at_date(now_yesterday, "2 days").unwrap(), + now + Duration::days(1) ); } #[test] fn test_invalid_input_at_date_relative() { - let today = Utc::now().date_naive(); - let result = parse_relative_time_at_date(today, "foobar"); - println!("{result:?}"); + let now = Utc::now(); + let result = parse_relative_time_at_date(now, "foobar"); assert_eq!(result, Err(ParseDateTimeError::InvalidInput)); - let result = parse_relative_time_at_date(today, "invalid 1r"); + let result = parse_relative_time_at_date(now, "invalid 1r"); assert_eq!(result, Err(ParseDateTimeError::InvalidInput)); } } From d75338a51b4059fdab2e84e289f928e5e6396c5e Mon Sep 17 00:00:00 2001 From: ysthakur <45539777+ysthakur@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:02:08 -0400 Subject: [PATCH 15/75] Make tests for months without 30 days and leap years --- src/parse_relative_time.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index 62f3d1c..96b9c34 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -672,6 +672,32 @@ mod tests { ); } + #[test] + fn test_parse_relative_time_at_date_month() { + // Use January because it has 31 days rather than 30 + let now = Utc.from_utc_datetime(&NaiveDateTime::new( + NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), + NaiveTime::from_hms_opt(0, 0, 0).unwrap(), + )); + assert_eq!( + parse_relative_time_at_date(now, "1 month").unwrap(), + now.checked_add_months(Months::new(1)).unwrap() + ); + } + + #[test] + fn test_parse_relative_time_at_date_year() { + // Use 2024 because it's a leap year and has 366 days rather than 365 + let now = Utc.from_utc_datetime(&NaiveDateTime::new( + NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), + NaiveTime::from_hms_opt(0, 0, 0).unwrap(), + )); + assert_eq!( + parse_relative_time_at_date(now, "1 year").unwrap(), + now.checked_add_months(Months::new(12)).unwrap() + ); + } + #[test] fn test_invalid_input_at_date_relative() { let now = Utc::now(); From ced645a4f46884b10dc6fd517362b8bb53bfe2a5 Mon Sep 17 00:00:00 2001 From: ysthakur <45539777+ysthakur@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:46:49 -0400 Subject: [PATCH 16/75] Make helpers timezone-generic --- src/parse_relative_time.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index 96b9c34..091adcf 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -1,7 +1,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. use crate::ParseDateTimeError; -use chrono::{DateTime, Days, Duration, Months, Utc}; +use chrono::{DateTime, Days, Duration, Months, TimeZone, Utc}; use regex::Regex; /// Parses a relative time string and returns a `Duration` representing the /// relative time. @@ -58,10 +58,10 @@ pub fn parse_relative_time(s: &str) -> Result { /// This function will return `Err(ParseDateTimeError::InvalidInput)` if the input string /// cannot be parsed as a relative time. /// ``` -fn parse_relative_time_at_date( - mut datetime: DateTime, +fn parse_relative_time_at_date( + mut datetime: DateTime, s: &str, -) -> Result, ParseDateTimeError> { +) -> Result, ParseDateTimeError> { let time_pattern: Regex = Regex::new( r"(?x) (?:(?P[-+]?\d*)\s*)? @@ -146,7 +146,11 @@ fn parse_relative_time_at_date( } } -fn add_months(datetime: DateTime, months: i64, mut is_ago: bool) -> Option> { +fn add_months( + datetime: DateTime, + months: i64, + mut is_ago: bool, +) -> Option> { let months = if months < 0 { is_ago = !is_ago; u32::try_from(-months).ok()? @@ -160,7 +164,11 @@ fn add_months(datetime: DateTime, months: i64, mut is_ago: bool) -> Option< } } -fn add_days(datetime: DateTime, days: i64, mut is_ago: bool) -> Option> { +fn add_days( + datetime: DateTime, + days: i64, + mut is_ago: bool, +) -> Option> { let days = if days < 0 { is_ago = !is_ago; u64::try_from(-days).ok()? @@ -174,11 +182,11 @@ fn add_days(datetime: DateTime, days: i64, mut is_ago: bool) -> Option, +fn add_duration( + datetime: DateTime, duration: Duration, is_ago: bool, -) -> Option> { +) -> Option> { let duration = if is_ago { -duration } else { duration }; datetime.checked_add_signed(duration) } From 5e6bddb6f56d9749876599a7ae0a2e44772ca18b Mon Sep 17 00:00:00 2001 From: ysthakur <45539777+ysthakur@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:13:47 -0400 Subject: [PATCH 17/75] Get rid of parse_relative_time --- src/lib.rs | 10 +- src/parse_relative_time.rs | 239 ++++++++++++++++++------------------- 2 files changed, 116 insertions(+), 133 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4d634f4..db1c8ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,7 @@ use chrono::{ Timelike, }; -use parse_relative_time::parse_relative_time; +use parse_relative_time::parse_relative_time_at_date; use parse_timestamp::parse_timestamp; #[derive(Debug, PartialEq)] @@ -228,12 +228,8 @@ pub fn parse_datetime_at_date + Clone>( } // Parse relative time. - if let Ok(relative_time) = parse_relative_time(s.as_ref()) { - let current_time = DateTime::::from(date); - - if let Some(date_time) = current_time.checked_add_signed(relative_time) { - return Ok(date_time); - } + if let Ok(datetime) = parse_relative_time_at_date(date, s.as_ref()) { + return Ok(DateTime::::from(datetime)); } // parse time only dates diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index 091adcf..70a6489 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -1,16 +1,17 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. use crate::ParseDateTimeError; -use chrono::{DateTime, Days, Duration, Months, TimeZone, Utc}; +use chrono::{DateTime, Days, Duration, Months, TimeZone}; use regex::Regex; -/// Parses a relative time string and returns a `Duration` representing the -/// relative time. -///Regex + +/// Parses a relative time string and adds the duration that it represents to the +/// given date. +/// /// # Arguments /// +/// * `date` - A `Date` instance representing the base date for the calculation /// * `s` - A string slice representing the relative time. /// -/// /// # Supported formats /// /// The function supports the following formats for relative time: @@ -38,27 +39,7 @@ use regex::Regex; /// This function will return `Err(ParseDateTimeError::InvalidInput)` if the input string /// cannot be parsed as a relative time. /// -/// ``` -pub fn parse_relative_time(s: &str) -> Result { - let now = Utc::now(); - let parsed = parse_relative_time_at_date(now, s)?; - Ok(parsed - now) -} - -/// Parses a duration string and returns a `Duration` instance, with the duration -/// calculated from the specified date. -/// -/// # Arguments -/// -/// * `date` - A `Date` instance representing the base date for the calculation -/// * `s` - A string slice representing the relative time. -/// -/// # Errors -/// -/// This function will return `Err(ParseDateTimeError::InvalidInput)` if the input string -/// cannot be parsed as a relative time. -/// ``` -fn parse_relative_time_at_date( +pub fn parse_relative_time_at_date( mut datetime: DateTime, s: &str, ) -> Result, ParseDateTimeError> { @@ -193,27 +174,33 @@ fn add_duration( #[cfg(test)] mod tests { + use super::parse_relative_time_at_date; use super::ParseDateTimeError; - use super::{parse_relative_time, parse_relative_time_at_date}; use chrono::{Days, Duration, Months, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc}; + fn parse_duration(s: &str) -> Result { + let now = Utc::now(); + let parsed = parse_relative_time_at_date(now, s)?; + Ok(parsed - now) + } + #[test] fn test_years() { let now = Utc::now(); assert_eq!( - now + parse_relative_time("1 year").unwrap(), + parse_relative_time_at_date(now, "1 year").unwrap(), now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!( - now + parse_relative_time("-2 years").unwrap(), + parse_relative_time_at_date(now, "-2 years").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - now + parse_relative_time("2 years ago").unwrap(), + parse_relative_time_at_date(now, "2 years ago").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - now + parse_relative_time("year").unwrap(), + parse_relative_time_at_date(now, "year").unwrap(), now.checked_add_months(Months::new(12)).unwrap() ); } @@ -222,29 +209,29 @@ mod tests { fn test_months() { let now = Utc::now(); assert_eq!( - now + parse_relative_time("1 month").unwrap(), + parse_relative_time_at_date(now, "1 month").unwrap(), now.checked_add_months(Months::new(1)).unwrap() ); assert_eq!( - now + parse_relative_time("1 month and 2 weeks").unwrap(), + parse_relative_time_at_date(now, "1 month and 2 weeks").unwrap(), now.checked_add_months(Months::new(1)) .unwrap() .checked_add_days(Days::new(14)) .unwrap() ); assert_eq!( - now + parse_relative_time("1 month and 2 weeks ago").unwrap(), + parse_relative_time_at_date(now, "1 month and 2 weeks ago").unwrap(), now.checked_sub_months(Months::new(1)) .unwrap() .checked_sub_days(Days::new(14)) .unwrap() ); assert_eq!( - now + parse_relative_time("2 months").unwrap(), + parse_relative_time_at_date(now, "2 months").unwrap(), now.checked_add_months(Months::new(2)).unwrap() ); assert_eq!( - now + parse_relative_time("month").unwrap(), + parse_relative_time_at_date(now, "month").unwrap(), now.checked_add_months(Months::new(1)).unwrap() ); } @@ -252,15 +239,15 @@ mod tests { #[test] fn test_fortnights() { assert_eq!( - parse_relative_time("1 fortnight").unwrap(), + parse_duration("1 fortnight").unwrap(), Duration::seconds(1_209_600) ); assert_eq!( - parse_relative_time("3 fortnights").unwrap(), + parse_duration("3 fortnights").unwrap(), Duration::seconds(3_628_800) ); assert_eq!( - parse_relative_time("fortnight").unwrap(), + parse_duration("fortnight").unwrap(), Duration::seconds(1_209_600) ); } @@ -268,27 +255,27 @@ mod tests { #[test] fn test_weeks() { assert_eq!( - parse_relative_time("1 week").unwrap(), + parse_duration("1 week").unwrap(), Duration::seconds(604_800) ); assert_eq!( - parse_relative_time("1 week 3 days").unwrap(), + parse_duration("1 week 3 days").unwrap(), Duration::seconds(864_000) ); assert_eq!( - parse_relative_time("1 week 3 days ago").unwrap(), + parse_duration("1 week 3 days ago").unwrap(), Duration::seconds(-864_000) ); assert_eq!( - parse_relative_time("-2 weeks").unwrap(), + parse_duration("-2 weeks").unwrap(), Duration::seconds(-1_209_600) ); assert_eq!( - parse_relative_time("2 weeks ago").unwrap(), + parse_duration("2 weeks ago").unwrap(), Duration::seconds(-1_209_600) ); assert_eq!( - parse_relative_time("week").unwrap(), + parse_duration("week").unwrap(), Duration::seconds(604_800) ); } @@ -296,19 +283,19 @@ mod tests { #[test] fn test_days() { assert_eq!( - parse_relative_time("1 day").unwrap(), + parse_duration("1 day").unwrap(), Duration::seconds(86400) ); assert_eq!( - parse_relative_time("2 days ago").unwrap(), + parse_duration("2 days ago").unwrap(), Duration::seconds(-172_800) ); assert_eq!( - parse_relative_time("-2 days").unwrap(), + parse_duration("-2 days").unwrap(), Duration::seconds(-172_800) ); assert_eq!( - parse_relative_time("day").unwrap(), + parse_duration("day").unwrap(), Duration::seconds(86400) ); } @@ -316,19 +303,19 @@ mod tests { #[test] fn test_hours() { assert_eq!( - parse_relative_time("1 hour").unwrap(), + parse_duration("1 hour").unwrap(), Duration::seconds(3600) ); assert_eq!( - parse_relative_time("1 hour ago").unwrap(), + parse_duration("1 hour ago").unwrap(), Duration::seconds(-3600) ); assert_eq!( - parse_relative_time("-2 hours").unwrap(), + parse_duration("-2 hours").unwrap(), Duration::seconds(-7200) ); assert_eq!( - parse_relative_time("hour").unwrap(), + parse_duration("hour").unwrap(), Duration::seconds(3600) ); } @@ -336,39 +323,39 @@ mod tests { #[test] fn test_minutes() { assert_eq!( - parse_relative_time("1 minute").unwrap(), + parse_duration("1 minute").unwrap(), Duration::seconds(60) ); assert_eq!( - parse_relative_time("2 minutes").unwrap(), + parse_duration("2 minutes").unwrap(), Duration::seconds(120) ); - assert_eq!(parse_relative_time("min").unwrap(), Duration::seconds(60)); + assert_eq!(parse_duration("min").unwrap(), Duration::seconds(60)); } #[test] fn test_seconds() { assert_eq!( - parse_relative_time("1 second").unwrap(), + parse_duration("1 second").unwrap(), Duration::seconds(1) ); assert_eq!( - parse_relative_time("2 seconds").unwrap(), + parse_duration("2 seconds").unwrap(), Duration::seconds(2) ); - assert_eq!(parse_relative_time("sec").unwrap(), Duration::seconds(1)); + assert_eq!(parse_duration("sec").unwrap(), Duration::seconds(1)); } #[test] fn test_relative_days() { - assert_eq!(parse_relative_time("now").unwrap(), Duration::seconds(0)); - assert_eq!(parse_relative_time("today").unwrap(), Duration::seconds(0)); + assert_eq!(parse_duration("now").unwrap(), Duration::seconds(0)); + assert_eq!(parse_duration("today").unwrap(), Duration::seconds(0)); assert_eq!( - parse_relative_time("yesterday").unwrap(), + parse_duration("yesterday").unwrap(), Duration::seconds(-86400) ); assert_eq!( - parse_relative_time("tomorrow").unwrap(), + parse_duration("tomorrow").unwrap(), Duration::seconds(86400) ); } @@ -376,46 +363,46 @@ mod tests { #[test] fn test_no_spaces() { let now = Utc::now(); - assert_eq!(parse_relative_time("-1hour").unwrap(), Duration::hours(-1)); - assert_eq!(parse_relative_time("+3days").unwrap(), Duration::days(3)); - assert_eq!(parse_relative_time("2weeks").unwrap(), Duration::weeks(2)); + assert_eq!(parse_duration("-1hour").unwrap(), Duration::hours(-1)); + assert_eq!(parse_duration("+3days").unwrap(), Duration::days(3)); + assert_eq!(parse_duration("2weeks").unwrap(), Duration::weeks(2)); assert_eq!( - parse_relative_time("2weeks 1hour").unwrap(), + parse_duration("2weeks 1hour").unwrap(), Duration::seconds(1_213_200) ); assert_eq!( - parse_relative_time("2weeks 1hour ago").unwrap(), + parse_duration("2weeks 1hour ago").unwrap(), Duration::seconds(-1_213_200) ); assert_eq!( - now + parse_relative_time("+4months").unwrap(), + parse_relative_time_at_date(now, "+4months").unwrap(), now.checked_add_months(Months::new(4)).unwrap() ); assert_eq!( - now + parse_relative_time("-2years").unwrap(), + parse_relative_time_at_date(now, "-2years").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - parse_relative_time("15minutes").unwrap(), + parse_duration("15minutes").unwrap(), Duration::minutes(15) ); assert_eq!( - parse_relative_time("-30seconds").unwrap(), + parse_duration("-30seconds").unwrap(), Duration::seconds(-30) ); assert_eq!( - parse_relative_time("30seconds ago").unwrap(), + parse_duration("30seconds ago").unwrap(), Duration::seconds(-30) ); } #[test] fn test_invalid_input() { - let result = parse_relative_time("foobar"); + let result = parse_duration("foobar"); println!("{result:?}"); assert_eq!(result, Err(ParseDateTimeError::InvalidInput)); - let result = parse_relative_time("invalid 1"); + let result = parse_duration("invalid 1"); assert_eq!(result, Err(ParseDateTimeError::InvalidInput)); // Fails for now with a panic /* let result = parse_relative_time("777777777777777771m"); @@ -449,16 +436,16 @@ mod tests { fn test_direction() { let now = Utc::now(); assert_eq!( - parse_relative_time("last hour").unwrap(), + parse_duration("last hour").unwrap(), Duration::seconds(-3600) ); assert_eq!( - now + parse_relative_time("next year").unwrap(), + parse_relative_time_at_date(now, "next year").unwrap(), now.checked_add_months(Months::new(12)).unwrap() ); - assert_eq!(parse_relative_time("next week").unwrap(), Duration::days(7)); + assert_eq!(parse_duration("next week").unwrap(), Duration::days(7)); assert_eq!( - now + parse_relative_time("last month").unwrap(), + parse_relative_time_at_date(now, "last month").unwrap(), now.checked_sub_months(Months::new(1)).unwrap() ); } @@ -467,173 +454,173 @@ mod tests { fn test_duration_parsing() { let now = Utc::now(); assert_eq!( - now + parse_relative_time("1 year").unwrap(), + parse_relative_time_at_date(now, "1 year").unwrap(), now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!( - now + parse_relative_time("-2 years").unwrap(), + parse_relative_time_at_date(now, "-2 years").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - now + parse_relative_time("2 years ago").unwrap(), + parse_relative_time_at_date(now, "2 years ago").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() ); assert_eq!( - now + parse_relative_time("year").unwrap(), + parse_relative_time_at_date(now, "year").unwrap(), now.checked_add_months(Months::new(12)).unwrap() ); assert_eq!( - now + parse_relative_time("1 month").unwrap(), + parse_relative_time_at_date(now, "1 month").unwrap(), now.checked_add_months(Months::new(1)).unwrap() ); assert_eq!( - now + parse_relative_time("1 month and 2 weeks").unwrap(), + parse_relative_time_at_date(now, "1 month and 2 weeks").unwrap(), now.checked_add_months(Months::new(1)) .unwrap() .checked_add_days(Days::new(14)) .unwrap() ); assert_eq!( - now + parse_relative_time("1 month, 2 weeks").unwrap(), + parse_relative_time_at_date(now, "1 month, 2 weeks").unwrap(), now.checked_add_months(Months::new(1)) .unwrap() .checked_add_days(Days::new(14)) .unwrap() ); assert_eq!( - now + parse_relative_time("1 months 2 weeks").unwrap(), + parse_relative_time_at_date(now, "1 months 2 weeks").unwrap(), now.checked_add_months(Months::new(1)) .unwrap() .checked_add_days(Days::new(14)) .unwrap() ); assert_eq!( - now + parse_relative_time("1 month and 2 weeks ago").unwrap(), + parse_relative_time_at_date(now, "1 month and 2 weeks ago").unwrap(), now.checked_sub_months(Months::new(1)) .unwrap() .checked_sub_days(Days::new(14)) .unwrap() ); assert_eq!( - now + parse_relative_time("2 months").unwrap(), + parse_relative_time_at_date(now, "2 months").unwrap(), now.checked_add_months(Months::new(2)).unwrap() ); assert_eq!( - now + parse_relative_time("month").unwrap(), + parse_relative_time_at_date(now, "month").unwrap(), now.checked_add_months(Months::new(1)).unwrap() ); assert_eq!( - now + parse_relative_time("1 fortnight").unwrap(), + parse_relative_time_at_date(now, "1 fortnight").unwrap(), now.checked_add_days(Days::new(14)).unwrap() ); assert_eq!( - now + parse_relative_time("3 fortnights").unwrap(), + parse_relative_time_at_date(now, "3 fortnights").unwrap(), now.checked_add_days(Days::new(3 * 14)).unwrap() ); assert_eq!( - now + parse_relative_time("fortnight").unwrap(), + parse_relative_time_at_date(now, "fortnight").unwrap(), now.checked_add_days(Days::new(14)).unwrap() ); assert_eq!( - now + parse_relative_time("1 week").unwrap(), + parse_relative_time_at_date(now, "1 week").unwrap(), now.checked_add_days(Days::new(7)).unwrap() ); assert_eq!( - now + parse_relative_time("1 week 3 days").unwrap(), + parse_relative_time_at_date(now, "1 week 3 days").unwrap(), now.checked_add_days(Days::new(7 + 3)).unwrap() ); assert_eq!( - now + parse_relative_time("1 week 3 days ago").unwrap(), + parse_relative_time_at_date(now, "1 week 3 days ago").unwrap(), now.checked_sub_days(Days::new(7 + 3)).unwrap() ); assert_eq!( - now + parse_relative_time("-2 weeks").unwrap(), + parse_relative_time_at_date(now, "-2 weeks").unwrap(), now.checked_sub_days(Days::new(14)).unwrap() ); assert_eq!( - now + parse_relative_time("2 weeks ago").unwrap(), + parse_relative_time_at_date(now, "2 weeks ago").unwrap(), now.checked_sub_days(Days::new(14)).unwrap() ); assert_eq!( - now + parse_relative_time("week").unwrap(), + parse_relative_time_at_date(now, "week").unwrap(), now.checked_add_days(Days::new(7)).unwrap() ); assert_eq!( - parse_relative_time("1 day").unwrap(), + parse_duration("1 day").unwrap(), Duration::seconds(86_400) ); assert_eq!( - parse_relative_time("2 days ago").unwrap(), + parse_duration("2 days ago").unwrap(), Duration::seconds(-172_800) ); assert_eq!( - parse_relative_time("-2 days").unwrap(), + parse_duration("-2 days").unwrap(), Duration::seconds(-172_800) ); assert_eq!( - parse_relative_time("day").unwrap(), + parse_duration("day").unwrap(), Duration::seconds(86_400) ); assert_eq!( - parse_relative_time("1 hour").unwrap(), + parse_duration("1 hour").unwrap(), Duration::seconds(3_600) ); assert_eq!( - parse_relative_time("1 h").unwrap(), + parse_duration("1 h").unwrap(), Duration::seconds(3_600) ); assert_eq!( - parse_relative_time("1 hour ago").unwrap(), + parse_duration("1 hour ago").unwrap(), Duration::seconds(-3_600) ); assert_eq!( - parse_relative_time("-2 hours").unwrap(), + parse_duration("-2 hours").unwrap(), Duration::seconds(-7_200) ); assert_eq!( - parse_relative_time("hour").unwrap(), + parse_duration("hour").unwrap(), Duration::seconds(3_600) ); assert_eq!( - parse_relative_time("1 minute").unwrap(), + parse_duration("1 minute").unwrap(), Duration::seconds(60) ); - assert_eq!(parse_relative_time("1 min").unwrap(), Duration::seconds(60)); + assert_eq!(parse_duration("1 min").unwrap(), Duration::seconds(60)); assert_eq!( - parse_relative_time("2 minutes").unwrap(), + parse_duration("2 minutes").unwrap(), Duration::seconds(120) ); assert_eq!( - parse_relative_time("2 mins").unwrap(), + parse_duration("2 mins").unwrap(), Duration::seconds(120) ); - assert_eq!(parse_relative_time("2m").unwrap(), Duration::seconds(120)); - assert_eq!(parse_relative_time("min").unwrap(), Duration::seconds(60)); + assert_eq!(parse_duration("2m").unwrap(), Duration::seconds(120)); + assert_eq!(parse_duration("min").unwrap(), Duration::seconds(60)); assert_eq!( - parse_relative_time("1 second").unwrap(), + parse_duration("1 second").unwrap(), Duration::seconds(1) ); - assert_eq!(parse_relative_time("1 s").unwrap(), Duration::seconds(1)); + assert_eq!(parse_duration("1 s").unwrap(), Duration::seconds(1)); assert_eq!( - parse_relative_time("2 seconds").unwrap(), + parse_duration("2 seconds").unwrap(), Duration::seconds(2) ); - assert_eq!(parse_relative_time("2 secs").unwrap(), Duration::seconds(2)); - assert_eq!(parse_relative_time("2 sec").unwrap(), Duration::seconds(2)); - assert_eq!(parse_relative_time("sec").unwrap(), Duration::seconds(1)); + assert_eq!(parse_duration("2 secs").unwrap(), Duration::seconds(2)); + assert_eq!(parse_duration("2 sec").unwrap(), Duration::seconds(2)); + assert_eq!(parse_duration("sec").unwrap(), Duration::seconds(1)); - assert_eq!(parse_relative_time("now").unwrap(), Duration::seconds(0)); - assert_eq!(parse_relative_time("today").unwrap(), Duration::seconds(0)); + assert_eq!(parse_duration("now").unwrap(), Duration::seconds(0)); + assert_eq!(parse_duration("today").unwrap(), Duration::seconds(0)); assert_eq!( - now + parse_relative_time("1 year 2 months 4 weeks 3 days and 2 seconds").unwrap(), + parse_relative_time_at_date(now, "1 year 2 months 4 weeks 3 days and 2 seconds").unwrap(), now.checked_add_months(Months::new(12 + 2)) .unwrap() .checked_add_days(Days::new(4 * 7 + 3)) @@ -642,7 +629,7 @@ mod tests { .unwrap() ); assert_eq!( - now + parse_relative_time("1 year 2 months 4 weeks 3 days and 2 seconds ago").unwrap(), + parse_relative_time_at_date(now, "1 year 2 months 4 weeks 3 days and 2 seconds ago").unwrap(), now.checked_sub_months(Months::new(12 + 2)) .unwrap() .checked_sub_days(Days::new(4 * 7 + 3)) @@ -656,13 +643,13 @@ mod tests { #[should_panic] fn test_display_parse_duration_error_through_parse_relative_time() { let invalid_input = "9223372036854775807 seconds and 1 second"; - let _ = parse_relative_time(invalid_input).unwrap(); + let _ = parse_duration(invalid_input).unwrap(); } #[test] fn test_display_should_fail() { let invalid_input = "Thu Jan 01 12:34:00 2015"; - let error = parse_relative_time(invalid_input).unwrap_err(); + let error = parse_duration(invalid_input).unwrap_err(); assert_eq!( format!("{error}"), From d5015a641e037a7e1c6e9ed166122d1a6f12468c Mon Sep 17 00:00:00 2001 From: ysthakur <45539777+ysthakur@users.noreply.github.com> Date: Wed, 28 Aug 2024 02:24:49 -0400 Subject: [PATCH 18/75] Format --- src/parse_relative_time.rs | 106 +++++++++---------------------------- 1 file changed, 24 insertions(+), 82 deletions(-) diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index 70a6489..d01d019 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -274,18 +274,12 @@ mod tests { parse_duration("2 weeks ago").unwrap(), Duration::seconds(-1_209_600) ); - assert_eq!( - parse_duration("week").unwrap(), - Duration::seconds(604_800) - ); + assert_eq!(parse_duration("week").unwrap(), Duration::seconds(604_800)); } #[test] fn test_days() { - assert_eq!( - parse_duration("1 day").unwrap(), - Duration::seconds(86400) - ); + assert_eq!(parse_duration("1 day").unwrap(), Duration::seconds(86400)); assert_eq!( parse_duration("2 days ago").unwrap(), Duration::seconds(-172_800) @@ -294,18 +288,12 @@ mod tests { parse_duration("-2 days").unwrap(), Duration::seconds(-172_800) ); - assert_eq!( - parse_duration("day").unwrap(), - Duration::seconds(86400) - ); + assert_eq!(parse_duration("day").unwrap(), Duration::seconds(86400)); } #[test] fn test_hours() { - assert_eq!( - parse_duration("1 hour").unwrap(), - Duration::seconds(3600) - ); + assert_eq!(parse_duration("1 hour").unwrap(), Duration::seconds(3600)); assert_eq!( parse_duration("1 hour ago").unwrap(), Duration::seconds(-3600) @@ -314,35 +302,20 @@ mod tests { parse_duration("-2 hours").unwrap(), Duration::seconds(-7200) ); - assert_eq!( - parse_duration("hour").unwrap(), - Duration::seconds(3600) - ); + assert_eq!(parse_duration("hour").unwrap(), Duration::seconds(3600)); } #[test] fn test_minutes() { - assert_eq!( - parse_duration("1 minute").unwrap(), - Duration::seconds(60) - ); - assert_eq!( - parse_duration("2 minutes").unwrap(), - Duration::seconds(120) - ); + assert_eq!(parse_duration("1 minute").unwrap(), Duration::seconds(60)); + assert_eq!(parse_duration("2 minutes").unwrap(), Duration::seconds(120)); assert_eq!(parse_duration("min").unwrap(), Duration::seconds(60)); } #[test] fn test_seconds() { - assert_eq!( - parse_duration("1 second").unwrap(), - Duration::seconds(1) - ); - assert_eq!( - parse_duration("2 seconds").unwrap(), - Duration::seconds(2) - ); + assert_eq!(parse_duration("1 second").unwrap(), Duration::seconds(1)); + assert_eq!(parse_duration("2 seconds").unwrap(), Duration::seconds(2)); assert_eq!(parse_duration("sec").unwrap(), Duration::seconds(1)); } @@ -382,10 +355,7 @@ mod tests { parse_relative_time_at_date(now, "-2years").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() ); - assert_eq!( - parse_duration("15minutes").unwrap(), - Duration::minutes(15) - ); + assert_eq!(parse_duration("15minutes").unwrap(), Duration::minutes(15)); assert_eq!( parse_duration("-30seconds").unwrap(), Duration::seconds(-30) @@ -549,10 +519,7 @@ mod tests { now.checked_add_days(Days::new(7)).unwrap() ); - assert_eq!( - parse_duration("1 day").unwrap(), - Duration::seconds(86_400) - ); + assert_eq!(parse_duration("1 day").unwrap(), Duration::seconds(86_400)); assert_eq!( parse_duration("2 days ago").unwrap(), Duration::seconds(-172_800) @@ -561,19 +528,10 @@ mod tests { parse_duration("-2 days").unwrap(), Duration::seconds(-172_800) ); - assert_eq!( - parse_duration("day").unwrap(), - Duration::seconds(86_400) - ); + assert_eq!(parse_duration("day").unwrap(), Duration::seconds(86_400)); - assert_eq!( - parse_duration("1 hour").unwrap(), - Duration::seconds(3_600) - ); - assert_eq!( - parse_duration("1 h").unwrap(), - Duration::seconds(3_600) - ); + assert_eq!(parse_duration("1 hour").unwrap(), Duration::seconds(3_600)); + assert_eq!(parse_duration("1 h").unwrap(), Duration::seconds(3_600)); assert_eq!( parse_duration("1 hour ago").unwrap(), Duration::seconds(-3_600) @@ -582,36 +540,18 @@ mod tests { parse_duration("-2 hours").unwrap(), Duration::seconds(-7_200) ); - assert_eq!( - parse_duration("hour").unwrap(), - Duration::seconds(3_600) - ); + assert_eq!(parse_duration("hour").unwrap(), Duration::seconds(3_600)); - assert_eq!( - parse_duration("1 minute").unwrap(), - Duration::seconds(60) - ); + assert_eq!(parse_duration("1 minute").unwrap(), Duration::seconds(60)); assert_eq!(parse_duration("1 min").unwrap(), Duration::seconds(60)); - assert_eq!( - parse_duration("2 minutes").unwrap(), - Duration::seconds(120) - ); - assert_eq!( - parse_duration("2 mins").unwrap(), - Duration::seconds(120) - ); + assert_eq!(parse_duration("2 minutes").unwrap(), Duration::seconds(120)); + assert_eq!(parse_duration("2 mins").unwrap(), Duration::seconds(120)); assert_eq!(parse_duration("2m").unwrap(), Duration::seconds(120)); assert_eq!(parse_duration("min").unwrap(), Duration::seconds(60)); - assert_eq!( - parse_duration("1 second").unwrap(), - Duration::seconds(1) - ); + assert_eq!(parse_duration("1 second").unwrap(), Duration::seconds(1)); assert_eq!(parse_duration("1 s").unwrap(), Duration::seconds(1)); - assert_eq!( - parse_duration("2 seconds").unwrap(), - Duration::seconds(2) - ); + assert_eq!(parse_duration("2 seconds").unwrap(), Duration::seconds(2)); assert_eq!(parse_duration("2 secs").unwrap(), Duration::seconds(2)); assert_eq!(parse_duration("2 sec").unwrap(), Duration::seconds(2)); assert_eq!(parse_duration("sec").unwrap(), Duration::seconds(1)); @@ -620,7 +560,8 @@ mod tests { assert_eq!(parse_duration("today").unwrap(), Duration::seconds(0)); assert_eq!( - parse_relative_time_at_date(now, "1 year 2 months 4 weeks 3 days and 2 seconds").unwrap(), + parse_relative_time_at_date(now, "1 year 2 months 4 weeks 3 days and 2 seconds") + .unwrap(), now.checked_add_months(Months::new(12 + 2)) .unwrap() .checked_add_days(Days::new(4 * 7 + 3)) @@ -629,7 +570,8 @@ mod tests { .unwrap() ); assert_eq!( - parse_relative_time_at_date(now, "1 year 2 months 4 weeks 3 days and 2 seconds ago").unwrap(), + parse_relative_time_at_date(now, "1 year 2 months 4 weeks 3 days and 2 seconds ago") + .unwrap(), now.checked_sub_months(Months::new(12 + 2)) .unwrap() .checked_sub_days(Days::new(4 * 7 + 3)) From e41e26fef1db32146ab01aa65c32c97f8ab3e7e7 Mon Sep 17 00:00:00 2001 From: ysthakur <45539777+ysthakur@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:55:47 -0400 Subject: [PATCH 19/75] Replace unnecessary return with None --- src/parse_relative_time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index d01d019..afaaf34 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -102,7 +102,7 @@ pub fn parse_relative_time_at_date( "yesterday" => add_days(datetime, 1, true), "tomorrow" => add_days(datetime, 1, false), "now" | "today" => Some(datetime), - _ => return Err(ParseDateTimeError::InvalidInput), + _ => None, }; datetime = match new_datetime { Some(dt) => dt, From 1570d92fc5f95c81b966ad0811447c08b5e8df69 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 4 May 2024 14:50:34 +0200 Subject: [PATCH 20/75] Bump chrono and iana-time-zone chrono: 0.4.26 -> 0.4.38 iana-time-zone: 0.1.56 -> 0.1.61 --- Cargo.lock | 104 +++++++++++++++++++++++------------------------------ Cargo.toml | 2 +- 2 files changed, 46 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b1ce71..e224c9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,14 +52,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets", ] [[package]] @@ -70,16 +70,16 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -224,19 +224,20 @@ checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", @@ -249,9 +250,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -259,9 +260,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", @@ -272,50 +273,29 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -324,42 +304,48 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml index f7148f6..7f2c4d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,5 @@ readme = "README.md" [dependencies] regex = "1.10.4" -chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] } +chrono = { version="0.4.38", default-features=false, features=["std", "alloc", "clock"] } nom = "7.1.3" From bbcafc42f9257be107d106fda376855e1ae00c8b Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 4 May 2024 15:02:34 +0200 Subject: [PATCH 21/75] Replace use of NativeDateTime::from_timestamp_opt with DateTime::from_timestamp due to deprecation --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4d634f4..547031c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -199,8 +199,8 @@ pub fn parse_datetime_at_date + Clone>( // Parse epoch seconds if let Ok(timestamp) = parse_timestamp(s.as_ref()) { - if let Some(timestamp_date) = NaiveDateTime::from_timestamp_opt(timestamp, 0) { - return Ok(date.offset().from_utc_datetime(×tamp_date)); + if let Some(timestamp_date) = DateTime::from_timestamp(timestamp, 0) { + return Ok(timestamp_date.into()); } } From 19d49cfe7396c4356f4b21ef0ba8b13ed3d2bbde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 07:39:50 +0000 Subject: [PATCH 22/75] fix(deps): update rust crate chrono to v0.4.38 --- fuzz/Cargo.lock | 106 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 79eef27..dbd05ce 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -61,14 +61,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets 0.52.6", ] [[package]] @@ -370,49 +370,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] -name = "winapi" -version = "0.3.9" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-targets 0.48.0", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" +name = "windows-targets" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows-targets", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -421,38 +415,86 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" From cd7020f0381ca32cdf73594e183ff9a5b11e9c32 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 17 Sep 2024 09:49:38 +0200 Subject: [PATCH 23/75] Bump iana-time-zone in fuzz from 0.1.56 to 0.1.61 --- fuzz/Cargo.lock | 112 ++++++++++++------------------------------------ 1 file changed, 28 insertions(+), 84 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index dbd05ce..c776941 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -68,7 +68,7 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -101,16 +101,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -133,9 +133,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -317,19 +317,20 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", @@ -342,9 +343,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -352,9 +353,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", @@ -365,32 +366,17 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows-targets", ] [[package]] @@ -399,46 +385,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -451,48 +419,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" From 8a528468ae1752bafd07dc615a6e030f233017f6 Mon Sep 17 00:00:00 2001 From: Paul Houssel Date: Mon, 2 Sep 2024 14:31:11 +1000 Subject: [PATCH 24/75] include 'this' direction --- src/parse_relative_time.rs | 68 ++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/parse_relative_time.rs b/src/parse_relative_time.rs index afaaf34..7d058b4 100644 --- a/src/parse_relative_time.rs +++ b/src/parse_relative_time.rs @@ -46,7 +46,7 @@ pub fn parse_relative_time_at_date( let time_pattern: Regex = Regex::new( r"(?x) (?:(?P[-+]?\d*)\s*)? - (\s*(?Pnext|last)?\s*)? + (\s*(?Pnext|this|last)?\s*)? (?Pyears?|months?|fortnights?|weeks?|days?|hours?|h|minutes?|mins?|m|seconds?|secs?|s|yesterday|tomorrow|now|today) (\s*(?Pand|,)?\s*)? (\s*(?Pago)?)?", @@ -71,10 +71,10 @@ pub fn parse_relative_time_at_date( .map_err(|_| ParseDateTimeError::InvalidInput)? }; - if let Some(direction) = capture.name("direction") { - if direction.as_str() == "last" { - is_ago = true; - } + let direction = capture.name("direction").map_or("", |d| d.as_str()); + + if direction == "last" { + is_ago = true; } let unit = capture @@ -86,23 +86,27 @@ pub fn parse_relative_time_at_date( is_ago = true; } - let new_datetime = match unit { - "years" | "year" => add_months(datetime, value * 12, is_ago), - "months" | "month" => add_months(datetime, value, is_ago), - "fortnights" | "fortnight" => add_days(datetime, value * 14, is_ago), - "weeks" | "week" => add_days(datetime, value * 7, is_ago), - "days" | "day" => add_days(datetime, value, is_ago), - "hours" | "hour" | "h" => add_duration(datetime, Duration::hours(value), is_ago), - "minutes" | "minute" | "mins" | "min" | "m" => { - add_duration(datetime, Duration::minutes(value), is_ago) - } - "seconds" | "second" | "secs" | "sec" | "s" => { - add_duration(datetime, Duration::seconds(value), is_ago) + let new_datetime = if direction == "this" { + add_days(datetime, 0, is_ago) + } else { + match unit { + "years" | "year" => add_months(datetime, value * 12, is_ago), + "months" | "month" => add_months(datetime, value, is_ago), + "fortnights" | "fortnight" => add_days(datetime, value * 14, is_ago), + "weeks" | "week" => add_days(datetime, value * 7, is_ago), + "days" | "day" => add_days(datetime, value, is_ago), + "hours" | "hour" | "h" => add_duration(datetime, Duration::hours(value), is_ago), + "minutes" | "minute" | "mins" | "min" | "m" => { + add_duration(datetime, Duration::minutes(value), is_ago) + } + "seconds" | "second" | "secs" | "sec" | "s" => { + add_duration(datetime, Duration::seconds(value), is_ago) + } + "yesterday" => add_days(datetime, 1, true), + "tomorrow" => add_days(datetime, 1, false), + "now" | "today" => Some(datetime), + _ => None, } - "yesterday" => add_days(datetime, 1, true), - "tomorrow" => add_days(datetime, 1, false), - "now" | "today" => Some(datetime), - _ => None, }; datetime = match new_datetime { Some(dt) => dt, @@ -191,6 +195,10 @@ mod tests { parse_relative_time_at_date(now, "1 year").unwrap(), now.checked_add_months(Months::new(12)).unwrap() ); + assert_eq!( + parse_relative_time_at_date(now, "this year").unwrap(), + now.checked_add_months(Months::new(0)).unwrap() + ); assert_eq!( parse_relative_time_at_date(now, "-2 years").unwrap(), now.checked_sub_months(Months::new(24)).unwrap() @@ -212,6 +220,10 @@ mod tests { parse_relative_time_at_date(now, "1 month").unwrap(), now.checked_add_months(Months::new(1)).unwrap() ); + assert_eq!( + parse_relative_time_at_date(now, "this month").unwrap(), + now.checked_add_months(Months::new(0)).unwrap() + ); assert_eq!( parse_relative_time_at_date(now, "1 month and 2 weeks").unwrap(), now.checked_add_months(Months::new(1)) @@ -242,6 +254,10 @@ mod tests { parse_duration("1 fortnight").unwrap(), Duration::seconds(1_209_600) ); + assert_eq!( + parse_duration("this fortnight").unwrap(), + Duration::seconds(0) + ); assert_eq!( parse_duration("3 fortnights").unwrap(), Duration::seconds(3_628_800) @@ -258,6 +274,7 @@ mod tests { parse_duration("1 week").unwrap(), Duration::seconds(604_800) ); + assert_eq!(parse_duration("this week").unwrap(), Duration::seconds(0)); assert_eq!( parse_duration("1 week 3 days").unwrap(), Duration::seconds(864_000) @@ -284,6 +301,7 @@ mod tests { parse_duration("2 days ago").unwrap(), Duration::seconds(-172_800) ); + assert_eq!(parse_duration("this day").unwrap(), Duration::seconds(0)); assert_eq!( parse_duration("-2 days").unwrap(), Duration::seconds(-172_800) @@ -298,6 +316,7 @@ mod tests { parse_duration("1 hour ago").unwrap(), Duration::seconds(-3600) ); + assert_eq!(parse_duration("this hour").unwrap(), Duration::seconds(0)); assert_eq!( parse_duration("-2 hours").unwrap(), Duration::seconds(-7200) @@ -307,6 +326,7 @@ mod tests { #[test] fn test_minutes() { + assert_eq!(parse_duration("this minute").unwrap(), Duration::seconds(0)); assert_eq!(parse_duration("1 minute").unwrap(), Duration::seconds(60)); assert_eq!(parse_duration("2 minutes").unwrap(), Duration::seconds(120)); assert_eq!(parse_duration("min").unwrap(), Duration::seconds(60)); @@ -314,6 +334,7 @@ mod tests { #[test] fn test_seconds() { + assert_eq!(parse_duration("this second").unwrap(), Duration::seconds(0)); assert_eq!(parse_duration("1 second").unwrap(), Duration::seconds(1)); assert_eq!(parse_duration("2 seconds").unwrap(), Duration::seconds(2)); assert_eq!(parse_duration("sec").unwrap(), Duration::seconds(1)); @@ -347,6 +368,7 @@ mod tests { parse_duration("2weeks 1hour ago").unwrap(), Duration::seconds(-1_213_200) ); + assert_eq!(parse_duration("thismonth").unwrap(), Duration::days(0)); assert_eq!( parse_relative_time_at_date(now, "+4months").unwrap(), now.checked_add_months(Months::new(4)).unwrap() @@ -418,6 +440,10 @@ mod tests { parse_relative_time_at_date(now, "last month").unwrap(), now.checked_sub_months(Months::new(1)).unwrap() ); + + assert_eq!(parse_duration("this month").unwrap(), Duration::days(0)); + + assert_eq!(parse_duration("this year").unwrap(), Duration::days(0)); } #[test] From 313de7ba7c3a45ecec1e697412ccbcd79802cec1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 29 Sep 2024 16:46:09 +0000 Subject: [PATCH 25/75] fix(deps): update rust crate regex to v1.11.0 --- Cargo.lock | 12 ++++++------ fuzz/Cargo.lock | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e224c9d..8a3852b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -190,9 +190,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "syn" diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index dbd05ce..6e6a361 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.4" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -288,9 +288,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "syn" From 48852068de09994d854efd5a95507a22756a31b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:07:28 +0000 Subject: [PATCH 26/75] fix(deps): update rust crate regex to v1.11.1 --- Cargo.lock | 4 ++-- fuzz/Cargo.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a3852b..b2878c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 6e6a361..e4c1b7d 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", From a841ad0fc44c7f28ce3b2ec64d409329b9b75c95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 01:44:41 +0000 Subject: [PATCH 27/75] fix(deps): update rust crate libfuzzer-sys to v0.4.8 --- fuzz/Cargo.lock | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index e4c1b7d..c71b77f 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -148,13 +148,12 @@ checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" dependencies = [ "arbitrary", "cc", - "once_cell", ] [[package]] From 9b266bcb1739d6ae464b5b0145e51be2aed419a7 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 11 Nov 2024 09:48:09 +0100 Subject: [PATCH 28/75] ci: use -Cinstrument-coverage instead of -Zprofile Support for -Zprofile has been removed: https://github.com/rust-lang/rust/pull/131829 --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cca0070..b2f1e00 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,21 +75,22 @@ jobs: if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi outputs TOOLCHAIN # target-specific options - # * CARGO_FEATURES_OPTION - CARGO_FEATURES_OPTION='--all -- --check' ; ## default to '--all-features' for code coverage # * CODECOV_FLAGS CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' ) outputs CODECOV_FLAGS - name: rust toolchain ~ install uses: dtolnay/rust-toolchain@nightly + with: + components: llvm-tools-preview - name: Test - run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast + run: cargo test --no-fail-fast env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" - RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" + RUSTFLAGS: "-Cinstrument-coverage -Zcoverage-options=branch -Ccodegen-units=1 -Copt-level=0 -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" + LLVM_PROFILE_FILE: "parse_datetime-%p-%m.profraw" - name: "`grcov` ~ install" id: build_grcov shell: bash @@ -117,13 +118,12 @@ jobs: COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info" mkdir -p "${COVERAGE_REPORT_DIR}" # display coverage files - grcov . --output-type files --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique + grcov . --binary-path="${COVERAGE_REPORT_DIR}" --output-type files --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique # generate coverage report - grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" + grcov . --binary-path="${COVERAGE_REPORT_DIR}" --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" echo "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT - name: Upload coverage results (to Codecov.io) uses: codecov/codecov-action@v4 - # if: steps.vars.outputs.HAS_CODECOV_TOKEN with: token: ${{ secrets.CODECOV_TOKEN }} file: ${{ steps.coverage.outputs.report }} From dba1374f8e3a222f2e08fd41e9773f15afd6c80e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 14:38:21 +0000 Subject: [PATCH 29/75] chore(config): migrate config renovate.json --- renovate.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index 39a2b6e..5db72dd 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "config:base" + "config:recommended" ] } From a9bccfa20ab95ede8037575ea440ece63609c168 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 29 Nov 2024 09:44:40 +0100 Subject: [PATCH 30/75] clippy: fix warning from needless_return lint --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 9f61baa..3fbe640 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -415,8 +415,9 @@ mod tests { fn get_formatted_date(date: DateTime, weekday: &str) -> String { let result = parse_datetime_at_date(date, weekday).unwrap(); - return result.format("%F %T %f").to_string(); + result.format("%F %T %f").to_string() } + #[test] fn test_weekday() { // add some constant hours and minutes and seconds to check its reset From 7ab9a02761e629625502db982e18595ca1e45b1a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2024 14:49:20 +0000 Subject: [PATCH 31/75] chore(deps): update codecov/codecov-action action to v5 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2f1e00..9d8a289 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: grcov . --binary-path="${COVERAGE_REPORT_DIR}" --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" echo "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT - name: Upload coverage results (to Codecov.io) - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} file: ${{ steps.coverage.outputs.report }} From fa311c0dd42d89024fa68dcbf93905323f8a842e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 29 Nov 2024 15:59:28 +0100 Subject: [PATCH 32/75] ci: fix deprecated codecov argument --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d8a289..9ad863d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,7 +126,7 @@ jobs: uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ${{ steps.coverage.outputs.report }} + files: ${{ steps.coverage.outputs.report }} ## flags: IntegrationTests, UnitTests, ${{ steps.vars.outputs.CODECOV_FLAGS }} flags: ${{ steps.vars.outputs.CODECOV_FLAGS }} name: codecov-umbrella From 56410cebcfc29a6986ba6a9311d240f4718b1e9c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:12:42 +0000 Subject: [PATCH 33/75] fix(deps): update rust crate chrono to v0.4.39 --- Cargo.lock | 6 +++--- fuzz/Cargo.lock | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2878c9..397acb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -52,9 +52,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 528b6ca..ef5d266 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -61,9 +61,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", From 3c67f4b5c9db6f6c6948316d4749b1a2b1af02e6 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Wed, 8 Jan 2025 21:38:12 -0500 Subject: [PATCH 34/75] Add support for military time zones Fixes #39 --- src/parse_time_only_str.rs | 114 +++++++++++++++++++++++++++++++++---- 1 file changed, 102 insertions(+), 12 deletions(-) diff --git a/src/parse_time_only_str.rs b/src/parse_time_only_str.rs index e909216..ef0f814 100644 --- a/src/parse_time_only_str.rs +++ b/src/parse_time_only_str.rs @@ -7,11 +7,75 @@ mod time_only_formats { pub const TWELVEHOUR: &str = "%r"; } +/// Convert a military time zone string to a time zone offset. +/// +/// Military time zones are the letters A through Z except J. They are +/// described in RFC 5322. +fn to_offset(tz: &str) -> Option { + let hour = match tz { + "A" => 1, + "B" => 2, + "C" => 3, + "D" => 4, + "E" => 5, + "F" => 6, + "G" => 7, + "H" => 8, + "I" => 9, + "K" => 10, + "L" => 11, + "M" => 12, + "N" => -1, + "O" => -2, + "P" => -3, + "Q" => -4, + "R" => -5, + "S" => -6, + "T" => -7, + "U" => -8, + "V" => -9, + "W" => -10, + "X" => -11, + "Y" => -12, + "Z" => 0, + _ => return None, + }; + let offset_in_sec = hour * 3600; + FixedOffset::east_opt(offset_in_sec) +} + +/// Parse a time string without an offset and apply an offset to it. +/// +/// Multiple formats are attempted when parsing the string. +fn parse_time_with_offset_multi( + date: DateTime, + offset: FixedOffset, + s: &str, +) -> Option> { + for fmt in [ + time_only_formats::HH_MM, + time_only_formats::HH_MM_SS, + time_only_formats::TWELVEHOUR, + ] { + let parsed = match NaiveTime::parse_from_str(s, fmt) { + Ok(t) => t, + Err(_) => continue, + }; + let parsed_dt = date.date_naive().and_time(parsed); + match offset.from_local_datetime(&parsed_dt).single() { + Some(dt) => return Some(dt), + None => continue, + } + } + None +} + pub(crate) fn parse_time_only(date: DateTime, s: &str) -> Option> { let re = Regex::new(r"^(?