25 Commits

Author SHA1 Message Date
Daniel Hofstetter 6462d410d8 Merge pull request #248 from cakebaker/bump_version_to_0_13_3
chore: bump version to `0.13.3`
2025-11-21 10:12:43 +01:00
Daniel Hofstetter 92d095b53b chore: bump version to 0.13.3 2025-11-21 09:52:19 +01:00
Daniel Hofstetter ea143af391 Merge pull request #247 from cakebaker/bump_dependencies
chore: update dependencies
2025-11-21 09:49:15 +01:00
Daniel Hofstetter 835e46e6f1 chore: update dependencies 2025-11-21 09:44:58 +01:00
Daniel Hofstetter 31b8e58cc5 Merge pull request #246 from 3v1n0/fix-parsing-relative-times
relative: Support parsing floating relative values with spaces
2025-11-21 09:16:18 +01:00
Daniel Hofstetter 9de30f5fc3 Merge pull request #245 from uutils/renovate/actions-checkout-6.x
chore(deps): update actions/checkout action to v6
2025-11-21 06:58:39 +01:00
Marco Trevisan (Treviño) d6ab892c29 relative: Add more tests for parsing signed values with spaces 2025-11-21 06:37:09 +01:00
Marco Trevisan (Treviño) 1e4fc30f7b relative: Support parsing floating relative values with spaces
In case a string such as "now + 1.5 seconds" was parsed we were failing.

This happened because after processing now, the parser was getting
to the point in which the string contained "+ 1.5", and once the sign
was processed, the remaining " 1.5" string conained a space that was
causing sec_and_nsec to fail.

Instead of failing at this point, just strip the spaces after the sign has
been processed.

Note in fact that "0+0.0 seconds" was working fine

Closes: https://github.com/uutils/coreutils/issues/8618
2025-11-21 06:37:09 +01:00
renovate[bot] 6ce151fb58 chore(deps): update actions/checkout action to v6 2025-11-20 18:43:38 +00:00
Daniel Hofstetter 9f6605f20d Merge pull request #244 from cakebaker/bump_version_to_0_13_2
chore: bump version to `0.13.2`
2025-11-09 18:27:31 +01:00
Daniel Hofstetter a025a04d72 chore: bump version to 0.13.2 2025-11-09 17:49:27 +01:00
Sylvestre Ledru dbae631ff0 Merge pull request #241 from cakebaker/literal3
feat: support formats `Nov-14-2024` and `November-14-2024`
2025-11-09 15:03:15 +01:00
Daniel Hofstetter 83278f0ddc Merge pull request #243 from uutils/renovate/jiff-0.x-lockfile
chore(deps): update rust crate jiff to v0.2.16
2025-11-07 17:39:07 +01:00
renovate[bot] ae518cac37 chore(deps): update rust crate jiff to v0.2.16 2025-11-07 15:41:39 +00:00
Daniel Hofstetter bc5d201b68 Merge pull request #242 from cakebaker/update_dependencies
chore: update dependencies
2025-10-30 09:29:46 +01:00
Daniel Hofstetter 8c56c5cb13 chore: update dependencies 2025-10-29 11:13:04 +01:00
Daniel Hofstetter 9c95c9549b feat: support formats Nov-14-2024/November-14-2024 2025-10-29 10:40:22 +01:00
Daniel Hofstetter ba69fb8772 Merge pull request #239 from cakebaker/bump_version_to_0_13_1
chore: bump version to 0.13.1
2025-10-04 17:27:00 +02:00
Daniel Hofstetter 912bc4e706 chore: bump version to 0.13.1 2025-10-04 17:19:18 +02:00
Daniel Hofstetter c239ed0b36 Merge pull request #238 from stillbeingnick/bugfix/issue/coreutils-date-invalid
Changing ErrMode::Cut to ErrMode::Backtrack to allow alt parser flow (Fix for uutils/coreutils issue 8754)
2025-10-04 17:00:00 +02:00
Nicholas Still 3074fe3baa Change ErrMode::Cut to ErrMode::Backtrack to allow alt parser flow 2025-10-04 16:55:43 +02:00
Daniel Hofstetter 29e368662c Merge pull request #237 from yuankunzhang/add-comments-for-build-function
docs: add comments for the build function
2025-09-28 15:21:47 +02:00
yuankunzhang 1e757df39b docs: add comments for the build function 2025-09-27 21:34:09 +08:00
Daniel Hofstetter 7a32b1ee3d Merge pull request #236 from yuankunzhang/remove-regex-dependency
chore: remove regex crate as dependency
2025-09-27 14:29:14 +02:00
yuankunzhang c898cd84de chore: remove regex crate as dependency 2025-09-27 20:10:25 +08:00
9 changed files with 307 additions and 328 deletions
+7 -7
View File
@@ -14,7 +14,7 @@ jobs:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo check
@@ -25,7 +25,7 @@ jobs:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo test
@@ -33,7 +33,7 @@ jobs:
name: cargo fmt --all -- --check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: rustup component add rustfmt
- run: cargo fmt --all -- --check
@@ -45,7 +45,7 @@ jobs:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: rustup component add clippy
- run: cargo clippy --all-targets -- -D warnings
@@ -57,7 +57,7 @@ jobs:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.RUST_MIN_SRV }}
@@ -74,7 +74,7 @@ jobs:
- { os: macos-latest , features: macos }
- { os: windows-latest , features: windows }
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Initialize workflow variables
id: vars
shell: bash
@@ -152,7 +152,7 @@ jobs:
env:
RUN_FOR: 60
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
- name: Install `cargo-fuzz`
run: cargo install cargo-fuzz
Generated
+64 -119
View File
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
@@ -19,9 +19,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "cfg-if"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "equivalent"
@@ -80,15 +80,15 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "hashbrown"
version = "0.15.5"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "indexmap"
version = "2.11.1"
version = "2.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
"hashbrown",
@@ -96,24 +96,24 @@ dependencies = [
[[package]]
name = "jiff"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
"serde_core",
"windows-sys",
]
[[package]]
name = "jiff-static"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69"
dependencies = [
"proc-macro2",
"quote",
@@ -143,9 +143,9 @@ checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "memchr"
version = "2.7.5"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "num-traits"
@@ -158,11 +158,10 @@ dependencies = [
[[package]]
name = "parse_datetime"
version = "0.13.0"
version = "0.13.3"
dependencies = [
"jiff",
"num-traits",
"regex",
"rstest",
"winnow",
]
@@ -196,36 +195,36 @@ dependencies = [
[[package]]
name = "proc-macro-crate"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.3"
version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [
"aho-corasick",
"memchr",
@@ -235,9 +234,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.11"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad"
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [
"aho-corasick",
"memchr",
@@ -246,9 +245,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.6"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]]
name = "relative-path"
@@ -296,33 +295,24 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.26"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
[[package]]
name = "serde"
version = "1.0.221"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "341877e04a22458705eb4e131a1508483c877dca2792b3781d4e5d8a6019ec43"
dependencies = [
"serde_core",
]
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde_core"
version = "1.0.221"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c459bc0a14c840cb403fc14b148620de1e0778c96ecd6e0c8c3cacb6d8d00fe"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.221"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6185cf75117e20e62b1ff867b9518577271e58abe0037c40bb4794969355ab0"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
@@ -337,9 +327,9 @@ checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
[[package]]
name = "syn"
version = "2.0.106"
version = "2.0.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
dependencies = [
"proc-macro2",
"quote",
@@ -348,100 +338,55 @@ dependencies = [
[[package]]
name = "toml_datetime"
version = "0.6.11"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
checksum = "a197c0ec7d131bfc6f7e82c8442ba1595aeab35da7adbf05b6b73cd06a16b6be"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
version = "0.23.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
checksum = "c2ad0b7ae9cfeef5605163839cb9221f453399f15cfb5c10be9885fcf56611f9"
dependencies = [
"indexmap",
"toml_datetime",
"toml_parser",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
dependencies = [
"winnow",
]
[[package]]
name = "unicode-ident"
version = "1.0.19"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.59.0"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-targets",
"windows-link",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[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.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[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.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[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.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.13"
+1 -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.13.0"
version = "0.13.3"
edition = "2021"
license = "MIT"
repository = "https://github.com/uutils/parse_datetime"
@@ -9,7 +9,6 @@ readme = "README.md"
rust-version = "1.71.1"
[dependencies]
regex = "1.10.4"
winnow = "0.7.10"
num-traits = "0.2.19"
jiff = { version = "0.2.15", default-features = false, features = ["tz-system", "tzdb-bundle-platform", "tzdb-zoneinfo"] }
+44 -159
View File
@@ -2,15 +2,6 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "arbitrary"
version = "1.4.2"
@@ -25,9 +16,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "cc"
version = "1.2.37"
version = "1.2.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -37,15 +28,15 @@ dependencies = [
[[package]]
name = "cfg-if"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "find-msvc-tools"
version = "0.1.1"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
[[package]]
name = "fuzz_parse_datetime"
@@ -57,36 +48,36 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.3.3"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
"wasip2",
]
[[package]]
name = "jiff"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
"serde_core",
"windows-sys",
]
[[package]]
name = "jiff-static"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69"
dependencies = [
"proc-macro2",
"quote",
@@ -120,9 +111,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.175"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "libfuzzer-sys"
@@ -142,9 +133,9 @@ checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "memchr"
version = "2.7.5"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "num-traits"
@@ -157,11 +148,10 @@ dependencies = [
[[package]]
name = "parse_datetime"
version = "0.11.0"
version = "0.13.2"
dependencies = [
"jiff",
"num-traits",
"regex",
"winnow",
]
@@ -182,18 +172,18 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.101"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
@@ -204,58 +194,20 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "regex"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "serde"
version = "1.0.221"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "341877e04a22458705eb4e131a1508483c877dca2792b3781d4e5d8a6019ec43"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.221"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c459bc0a14c840cb403fc14b148620de1e0778c96ecd6e0c8c3cacb6d8d00fe"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.221"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6185cf75117e20e62b1ff867b9518577271e58abe0037c40bb4794969355ab0"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
@@ -270,9 +222,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.106"
version = "2.0.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
dependencies = [
"proc-macro2",
"quote",
@@ -281,101 +233,34 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.19"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "wasi"
version = "0.14.5+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4"
dependencies = [
"wasip2",
]
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "wasip2"
version = "1.0.0+wasi-0.2.4"
version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.59.0"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-targets",
"windows-link",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[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.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[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.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[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.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.13"
@@ -387,6 +272,6 @@ dependencies = [
[[package]]
name = "wit-bindgen"
version = "0.45.1"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+58 -27
View File
@@ -160,31 +160,59 @@ impl DateTimeBuilder {
self.set_time(time)
}
/// Build a `Zoned` object from the pieces accumulated in this builder.
///
/// Resolution order (mirrors GNU `date` semantics):
///
/// 1. Base instant.
/// - a. If `self.base` is provided, start with it.
/// - b. Else if a `timezone` rule is present, start with "now" in that
/// timezone.
/// - c. Else start with current system local time.
///
/// 2. Absolute timestamp override.
/// - a. If `self.timestamp` is set, it fully determines the result.
///
/// 3. Time of day truncation.
/// - a. If any of date, time, weekday, offset, timezone is set, zero the
/// time of day to 00:00:00 before applying fields.
///
/// 4. Fieldwise resolution (applied to the base instant).
/// - a. Apply date. If year is absent in the parsed date, inherit the year
/// from the base instant.
/// - b. Apply time. If time carries an explicit numeric offset, apply the
/// offset before setting time.
/// - c. Apply weekday (e.g., "next Friday" or "last Monday").
/// - d. Apply relative adjustments (e.g., "+3 days", "-2 months").
/// - e. Apply final fixed offset if present.
pub(super) fn build(self) -> Result<Zoned, error::Error> {
let base = self.base.unwrap_or(if let Some(tz) = &self.timezone {
jiff::Timestamp::now().to_zoned(tz.clone())
} else {
Zoned::now()
});
// If a timestamp is set, we use it to build the `Zoned` object.
if let Some(ts) = self.timestamp {
return Ok(jiff::Timestamp::try_from(ts)?.to_zoned(base.offset().to_time_zone()));
}
// If any of the following items are set, we truncate the time portion
// of the base date to zero; otherwise, we use the base date as is.
let mut dt = if self.date.is_none()
&& self.time.is_none()
&& self.weekday.is_none()
&& self.offset.is_none()
&& self.timezone.is_none()
{
base
} else {
base.with().time(civil::time(0, 0, 0, 0)).build()?
// 1. Choose the base instant.
let base = match (self.base, &self.timezone) {
(Some(b), _) => b,
(None, Some(tz)) => jiff::Timestamp::now().to_zoned(tz.clone()),
(None, None) => Zoned::now(),
};
// 2. Absolute timestamp override everything else.
if let Some(ts) = self.timestamp {
let ts = jiff::Timestamp::try_from(ts)?;
return Ok(ts.to_zoned(base.offset().to_time_zone()));
}
// 3. Determine whether to truncate the time of day.
let need_midnight = self.date.is_some()
|| self.time.is_some()
|| self.weekday.is_some()
|| self.offset.is_some()
|| self.timezone.is_some();
let mut dt = if need_midnight {
base.with().time(civil::time(0, 0, 0, 0)).build()?
} else {
base
};
// 4a. Apply date.
if let Some(date) = self.date {
let d: civil::Date = if date.year.is_some() {
date.try_into()?
@@ -194,6 +222,7 @@ impl DateTimeBuilder {
dt = dt.with().date(d).build()?;
}
// 4b. Apply time.
if let Some(time) = self.time.clone() {
if let Some(offset) = &time.offset {
dt = dt.datetime().to_zoned(offset.try_into()?)?;
@@ -203,13 +232,13 @@ impl DateTimeBuilder {
dt = dt.with().time(t).build()?;
}
if let Some(weekday::Weekday { offset, day }) = self.weekday {
// 4c. Apply weekday.
if let Some(weekday::Weekday { mut offset, day }) = self.weekday {
if self.time.is_none() {
dt = dt.with().time(civil::time(0, 0, 0, 0)).build()?;
}
let mut offset = offset;
let day = day.into();
let target = day.into();
// If the current day is not the target day, we need to adjust
// the x value to ensure we find the correct day.
@@ -217,7 +246,7 @@ impl DateTimeBuilder {
// Consider this:
// Assuming today is Monday, next Friday is actually THIS Friday;
// but next Monday is indeed NEXT Monday.
if dt.date().weekday() != day && offset > 0 {
if dt.date().weekday() != target && offset > 0 {
offset -= 1;
}
@@ -237,7 +266,7 @@ impl DateTimeBuilder {
//
// Example 4: next Thursday (x = 1, day = Thursday)
// delta = (3 - 3) % 7 + (1) * 7 = 7
let delta = (day.since(civil::Weekday::Monday) as i32
let delta = (target.since(civil::Weekday::Monday) as i32
- dt.date().weekday().since(civil::Weekday::Monday) as i32)
.rem_euclid(7)
+ offset.checked_mul(7).ok_or("multiplication overflow")?;
@@ -245,6 +274,7 @@ impl DateTimeBuilder {
dt = dt.checked_add(Span::new().try_days(delta)?)?;
}
// 4d. Apply relative adjustments.
for rel in self.relative {
dt = dt.checked_add::<Span>(if let relative::Relative::Months(x) = rel {
// *NOTE* This is done in this way to conform to GNU behavior.
@@ -255,6 +285,7 @@ impl DateTimeBuilder {
})?;
}
// 4e. Apply final fixed offset.
if let Some(offset) = self.offset {
let (offset, hour_adjustment) = offset.normalize();
dt = dt.checked_add(Span::new().hours(hour_adjustment))?;
+48 -12
View File
@@ -128,7 +128,7 @@ impl TryFrom<Date> for jiff::civil::Date {
}
pub(super) fn parse(input: &mut &str) -> ModalResult<Date> {
alt((iso1, iso2, us, literal1, literal2)).parse_next(input)
alt((iso1, iso2, us, literal1, literal2, literal3)).parse_next(input)
}
/// Parse `[year]-[month]-[day]`
@@ -138,9 +138,10 @@ pub(super) fn iso1(input: &mut &str) -> ModalResult<Date> {
let (year, _, month, _, day) =
(year_str, s('-'), s(dec_uint), s('-'), s(dec_uint)).parse_next(input)?;
// Map err to Backtrack instead of Cut to avoid early termination of parsing
(year, month, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e)))
.map_err(|e| ErrMode::Backtrack(ctx_err(e)))
}
/// Parse `[year][month][day]`
@@ -156,7 +157,7 @@ pub(super) fn iso2(input: &mut &str) -> ModalResult<Date> {
(year, month, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e)))
.map_err(|e| ErrMode::Backtrack(ctx_err(e)))
}
/// Parse `[year]/[month]/[day]` or `[month]/[day]/[year]` or `[month]/[day]`.
@@ -178,19 +179,21 @@ fn us(input: &mut &str) -> ModalResult<Date> {
let day = day_from_str(s2)?;
(s1, n, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e)))
.map_err(|e| ErrMode::Backtrack(ctx_err(e)))
}
Some(s2) => {
// [month]/[day]/[year]
let month = month_from_str(s1)?;
(s2, month, n)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e)))
.map_err(|e| ErrMode::Backtrack(ctx_err(e)))
}
None => {
// [month]/[day]
let month = month_from_str(s1)?;
(month, n).try_into().map_err(|e| ErrMode::Cut(ctx_err(e)))
(month, n)
.try_into()
.map_err(|e| ErrMode::Backtrack(ctx_err(e)))
}
}
}
@@ -213,10 +216,10 @@ fn literal1(input: &mut &str) -> ModalResult<Date> {
match year {
Some(year) => (year, month, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e))),
.map_err(|e| ErrMode::Backtrack(ctx_err(e))),
None => (month, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e))),
.map_err(|e| ErrMode::Backtrack(ctx_err(e))),
}
}
@@ -242,13 +245,25 @@ fn literal2(input: &mut &str) -> ModalResult<Date> {
match year {
Some(year) => (year, month, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e))),
.map_err(|e| ErrMode::Backtrack(ctx_err(e))),
None => (month, day)
.try_into()
.map_err(|e| ErrMode::Cut(ctx_err(e))),
.map_err(|e| ErrMode::Backtrack(ctx_err(e))),
}
}
/// Parse `November-14-2022` and `Nov-14-2022`. Unlike `literal2`, the year is mandatory
/// to match the behavior of GNU `date`.
fn literal3(input: &mut &str) -> ModalResult<Date> {
let (month, _, day, _, year) =
(s(literal_month), s('-'), s(dec_uint), s('-'), year_str).parse_next(input)?;
// Map err to Backtrack instead of Cut to avoid early termination of parsing
(year, month, day)
.try_into()
.map_err(|e| ErrMode::Backtrack(ctx_err(e)))
}
/// Parse the name of a month (case-insensitive)
fn literal_month(input: &mut &str) -> ModalResult<u8> {
s(alpha1)
@@ -274,12 +289,12 @@ fn literal_month(input: &mut &str) -> ModalResult<u8> {
fn month_from_str(s: &str) -> ModalResult<u8> {
s.parse::<u8>()
.map_err(|_| ErrMode::Cut(ctx_err("month must be a valid u8 number")))
.map_err(|_| ErrMode::Backtrack(ctx_err("month must be a valid u8 number")))
}
fn day_from_str(s: &str) -> ModalResult<u8> {
s.parse::<u8>()
.map_err(|_| ErrMode::Cut(ctx_err("day must be a valid u8 number")))
.map_err(|_| ErrMode::Backtrack(ctx_err("day must be a valid u8 number")))
}
#[cfg(test)]
@@ -546,6 +561,27 @@ mod tests {
assert_eq!(s, ", 2022a");
}
#[test]
fn literal3() {
let reference = Date {
year: Some(2022),
month: 11,
day: 14,
};
for mut s in [
"november-14-2022",
"november----14----2022",
"november - 14 - 2022",
"nov-14-2022",
"nov---14---2022",
"nov - 14 - 2022",
] {
let old_s = s.to_owned();
assert_eq!(parse(&mut s).unwrap(), reference, "Format string: {old_s}");
}
}
#[test]
fn with_year() {
let reference = Date {
+15 -2
View File
@@ -83,7 +83,7 @@ pub(super) fn parse(input: &mut &str) -> ModalResult<Relative> {
fn seconds(input: &mut &str) -> ModalResult<Relative> {
(
opt(alt((s('+').value(1), s('-').value(-1)))),
sec_and_nsec,
s(sec_and_nsec),
s(alpha1).verify(|s: &str| matches!(s, "seconds" | "second" | "sec" | "secs")),
ago,
)
@@ -138,11 +138,13 @@ mod tests {
("secs", Relative::Seconds(1, 0)),
("second ago", Relative::Seconds(-1, 0)),
("3 seconds", Relative::Seconds(3, 0)),
("+ 3 seconds", Relative::Seconds(3, 0)),
("3.5 seconds", Relative::Seconds(3, 500_000_000)),
("-3.5 seconds", Relative::Seconds(-4, 500_000_000)),
("+3.5 seconds", Relative::Seconds(3, 500_000_000)),
("+ 3.5 seconds", Relative::Seconds(3, 500_000_000)),
("3.5 seconds ago", Relative::Seconds(-4, 500_000_000)),
("-3.5 seconds ago", Relative::Seconds(3, 500_000_000)),
("- 3.5 seconds ago", Relative::Seconds(3, 500_000_000)),
// Minutes
("minute", Relative::Minutes(1)),
("minutes", Relative::Minutes(1)),
@@ -150,29 +152,40 @@ mod tests {
("mins", Relative::Minutes(1)),
("10 minutes", Relative::Minutes(10)),
("-10 minutes", Relative::Minutes(-10)),
("- 10 minutes", Relative::Minutes(-10)),
("10 minutes ago", Relative::Minutes(-10)),
("-10 minutes ago", Relative::Minutes(10)),
("- 10 minutes ago", Relative::Minutes(10)),
("-10 minutes ago", Relative::Minutes(10)),
("- 10 minutes ago", Relative::Minutes(10)),
// Hours
("hour", Relative::Hours(1)),
("hours", Relative::Hours(1)),
("10 hours", Relative::Hours(10)),
("+10 hours", Relative::Hours(10)),
("+ 10 hours", Relative::Hours(10)),
("-10 hours", Relative::Hours(-10)),
("- 10 hours", Relative::Hours(-10)),
("10 hours ago", Relative::Hours(-10)),
("-10 hours ago", Relative::Hours(10)),
("- 10 hours ago", Relative::Hours(10)),
// Days
("day", Relative::Days(1)),
("days", Relative::Days(1)),
("10 days", Relative::Days(10)),
("+10 days", Relative::Days(10)),
("+ 10 days", Relative::Days(10)),
("-10 days", Relative::Days(-10)),
("- 10 days", Relative::Days(-10)),
("10 days ago", Relative::Days(-10)),
("-10 days ago", Relative::Days(10)),
("- 10 days ago", Relative::Days(10)),
// Multiple days
("fortnight", Relative::Days(14)),
("fortnights", Relative::Days(14)),
("2 fortnights ago", Relative::Days(-28)),
("+2 fortnights ago", Relative::Days(-28)),
("+ 2 fortnights ago", Relative::Days(-28)),
("week", Relative::Days(7)),
("weeks", Relative::Days(7)),
("2 weeks ago", Relative::Days(-14)),
+36
View File
@@ -307,6 +307,42 @@ mod tests {
assert!(parse_datetime(relative_time).is_ok());
}
}
#[test]
fn integer_seconds_offset() {
let dt = "0 + 0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn integer_seconds_offset_spaceless() {
let dt = "0+0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset() {
let dt = "0 + 0.0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset_spaceless() {
let dt = "0+0.0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset_from_now() {
let dt = "now + 1.5 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset_from_tomorrow_spaceless() {
let dt = "tomorrow+1.5 seconds";
assert!(parse_datetime(dt).is_ok());
}
}
#[cfg(test)]
+34
View File
@@ -128,3 +128,37 @@ fn test_time_invalid(#[case] input: &str) {
"Input string '{input}' did not produce an error when parsing"
);
}
#[rstest]
#[case::decimal_1_whole("1.123456789 seconds ago")]
#[case::decimal_2_whole("12.123456789 seconds ago")]
#[case::decimal_3_whole("123.123456789 seconds ago")]
#[case::decimal_4_whole("1234.123456789 seconds ago")]
#[case::decimal_5_whole("12345.123456789 seconds ago")]
#[case::decimal_6_whole("123456.123456789 seconds ago")]
#[case::decimal_7_whole("1234567.123456789 seconds ago")]
#[case::decimal_8_whole("12345678.123456789 seconds ago")]
#[case::decimal_9_whole("123456789.123456789 seconds ago")]
#[case::decimal_10_whole("1234567891.123456789 seconds ago")]
#[case::decimal_11_whole("12345678912.123456789 seconds ago")]
#[case::decimal_12_whole("123456789123.123456789 seconds ago")]
fn test_time_seconds_ago(#[case] input: &str) {
let result = parse_datetime::parse_datetime(input);
assert!(
result.is_ok(),
"Input string '{input}', produced {result:?}, instead of Ok(Zoned)"
);
}
#[rstest]
#[case::decimal_13_whole("1234567891234.123456789 seconds ago")]
#[case::decimal_14_whole("12345678912345.123456789 seconds ago")]
#[case::decimal_15_whole("123456789123456.123456789 seconds ago")]
fn test_time_seconds_ago_invalid(#[case] input: &str) {
let result = parse_datetime::parse_datetime(input);
assert_eq!(
result,
Err(parse_datetime::ParseDateTimeError::InvalidInput),
"Input string '{input}' did not produce an error when parsing"
);
}