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
,sec
minutes
,minute
,mins
,min
hours
,hour
days
,day
weeks
,week
fortnights
,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 of1
is 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::MAX
seconds (18_446_744_073_709_551_615
) and999_999_999
nano 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
- Proleptic gregorian date and time with fast calculations of differences in date and time
- The duration which is returned by the parser
- Store a proleptic gregorian date as
JulianDay
- The main gnu relative time parser
Enums
- Error type emitted during the parsing
- This error may occur when converting a
crate::time::Duration
to a different duration likestd::time::Duration
Traits
- Conversion which saturates at the maximum or maximum instead of overflowing
Functions
- Parse the
source
string into aDuration