#time-parser #duration #parse-duration #duration-parser #gnu #parse #parser

fundu-gnu

快速精确的 Rust 字符串到 Duration 的 gnu 相对时间解析器

3 个版本 (重大变更)

0.3.0 2023年8月7日
0.2.0 2023年7月9日
0.1.0 2023年6月26日

#508 in 日期和时间

MIT 许可证

320KB
5.5K SLoC

快速精确的 Rust 字符串到 Duration 的 gnu 相对时间解析器


目录

概述

此crate提供了一个简单易用且快速的基于 fundu 的解析器,旨在与 gnu 日期字符串格式中的相对项完全兼容,如其在 文档 中指定。

fundu-gnu 可以使用 RelativeTimeParser::parse 和其他或全局的 parse 方法解析 Rust 字符串

&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 解析为它自己的 Duration,这是其他 Durations,如 std::time::Durationchrono::Durationtime::Duration 的超集。有关如何轻松处理这些持续时间之间的转换的说明,请参阅 文档

受众

如果您需要以下内容,这款软件包就适合您:

  • 寻找一个快速且精确的与 GNU 兼容的持续时间解析器
  • 希望它只需简单配置即可使用,无需进行大量自定义
  • 需要相对于儒略格历日期解析持续时间。由于在儒略格历中,年和月并不都是相同长度,因此解析的持续时间是相对于该日期计算的。
  • 类似于 GNU 格式
  • ...

如果您想要自定义解析器以适应与 gnu 不兼容的格式,那么这款软件包可能不适合您。如果您需要针对您需求的解析器,请参阅主 fundu 项目。

安装

将以下内容添加到 Cargo.toml

[dependencies]
fundu-gnu = "0.3.0"

或者使用以下命令安装:cargo add fundu-gnu

激活 chronotime 功能将为 chrono::Durationtime::Duration 提供 fundu 的 DurationTryFromSaturatingInto 实现。这些功能还启用了 chrono::DateTimetime::OffsetDateTimetime::PrimitiveDateTimestd::time::Duration 实现。激活 serde 功能允许某些结构体和枚举使用 serde 进行序列化和反序列化。

格式描述

支持的时间单位

  • secondssecondsecssec
  • minutesminuteminsmin
  • hourshour
  • daysday
  • weeksweek
  • fortnightsfortnight(2 周)
  • monthsmonth(模糊)
  • yearsyear(模糊)

模糊时间单位长度不均,取决于特定日期。如果在解析时未提供日期,则假定 UTC +0 的系统时间 now

支持的数量词

  • 下一个 (=1)
  • 上一个 (=-1)
  • 这个 (=0)
  • first(=1)、third(=3)...、twelfth(=12)(注意缺少的第二个,这是一个时间单位)

特殊关键词 yesterday 值为 -1tomorrow 值为 +1todaynow 每个都代表零时长,也是允许的。这些关键词计为一个完整时长,不接受数字、时间单位或 ago 时间单位后缀。

格式的其余部分摘要

  • 时间单位、关键词(包括 ago)和数字均不区分大小写
  • 只允许像 "123 days" 这样的数字以及没有指数(如 "3e9 days")的情况。只有秒时间单位允许分数(如 "1.123456 secs"
  • 在源字符串中,多个时长如 "1sec 2min""1week2secs" 会累积
  • 允许没有数字的时间单位(如 "second"),默认值为 1
  • 解析的时长代表源字符串中指定的值(没有四舍五入错误,如浮点运算中可能出现的错误)
  • 支持的最大时长(Duration::MAX)为 u64::MAX 秒(18_446_744_073_709_551_615)和 999_999_999 纳秒
  • 大于最大时长的解析时长将饱和于最大时长
  • 允许负时长,如 "-1min""1 week ago"
  • 任何前导、尾随空白或数字和时间单位之间的空白(如 "1 \n sec")和多个时长(如 "1week \n 2minutes")都将被忽略,并遵循 POSIX 对空白的定义,即
    • 空格(' '
    • 水平制表符('\x09'
    • 换行符('\x0A'
    • 垂直制表符('\x0B'
    • 换页符('\x0C'
    • 回车符('\x0D'

请参阅 GNU 的文档以了解它们的格式说明。

基准测试

要在您的机器上运行基准测试,请克隆仓库

git clone https://github.com/fundu-rs/fundu.git
cd fundu

然后使用以下命令运行 fundu-gnu 基准测试

cargo bench --package fundu-gnu

上述命令不会运行 flamegraphiai-callgrind 基准测试。

iai-callgrind(功能 = with-iai)和 flamegraph(功能 = with-flamegraph)基准测试只能在 Unix 上运行。使用 cargo 的 --features 选项运行具有这些功能的基准测试。

为了大致了解解析时间,以下是一些输入的平均解析速度(四核 3000MHz,8GB DDR3,Linux)

输入 平均解析时间
1 49.399ns
123456789 57.108ns
"1".重复(1022) 253.89ns
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
1年 164.30ns
10000000年 182.85ns
1秒 1分钟 167.74ns
1秒 1分钟 1秒 1分钟 325.70ns
1秒 1分钟 1小时 1天 353.18ns
"1秒 1分钟".重复(100) 15.258µs

解析模糊时间单位(如 1年10000000年)会增加相当数量的额外计算,但仍然相对较快。

许可证

MIT 许可证(LICENSEhttp://opensource.org/licenses/MIT

依赖关系

~0–620KB
~11K SLoC