You've already forked parse_datetime
mirror of
https://github.com/uutils/parse_datetime.git
synced 2026-06-10 16:13:15 -07:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 02e5c22985 | |||
| c6feb9a251 | |||
| 852638fef0 | |||
| 5c34517469 | |||
| 47c5f3620b | |||
| 1e43cc945f | |||
| f9ce5047a5 | |||
| 4c3fd2b1ed | |||
| 9a7f87ac09 | |||
| 0b0aa70193 | |||
| 0c44becec8 | |||
| 64dfea4b47 | |||
| 0bdabd5303 | |||
| 2112830d8b | |||
| 2737b4a0f2 | |||
| f10749eade | |||
| a7380508bc | |||
| 7f0a909752 | |||
| ff0f99bea5 | |||
| dc0d8a3aa0 | |||
| b615effc4e | |||
| cebf55cf82 | |||
| efee20bf01 | |||
| c084001056 | |||
| a35530ed4a | |||
| 6cfcc985a8 | |||
| 497bebb9e7 | |||
| dfd43a6d65 | |||
| 51dd843ded | |||
| c24d593821 | |||
| bed2d16e67 | |||
| 7ab1ad2f0e | |||
| c1a2bef4a6 | |||
| 673d5b600e | |||
| 83e1431db0 | |||
| 80f8fdf883 | |||
| 22bdd8f49c | |||
| dc508c469b | |||
| e503de7559 | |||
| 7ee33d1fb1 | |||
| bc33770075 | |||
| 29e7a5c335 | |||
| 8d797fcbcb | |||
| c177117428 | |||
| e53aabd914 |
@@ -13,7 +13,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
name: cargo fmt --all -- --check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
- { os: macos-latest , features: macos }
|
||||
- { os: windows-latest , features: windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
shell: bash
|
||||
@@ -155,7 +155,7 @@ jobs:
|
||||
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\()"
|
||||
echo "report=${COVERAGE_REPORT_FILE}" >> $GITHUB_OUTPUT
|
||||
- name: Upload coverage results (to Codecov.io)
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
# if: steps.vars.outputs.HAS_CODECOV_TOKEN
|
||||
with:
|
||||
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||
@@ -164,3 +164,21 @@ jobs:
|
||||
flags: ${{ steps.vars.outputs.CODECOV_FLAGS }}
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
|
||||
fuzz:
|
||||
name: Run the fuzzers
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUN_FOR: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- name: Install `cargo-fuzz`
|
||||
run: cargo install cargo-fuzz
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Run from_str for XX seconds
|
||||
shell: bash
|
||||
run: |
|
||||
## Run it
|
||||
cd fuzz
|
||||
cargo +nightly fuzz run fuzz_parse_datetime -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
|
||||
|
||||
Generated
+24
-12
@@ -68,14 +68,6 @@ version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
|
||||
[[package]]
|
||||
name = "humantime_to_duration"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.56"
|
||||
@@ -141,6 +133,14 @@ version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "parse_datetime"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.59"
|
||||
@@ -161,9 +161,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.8.1"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
||||
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9aaecc05d5c4b5f7da074b9a0d1a0867e71fd36e7fc0482d8bcfe8e8fc56290"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -172,9 +184,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.1"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
||||
checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
[package]
|
||||
name = "humantime_to_duration"
|
||||
description = " parsing human-readable relative time strings and converting them to a Duration"
|
||||
version = "0.3.1"
|
||||
name = "parse_datetime"
|
||||
description = "parsing human-readable time strings and converting them to a DateTime"
|
||||
version = "0.5.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/uutils/humantime_to_duration"
|
||||
repository = "https://github.com/uutils/parse_datetime"
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
regex = "1.8"
|
||||
regex = "1.9"
|
||||
chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] }
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# humantime_to_duration
|
||||
# parse_datetime
|
||||
|
||||
[](https://crates.io/crates/humantime_to_duration)
|
||||
[](https://github.com/uutils/humantime_to_duration/blob/main/LICENSE)
|
||||
[](https://codecov.io/gh/uutils/humantime_to_duration)
|
||||
[](https://crates.io/crates/parse_datetime)
|
||||
[](https://github.com/uutils/parse_datetime/blob/main/LICENSE)
|
||||
[](https://codecov.io/gh/uutils/parse_datetime)
|
||||
|
||||
A Rust crate for parsing human-readable relative time strings and converting them to a `Duration`.
|
||||
A Rust crate for parsing human-readable relative time strings and human-readable datetime strings and converting them to a `DateTime`.
|
||||
|
||||
## Features
|
||||
|
||||
- Parses a variety of human-readable time formats.
|
||||
- Parses a variety of human-readable and standard time formats.
|
||||
- Supports positive and negative durations.
|
||||
- Allows for chaining time units (e.g., "1 hour 2 minutes" or "2 days and 2 hours").
|
||||
- Calculate durations relative to a specified date.
|
||||
@@ -20,28 +20,37 @@ Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
humantime_to_duration = "0.3.0"
|
||||
parse_datetime = "0.4.0"
|
||||
```
|
||||
|
||||
Then, import the crate and use the `from_str` and `from_str_at_date` functions:
|
||||
Then, import the crate and use the `parse_datetime_at_date` function:
|
||||
|
||||
```rs
|
||||
use humantime_to_duration::{from_str, from_str_at_date};
|
||||
use chrono::Duration;
|
||||
use chrono::{Duration, Local};
|
||||
use parse_datetime::parse_datetime_at_date;
|
||||
|
||||
let duration = from_str("+3 days");
|
||||
assert_eq!(duration.unwrap(), Duration::days(3));
|
||||
let now = Local::now();
|
||||
let after = parse_datetime_at_date(now, "+3 days");
|
||||
|
||||
let today = Utc::today().naive_utc();
|
||||
let yesterday = today - Duration::days(1);
|
||||
assert_eq!(
|
||||
from_str_at_date(yesterday, "2 days").unwrap(),
|
||||
Duration::days(1)
|
||||
(now + Duration::days(3)).naive_utc(),
|
||||
after.unwrap().naive_utc()
|
||||
);
|
||||
```
|
||||
|
||||
For DateTime parsing, import the `parse_datetime` module:
|
||||
|
||||
```rs
|
||||
use parse_datetime::parse_datetime::from_str;
|
||||
use chrono::{Local, TimeZone};
|
||||
|
||||
let dt = from_str("2021-02-14 06:37:47");
|
||||
assert_eq!(dt.unwrap(), Local.with_ymd_and_hms(2021, 2, 14, 6, 37, 47).unwrap());
|
||||
```
|
||||
|
||||
### Supported Formats
|
||||
|
||||
The `from_str` and `from_str_at_date` functions support the following formats for relative time:
|
||||
The `parse_datetime` and `parse_datetime_at_date` functions support absolute datetime and the following relative times:
|
||||
|
||||
- `num` `unit` (e.g., "-1 hour", "+3 days")
|
||||
- `unit` (e.g., "hour", "day")
|
||||
@@ -49,28 +58,37 @@ The `from_str` and `from_str_at_date` functions support the following formats fo
|
||||
- "yesterday"
|
||||
- "tomorrow"
|
||||
- use "ago" for the past
|
||||
- use "next" or "last" with `unit` (e.g., "next week", "last year")
|
||||
- combined units with "and" or "," (e.g., "2 years and 1 month", "1 day, 2 hours" or "2 weeks 1 second")
|
||||
- unix timestamps (for example "@0" "@1344000")
|
||||
|
||||
`num` can be a positive or negative integer.
|
||||
`unit` can be one of the following: "fortnight", "week", "day", "hour", "minute", "min", "second", "sec" and their plural forms.
|
||||
|
||||
## Return Values
|
||||
|
||||
The `from_str` and `from_str_at_date` functions return:
|
||||
### parse_datetime and parse_datetime_at_date
|
||||
|
||||
- `Ok(Duration)` - If the input string can be parsed as a relative time
|
||||
- `Err(ParseDurationError)` - If the input string cannot be parsed as a relative time
|
||||
The `parse_datetime` and `parse_datetime_at_date` function return:
|
||||
|
||||
This function will return `Err(ParseDurationError::InvalidInput)` if the input string
|
||||
cannot be parsed as a relative time.
|
||||
- `Ok(DateTime<FixedOffset>)` - If the input string can be parsed as a datetime
|
||||
- `Err(ParseDateTimeError::InvalidInput)` - If the input string cannot be parsed
|
||||
|
||||
## Fuzzer
|
||||
|
||||
To run the fuzzer:
|
||||
|
||||
```
|
||||
$ cargo fuzz run fuzz_from_str
|
||||
$ cd fuzz
|
||||
$ cargo install cargo-fuzz
|
||||
$ cargo +nightly fuzz run fuzz_parse_datetime
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT License](LICENSE).
|
||||
|
||||
## Note
|
||||
|
||||
At some point, this crate was called humantime_to_duration.
|
||||
It has been renamed to cover more cases.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
corpus
|
||||
Generated
+30
-38
@@ -67,10 +67,7 @@ checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -81,12 +78,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
|
||||
[[package]]
|
||||
name = "fuzz_from_str"
|
||||
version = "0.1.0"
|
||||
name = "fuzz_parse_datetime"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"humantime_to_duration",
|
||||
"libfuzzer-sys",
|
||||
"parse_datetime",
|
||||
"rand",
|
||||
"regex",
|
||||
]
|
||||
@@ -99,15 +96,7 @@ checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime_to_duration"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"regex",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -176,9 +165,9 @@ checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
version = "2.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
@@ -195,6 +184,14 @@ version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "parse_datetime"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
@@ -251,9 +248,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.8.4"
|
||||
version = "1.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
|
||||
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -262,9 +271,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.2"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
@@ -277,29 +286,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
||||
+8
-8
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "fuzz_from_str"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
name = "fuzz_parse_datetime"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
@@ -9,14 +9,14 @@ cargo-fuzz = true
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
||||
libfuzzer-sys = "0.4"
|
||||
regex = "1.8.4"
|
||||
chrono = "0.4"
|
||||
regex = "1.9.5"
|
||||
chrono = { version="0.4", default-features=false, features=["std", "alloc", "clock"] }
|
||||
|
||||
[dependencies.humantime_to_duration]
|
||||
[dependencies.parse_datetime]
|
||||
path = "../"
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_from_str"
|
||||
path = "fuzz_targets/from_str.rs"
|
||||
name = "fuzz_parse_datetime"
|
||||
path = "fuzz_targets/parse_datetime.rs"
|
||||
test = false
|
||||
doc = false
|
||||
|
||||
@@ -4,5 +4,5 @@ use libfuzzer_sys::fuzz_target;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
let s = std::str::from_utf8(data).unwrap_or("");
|
||||
let _ = humantime_to_duration::from_str(s);
|
||||
let _ = parse_datetime::parse_datetime(s);
|
||||
});
|
||||
+322
-284
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-147
@@ -1,148 +1 @@
|
||||
use chrono::{Duration, Utc};
|
||||
use humantime_to_duration::{from_str, from_str_at_date, ParseDurationError};
|
||||
|
||||
#[test]
|
||||
fn test_invalid_input() {
|
||||
let result = from_str("foobar");
|
||||
println!("{result:?}");
|
||||
assert_eq!(result, Err(ParseDurationError::InvalidInput));
|
||||
|
||||
let result = from_str("invalid 1");
|
||||
assert_eq!(result, Err(ParseDurationError::InvalidInput));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duration_parsing() {
|
||||
assert_eq!(from_str("1 year").unwrap(), Duration::seconds(31_536_000));
|
||||
assert_eq!(
|
||||
from_str("-2 years").unwrap(),
|
||||
Duration::seconds(-63_072_000)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("2 years ago").unwrap(),
|
||||
Duration::seconds(-63_072_000)
|
||||
);
|
||||
assert_eq!(from_str("year").unwrap(), Duration::seconds(31_536_000));
|
||||
|
||||
assert_eq!(from_str("1 month").unwrap(), Duration::seconds(2_592_000));
|
||||
assert_eq!(
|
||||
from_str("1 month and 2 weeks").unwrap(),
|
||||
Duration::seconds(3_801_600)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("1 month, 2 weeks").unwrap(),
|
||||
Duration::seconds(3_801_600)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("1 months 2 weeks").unwrap(),
|
||||
Duration::seconds(3_801_600)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("1 month and 2 weeks ago").unwrap(),
|
||||
Duration::seconds(-3_801_600)
|
||||
);
|
||||
assert_eq!(from_str("2 months").unwrap(), Duration::seconds(5_184_000));
|
||||
assert_eq!(from_str("month").unwrap(), Duration::seconds(2_592_000));
|
||||
|
||||
assert_eq!(
|
||||
from_str("1 fortnight").unwrap(),
|
||||
Duration::seconds(1_209_600)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("3 fortnights").unwrap(),
|
||||
Duration::seconds(3_628_800)
|
||||
);
|
||||
assert_eq!(from_str("fortnight").unwrap(), Duration::seconds(1_209_600));
|
||||
|
||||
assert_eq!(from_str("1 week").unwrap(), Duration::seconds(604_800));
|
||||
assert_eq!(
|
||||
from_str("1 week 3 days").unwrap(),
|
||||
Duration::seconds(864_000)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("1 week 3 days ago").unwrap(),
|
||||
Duration::seconds(-864_000)
|
||||
);
|
||||
assert_eq!(from_str("-2 weeks").unwrap(), Duration::seconds(-1_209_600));
|
||||
assert_eq!(
|
||||
from_str("2 weeks ago").unwrap(),
|
||||
Duration::seconds(-1_209_600)
|
||||
);
|
||||
assert_eq!(from_str("week").unwrap(), Duration::seconds(604_800));
|
||||
|
||||
assert_eq!(from_str("1 day").unwrap(), Duration::seconds(86_400));
|
||||
assert_eq!(from_str("2 days ago").unwrap(), Duration::seconds(-172_800));
|
||||
assert_eq!(from_str("-2 days").unwrap(), Duration::seconds(-172_800));
|
||||
assert_eq!(from_str("day").unwrap(), Duration::seconds(86_400));
|
||||
|
||||
assert_eq!(from_str("1 hour").unwrap(), Duration::seconds(3_600));
|
||||
assert_eq!(from_str("1 h").unwrap(), Duration::seconds(3_600));
|
||||
assert_eq!(from_str("1 hour ago").unwrap(), Duration::seconds(-3_600));
|
||||
assert_eq!(from_str("-2 hours").unwrap(), Duration::seconds(-7_200));
|
||||
assert_eq!(from_str("hour").unwrap(), Duration::seconds(3_600));
|
||||
|
||||
assert_eq!(from_str("1 minute").unwrap(), Duration::seconds(60));
|
||||
assert_eq!(from_str("1 min").unwrap(), Duration::seconds(60));
|
||||
assert_eq!(from_str("2 minutes").unwrap(), Duration::seconds(120));
|
||||
assert_eq!(from_str("2 mins").unwrap(), Duration::seconds(120));
|
||||
assert_eq!(from_str("2m").unwrap(), Duration::seconds(120));
|
||||
assert_eq!(from_str("min").unwrap(), Duration::seconds(60));
|
||||
|
||||
assert_eq!(from_str("1 second").unwrap(), Duration::seconds(1));
|
||||
assert_eq!(from_str("1 s").unwrap(), Duration::seconds(1));
|
||||
assert_eq!(from_str("2 seconds").unwrap(), Duration::seconds(2));
|
||||
assert_eq!(from_str("2 secs").unwrap(), Duration::seconds(2));
|
||||
assert_eq!(from_str("2 sec").unwrap(), Duration::seconds(2));
|
||||
assert_eq!(from_str("sec").unwrap(), Duration::seconds(1));
|
||||
|
||||
assert_eq!(from_str("now").unwrap(), Duration::seconds(0));
|
||||
assert_eq!(from_str("today").unwrap(), Duration::seconds(0));
|
||||
|
||||
assert_eq!(
|
||||
from_str("1 year 2 months 4 weeks 3 days and 2 seconds").unwrap(),
|
||||
Duration::seconds(39_398_402)
|
||||
);
|
||||
assert_eq!(
|
||||
from_str("1 year 2 months 4 weeks 3 days and 2 seconds ago").unwrap(),
|
||||
Duration::seconds(-39_398_402)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_display_parse_duration_error_through_from_str() {
|
||||
let invalid_input = "9223372036854775807 seconds and 1 second";
|
||||
let _ = from_str(invalid_input).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_display_should_fail() {
|
||||
let invalid_input = "Thu Jan 01 12:34:00 2015";
|
||||
let error = from_str(invalid_input).unwrap_err();
|
||||
|
||||
assert_eq!(
|
||||
format!("{error}"),
|
||||
"Invalid input string: cannot be parsed as a relative time"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_at_date_day() {
|
||||
let today = Utc::now().date_naive();
|
||||
let yesterday = today - Duration::days(1);
|
||||
assert_eq!(
|
||||
from_str_at_date(yesterday, "2 days").unwrap(),
|
||||
Duration::days(1)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_input_at_date() {
|
||||
let today = Utc::now().date_naive();
|
||||
let result = from_str_at_date(today, "foobar");
|
||||
println!("{result:?}");
|
||||
assert_eq!(result, Err(ParseDurationError::InvalidInput));
|
||||
|
||||
let result = from_str_at_date(today, "invalid 1r");
|
||||
assert_eq!(result, Err(ParseDurationError::InvalidInput));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user