Expand description
A simple to use, fast and precise gnu relative time parser fully compatible with the gnu relative time format
fundu-gnu can parse rust strings like
&str | Duration |
|---|---|
"1hour" | Duration::positive(60 * 60, 0) |
"minute" | Duration::positive(60, 0) |
"2 hours" | Duration::positive(2 * 60 * 60, 0) |
"-3minutes" | Duration::negative(3 * 60, 0) |
"3 mins ago" | Duration::negative(3 * 60, 0) |
"999sec +1day" | Duration::positive(86_400 + 999, 0) |
"55secs500week" | Duration::positive(55 + 500 * 604_800, 0) |
"123456789" | Duration::positive(123_456_789, 0) |
"42fortnight" | Duration::positive(42 * 2 * 604_800, 0) |
"yesterday" | Duration::negative(24 * 60 * 60, 0) |
"now" | Duration::positive(0, 0) |
"today -10seconds" | Duration::negative(10, 0) |
fundu parses into its own Duration which is a superset of other Durations like
std::time::Duration, chrono::Duration and time::Duration. See the
documentation how to easily
handle the conversion between these durations.
§The Format
Supported time units:
seconds,second,secs,secminutes,minute,mins,minhours,hourdays,dayweeks,weekfortnights,fortnight(2 weeks)months,month(fuzzy)years,year(fuzzy)
Fuzzy time units are not all of equal duration and depend on a given date. If no date is given
when parsing, the system time of now in UTC +0 is assumed.
The special keywords yesterday worth -1 day, tomorrow worth +1 day, today and now
each worth a zero duration are allowed, too. These keywords count as a full duration and don’t
accept a number, time unit or the ago time unit suffix.
Summary of the rest of the format:
- Only numbers like
"123 days"and without exponent (like"3e9 days") are allowed. Only seconds time units allow a fraction (like in"1.123456 secs") - Multiple durations like
"1sec 2min"or"1week2secs"in the source string accumulate - Time units without a number (like in
"second") are allowed and a value of1is assumed. - The parsed duration represents the value exactly (without rounding errors as would occur in floating point calculations) as it is specified in the source string.
- The maximum supported duration (
Duration::MAX) hasu64::MAXseconds (18_446_744_073_709_551_615) and999_999_999nano seconds - parsed durations larger than the maximum duration saturate at the maximum duration
- Negative durations like
"-1min"or"1 week ago"are allowed - Any leading, trailing whitespace or whitespace between the number and the time unit (like in
"1 \n sec") and multiple durations (like in"1week \n 2minutes") is ignored and follows the posix definition of whitespace which is:- Space (
' ') - Horizontal Tab (
'\x09') - Line Feed (
'\x0A') - Vertical Tab (
'\x0B') - Form Feed (
'\x0C') - Carriage Return (
'\x0D')
- Space (
Please see also the gnu documentation for a description of their format.
§Examples
use fundu_gnu::{Duration, RelativeTimeParser};
let parser = RelativeTimeParser::new();
assert_eq!(parser.parse("1hour"), Ok(Duration::positive(60 * 60, 0)));
assert_eq!(parser.parse("minute"), Ok(Duration::positive(60, 0)));
assert_eq!(
parser.parse("2 hours"),
Ok(Duration::positive(2 * 60 * 60, 0))
);
assert_eq!(parser.parse("second"), Ok(Duration::positive(1, 0)));
assert_eq!(parser.parse("-3minutes"), Ok(Duration::negative(3 * 60, 0)));
assert_eq!(
parser.parse("3 mins ago"),
Ok(Duration::negative(3 * 60, 0))
);
assert_eq!(
parser.parse("999sec +1day"),
Ok(Duration::positive(86_400 + 999, 0))
);
assert_eq!(
parser.parse("55secs500week"),
Ok(Duration::positive(55 + 500 * 7 * 24 * 60 * 60, 0))
);
assert_eq!(
parser.parse("300mins20secs 5hour"),
Ok(Duration::positive(300 * 60 + 20 + 5 * 60 * 60, 0))
);
assert_eq!(
parser.parse("123456789"),
Ok(Duration::positive(123_456_789, 0))
);
assert_eq!(
parser.parse("42fortnight"),
Ok(Duration::positive(42 * 2 * 7 * 24 * 60 * 60, 0))
);
assert_eq!(
parser.parse("yesterday"),
Ok(Duration::negative(24 * 60 * 60, 0))
);
assert_eq!(parser.parse("now"), Ok(Duration::positive(0, 0)));
assert_eq!(
parser.parse("today -10seconds"),
Ok(Duration::negative(10, 0))
);If parsing fuzzy units then the fuzz can cause different Duration based on the given
DateTime:
use fundu_gnu::{DateTime, Duration, RelativeTimeParser};
let parser = RelativeTimeParser::new();
let date_time = DateTime::from_gregorian_date_time(1970, 1, 1, 0, 0, 0, 0);
assert_eq!(
parser.parse_with_date("+1year", Some(date_time)),
Ok(Duration::positive(365 * 86400, 0))
);
assert_eq!(
parser.parse_with_date("+2month", Some(date_time)),
Ok(Duration::positive((31 + 28) * 86400, 0))
);
// 1972 is a leap year
let date_time = DateTime::from_gregorian_date_time(1972, 1, 1, 0, 0, 0, 0);
assert_eq!(
parser.parse_with_date("+1year", Some(date_time)),
Ok(Duration::positive(366 * 86400, 0))
);
assert_eq!(
parser.parse_with_date("+2month", Some(date_time)),
Ok(Duration::positive((31 + 29) * 86400, 0))
);If parsing fuzzy units with RelativeTimeParser::parse, the DateTime of now in UTC +0
is assumed.
The global parse method does the same without the need to create a RelativeTimeParser.
use fundu_gnu::{parse, Duration};
assert_eq!(parse("123 sec"), Ok(Duration::positive(123, 0)));
assert_eq!(parse("1sec3min"), Ok(Duration::positive(1 + 3 * 60, 0)));Convert fundu’s Duration into a std::time::Duration. Converting to chrono::Duration or
time::Duration works the same but needs the chrono or time feature activated.
use fundu_gnu::{parse, SaturatingInto};
let duration = parse("123 sec").unwrap();
assert_eq!(
TryInto::<std::time::Duration>::try_into(duration),
Ok(std::time::Duration::new(123, 0))
);
// With saturating_into the duration will saturate at the minimum and maximum of
// std::time::Duration, so for negative values at std::time::Duration::ZERO and for positive values
// at std::time::Duration::MAX
assert_eq!(
SaturatingInto::<std::time::Duration>::saturating_into(duration),
std::time::Duration::new(123, 0)
);Structs§
- Date
Time - Proleptic gregorian date and time with fast calculations of differences in date and time
- Duration
- The duration which is returned by the parser
- Julian
Day - Store a proleptic gregorian date as
JulianDay - Relative
Time Parser - The main gnu relative time parser
Enums§
- Parse
Error - Error type emitted during the parsing
- TryFrom
Duration Error - This error may occur when converting a
crate::time::Durationto a different duration likestd::time::Duration
Traits§
- Saturating
Into - Conversion which saturates at the maximum or maximum instead of overflowing
Functions§
- parse
- Parse the
sourcestring into aDuration - parse_
fuzzy - Parse the
sourcestring extractingyearandmonthtime units from theDuration - parse_
with_ date - Parse the
sourcestring into aDurationrelative to the optionally givendate