3 个版本 (重大变更)
| 0.3.0 | 2023年8月7日 |
|---|---|
| 0.2.0 | 2023年7月9日 |
| 0.1.0 | 2023年6月26日 |
#508 in 日期和时间
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::Duration、chrono::Duration 和 time::Duration 的超集。有关如何轻松处理这些持续时间之间的转换的说明,请参阅 文档!
受众
如果您需要以下内容,这款软件包就适合您:
- 寻找一个快速且精确的与 GNU 兼容的持续时间解析器
- 希望它只需简单配置即可使用,无需进行大量自定义
- 需要相对于儒略格历日期解析持续时间。由于在儒略格历中,年和月并不都是相同长度,因此解析的持续时间是相对于该日期计算的。
- 类似于 GNU 格式
- ...
如果您想要自定义解析器以适应与 gnu 不兼容的格式,那么这款软件包可能不适合您。如果您需要针对您需求的解析器,请参阅主 fundu 项目。
安装
将以下内容添加到 Cargo.toml
[dependencies]
fundu-gnu = "0.3.0"
或者使用以下命令安装:cargo add fundu-gnu。
激活 chrono 或 time 功能将为 chrono::Duration 或 time::Duration 提供 fundu 的 Duration 的 TryFrom 和 SaturatingInto 实现。这些功能还启用了 chrono::DateTime 或 time::OffsetDateTime 的 time::PrimitiveDateTime 的 std::time::Duration 实现。激活 serde 功能允许某些结构体和枚举使用 serde 进行序列化和反序列化。
格式描述
支持的时间单位
seconds、second、secs、secminutes、minute、mins、minhours、hourdays、dayweeks、weekfortnights、fortnight(2 周)months、month(模糊)years、year(模糊)
模糊时间单位长度不均,取决于特定日期。如果在解析时未提供日期,则假定 UTC +0 的系统时间 now。
支持的数量词
下一个(=1)上一个(=-1)这个(=0)first(=1)、third(=3)...、twelfth(=12)(注意缺少的第二个,这是一个时间单位)
特殊关键词 yesterday 值为 -1 天,tomorrow 值为 +1 天,today 和 now 每个都代表零时长,也是允许的。这些关键词计为一个完整时长,不接受数字、时间单位或 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
上述命令不会运行 flamegraph 和 iai-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 许可证(LICENSE 或 https://open-source.org.cn/licenses/MIT)
依赖关系
~0–620KB
~11K SLoC