Table of Contents
Overview
This crate provides a simple to use and fast parser based on fundu aiming for full compatibility with gnu relative items in date strings format as specified in their documentation.
fundu-gnu can parse rust strings with RelativeTimeParser::parse and others or the global parse
method:
&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. For examples and further documentation see the
docs!
Audience
This crate is for you if you
- seek a fast and precise gnu compatible duration parser
- want it to simply just work without diving into many customizations
- need to parse a duration relative to a proleptic gregorian date. Since years and months are not all of equal length in the gregorian calendar, the parsed duration is calculated relative to that date.
- just like the gnu format
- ...
This crate might not be for you if you want to customize the parser to a format which would not be
compatible with gnu. See the main fundu project, if you want to use a parser
tailored to your needs.
Installation
Add this to Cargo.toml
[]
= "0.3.1"
or install with cargo add fundu-gnu.
Activating the chrono or time feature provides a TryFrom and SaturatingInto implementation
of fundu's Duration for chrono::Duration or time::Duration. These features also enable a
From implementation of chrono::DateTime or time::OffsetDateTime,
time::PrimitiveDateTime for fundu-gnu's DateTime. Converting from/to std::time::Duration
does not require an additional feature. Activating the serde feature allows some structs and enums
to be serialized or deserialized with serde
Description of 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.
Supported numerals:
next(=1)last(=-1)this(=0)first(=1),third(=3), ... ,twelfth(=12) (Note the missing second which is a time unit)
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:
- Time units, keywords (including
ago) and numerals are case insensitive - 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.
Benchmarks
To run the benchmarks on your machine, clone the repository
git clone https://github.com/fundu-rs/fundu.git
cd fundu
and then run the fundu-gnu benchmarks with
cargo bench --package fundu-gnu
The above won't run the flamegraph and iai-callgrind benchmarks.
The iai-callgrind (feature = with-iai) and flamegraph (feature = with-flamegraph) benchmarks
can only be run on unix. Use the --features option of cargo to run the benchmarks with these
features.
To get a rough idea about the parsing times, here the average parsing speed of some inputs (Quad core 3000Mhz, 8GB DDR3, Linux):
| Input | avg parsing time |
|---|---|
1 |
49.399 ns |
123456789 |
57.108 ns |
"1".repeat(1022) |
253.89 ns |
sec / 1sec / seconds / 1seconds |
63.521 / 81.871 / 74.962 / 97.785 ns |
min / 1min / minutes / 1minutes |
64.102 / 82.876 / 77.893 / 98.374 ns |
1year |
164.30 ns |
10000000year |
182.85 ns |
1sec 1min |
167.74 ns |
1sec 1min 1sec 1min |
325.70 ns |
1sec 1min 1hour 1day |
353.18 ns |
"1sec 1min".repeat(100) |
15.258 µs |
Parsing of fuzzy time units like in 1year or 10000000year adds a considerable amount of
additional computations but is still comparably fast.
License
MIT license (LICENSE or http://opensource.org/licenses/MIT)