1 Commits

Author SHA1 Message Date
Sylvestre Ledru ea52a79163 prepare new release 0.7.0 2025-01-19 22:23:58 +01:00
10 changed files with 187 additions and 464 deletions
Generated
+11 -4
View File
@@ -119,12 +119,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "nom"
version = "8.0.0"
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
@@ -144,7 +151,7 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parse_datetime"
version = "0.8.0"
version = "0.7.0"
dependencies = [
"chrono",
"nom",
+2 -2
View File
@@ -1,7 +1,7 @@
[package]
name = "parse_datetime"
description = "parsing human-readable time strings and converting them to a DateTime"
version = "0.8.0"
version = "0.7.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/uutils/parse_datetime"
@@ -10,4 +10,4 @@ readme = "README.md"
[dependencies]
regex = "1.10.4"
chrono = { version="0.4.38", default-features=false, features=["std", "alloc", "clock"] }
nom = "8.0.0"
nom = "7.1.3"
+3 -2
View File
@@ -18,8 +18,9 @@ A Rust crate for parsing human-readable relative time strings and human-readable
Add this to your `Cargo.toml`:
```
cargo add parse_datetime
```toml
[dependencies]
parse_datetime = "0.6.0"
```
Then, import the crate and use the `parse_datetime_at_date` function:
+71 -18
View File
@@ -46,13 +46,11 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "cc"
version = "1.2.10"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
"libc",
"shlex",
]
[[package]]
@@ -86,9 +84,21 @@ dependencies = [
"chrono",
"libfuzzer-sys",
"parse_datetime",
"rand",
"regex",
]
[[package]]
name = "getrandom"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "iana-time-zone"
version = "0.1.61"
@@ -114,9 +124,9 @@ dependencies = [
[[package]]
name = "jobserver"
version = "0.1.32"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
dependencies = [
"libc",
]
@@ -138,9 +148,9 @@ checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
[[package]]
name = "libfuzzer-sys"
version = "0.4.9"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75"
checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa"
dependencies = [
"arbitrary",
"cc",
@@ -159,12 +169,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e"
[[package]]
name = "nom"
version = "8.0.0"
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
@@ -184,13 +201,19 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "parse_datetime"
version = "0.7.0"
version = "0.6.0"
dependencies = [
"chrono",
"nom",
"regex",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.59"
@@ -209,6 +232,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.11.1"
@@ -238,12 +291,6 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.18"
@@ -261,6 +308,12 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.93"
+1
View File
@@ -7,6 +7,7 @@ edition = "2021"
cargo-fuzz = true
[dependencies]
rand = "0.8.5"
libfuzzer-sys = "0.4.7"
regex = "1.10.4"
chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] }
+68 -396
View File
File diff suppressed because it is too large Load Diff
+17 -27
View File
@@ -20,8 +20,6 @@ const DAYS_PER_MONTH: [u32; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 3
/// * `date` - A `Date` instance representing the base date for the calculation
/// * `s` - A string slice representing the relative time.
///
/// If `s` is empty, the `date` is returned as-is.
///
/// # Supported formats
///
/// The function supports the following formats for relative time:
@@ -53,10 +51,6 @@ pub fn parse_relative_time_at_date<T: TimeZone>(
mut datetime: DateTime<T>,
s: &str,
) -> Result<DateTime<T>, ParseDateTimeError> {
let s = s.trim();
if s.is_empty() {
return Ok(datetime);
}
let time_pattern: Regex = Regex::new(
r"(?x)
(?:(?P<value>[-+]?\d*)\s*)?
@@ -284,12 +278,6 @@ mod tests {
Ok(parsed - now)
}
#[test]
fn test_empty_string() {
let now = Utc::now();
assert_eq!(parse_relative_time_at_date(now, "").unwrap(), now);
}
#[test]
fn test_years() {
let now = Utc::now();
@@ -297,7 +285,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);
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()
@@ -328,24 +319,25 @@ mod tests {
#[test]
fn test_months() {
use crate::parse_relative_time::add_months;
let now = Utc::now();
assert_eq!(
parse_relative_time_at_date(now, "1 month").unwrap(),
add_months(now, 1, false).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, "this month").unwrap(), now);
assert_eq!(
parse_relative_time_at_date(now, "1 month and 2 weeks").unwrap(),
add_months(now, 1, false)
now.checked_add_months(Months::new(1))
.unwrap()
.checked_add_days(Days::new(14))
.unwrap()
);
assert_eq!(
parse_relative_time_at_date(now, "1 month and 2 weeks ago").unwrap(),
add_months(now, 1, true)
now.checked_sub_months(Months::new(1))
.unwrap()
.checked_sub_days(Days::new(14))
.unwrap()
@@ -356,7 +348,7 @@ mod tests {
);
assert_eq!(
parse_relative_time_at_date(now, "month").unwrap(),
add_months(now, 1, false).unwrap(),
now.checked_add_months(Months::new(1)).unwrap()
);
}
@@ -570,8 +562,6 @@ mod tests {
#[test]
fn test_duration_parsing() {
use crate::parse_relative_time::add_months;
let now = Utc::now();
assert_eq!(
parse_relative_time_at_date(now, "1 year").unwrap(),
@@ -592,25 +582,25 @@ mod tests {
assert_eq!(
parse_relative_time_at_date(now, "1 month").unwrap(),
add_months(now, 1, false).unwrap(),
now.checked_add_months(Months::new(1)).unwrap()
);
assert_eq!(
parse_relative_time_at_date(now, "1 month and 2 weeks").unwrap(),
add_months(now, 1, false)
now.checked_add_months(Months::new(1))
.unwrap()
.checked_add_days(Days::new(14))
.unwrap()
);
assert_eq!(
parse_relative_time_at_date(now, "1 month, 2 weeks").unwrap(),
add_months(now, 1, false)
now.checked_add_months(Months::new(1))
.unwrap()
.checked_add_days(Days::new(14))
.unwrap()
);
assert_eq!(
parse_relative_time_at_date(now, "1 months 2 weeks").unwrap(),
add_months(now, 1, false)
now.checked_add_months(Months::new(1))
.unwrap()
.checked_add_days(Days::new(14))
.unwrap()
@@ -628,7 +618,7 @@ mod tests {
);
assert_eq!(
parse_relative_time_at_date(now, "month").unwrap(),
add_months(now, 1, false).unwrap(),
now.checked_add_months(Months::new(1)).unwrap()
);
assert_eq!(
+4 -4
View File
@@ -140,7 +140,7 @@ mod tests {
let parsed_time = parse_time_only(get_test_date(), "21:04")
.unwrap()
.timestamp();
assert_eq!(parsed_time, 1709499840);
assert_eq!(parsed_time, 1709499840)
}
#[test]
@@ -187,7 +187,7 @@ mod tests {
let parsed_time = parse_time_only(get_test_date(), "21:04:30")
.unwrap()
.timestamp();
assert_eq!(parsed_time, 1709499870);
assert_eq!(parsed_time, 1709499870)
}
#[test]
@@ -196,7 +196,7 @@ mod tests {
let parsed_time = parse_time_only(get_test_date(), "21:04:30 +0530")
.unwrap()
.timestamp();
assert_eq!(parsed_time, 1709480070);
assert_eq!(parsed_time, 1709480070)
}
#[test]
@@ -205,6 +205,6 @@ mod tests {
let parsed_time = parse_time_only(get_test_date(), "9:04:00 PM")
.unwrap()
.timestamp();
assert_eq!(parsed_time, 1709499840);
assert_eq!(parsed_time, 1709499840)
}
}
+5 -5
View File
@@ -10,7 +10,8 @@ use nom::character::complete::{char, digit1};
use nom::combinator::all_consuming;
use nom::multi::fold_many0;
use nom::sequence::preceded;
use nom::{self, IResult, Parser};
use nom::sequence::tuple;
use nom::{self, IResult};
#[derive(Debug, PartialEq)]
pub enum ParseTimestampError {
@@ -54,7 +55,7 @@ pub(crate) fn parse_timestamp(s: &str) -> Result<i64, ParseTimestampError> {
let res: IResult<&str, (char, &str)> = all_consuming(preceded(
char('@'),
(
tuple((
// Note: to stay compatible with gnu date this code allows
// multiple + and - and only considers the last one
fold_many0(
@@ -66,9 +67,8 @@ pub(crate) fn parse_timestamp(s: &str) -> Result<i64, ParseTimestampError> {
|_, c| c,
),
digit1,
),
))
.parse(s);
)),
))(s);
let (_, (sign, number_str)) = res?;
+5 -6
View File
@@ -4,7 +4,7 @@ use chrono::Weekday;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::combinator::value;
use nom::{self, IResult, Parser};
use nom::{self, IResult};
// Helper macro to simplify tag matching
macro_rules! tag_match {
@@ -25,8 +25,7 @@ pub(crate) fn parse_weekday(s: &str) -> Option<Weekday> {
tag_match!(Weekday::Fri, "friday", "fri"),
tag_match!(Weekday::Sat, "saturday", "sat"),
tag_match!(Weekday::Sun, "sunday", "sun"),
)))
.parse(s);
)))(s);
match parse_result {
Ok((_, weekday)) => Some(weekday),
@@ -64,9 +63,9 @@ mod tests {
for (name, weekday) in days {
assert_eq!(parse_weekday(name), Some(weekday));
assert_eq!(parse_weekday(&format!(" {name}")), Some(weekday));
assert_eq!(parse_weekday(&format!(" {name} ")), Some(weekday));
assert_eq!(parse_weekday(&format!("{name} ")), Some(weekday));
assert_eq!(parse_weekday(&format!(" {}", name)), Some(weekday));
assert_eq!(parse_weekday(&format!(" {} ", name)), Some(weekday));
assert_eq!(parse_weekday(&format!("{} ", name)), Some(weekday));
let (left, right) = name.split_at(1);
let (test_str1, test_str2) = (