12 个版本 (4 个破坏性版本)

0.5.1 2024 年 4 月 11 日
0.5.0 2024 年 1 月 9 日
0.4.1 2023 年 12 月 9 日
0.4.0 2023 年 10 月 27 日
0.1.0 2023 年 10 月 19 日

#84 in 日期和时间

Download history 18/week @ 2024-04-13 5/week @ 2024-04-20 9/week @ 2024-05-11 49/week @ 2024-05-18 5/week @ 2024-05-25 117/week @ 2024-06-01 43/week @ 2024-06-08 16/week @ 2024-06-15 2/week @ 2024-06-22 36/week @ 2024-07-06 7/week @ 2024-07-13 22/week @ 2024-07-27

每月 65 次下载
用于 ala-lape

MIT 许可证

33KB
928

dur

Dur 是一个可读性好的持续时间解析器和格式化/美化打印器。

no_std 支持

Dur 无需 std! 它不使用堆,因此不需要 alloc,因此可以在没有内存分配器的情况下工作。

但是,您可以通过启用 alloc 功能来获得更好的错误消息,并通过启用 std 功能来实现 crate 的 Error 类型以实现 std::error::Error

示例

// StdDuration is a re-export of core::time::Duration
use dur::{Duration, StdDuration};

// Parsing
let d = "1m 42s".parse::<Duration>().unwrap();
assert_eq!(d, Duration::from_secs(60 + 42));
// Duration::to_std and Duration::from_std convert to and from std's Duration:
assert_eq!(d.to_std(), StdDuration::from_secs(60 + 42));
assert_eq!(d, Duration::from_std(StdDuration::from_secs(60 + 42)));

// Formatting
assert_eq!("1m 42s", &format!("{d}"));
// The alternate formatter `#` makes it use full units:
assert_eq!("1 minute 42 seconds", &format!("{d:#}"));

// Fractions work:
let d = "5.1230 secs".parse::<Duration>().unwrap();
assert_eq!(d, Duration::from_millis(5000 + 123));

// Without any precision formatter, at most 2 digits after the decimal point are printed:
assert_eq!("5.12s", &format!("{d}"));

// We can specify precision:
assert_eq!("5.123s", &format!("{d:.3}"));

// Trailling zeros are removed while formatting
let d = "1.2000 milliseconds".parse::<Duration>().unwrap();
assert_eq!("1.2ms", &format!("{d}"));
// The precision specifier is considered "maximum number of digits after the decimal point"
// so, trailling zeroes are still removed!
assert_eq!("1.2ms", &format!("{d:.5}"));

// Durations are normalized to human readable forms:
let hour = "3600 seconds".parse::<Duration>().unwrap();
assert_eq!("1h", &format!("{hour}"));

// IF the string contains only a single integer, no unit, it's parsed as milliseconds:
assert_eq!("500".parse::<Duration>(), Ok(Duration::from_millis(500)));

// However if there's more than one value, it's an error:
assert_eq!(
	dur::parse("1m 300"),
	Err(dur::Error::MissingUnit),
);

// Negative values aren't allowed:
assert_eq!(
	dur::parse("-50 weeks"),
	Err(dur::Error::IsNegative(dur::Decimal::new(-50, 0))),
);

// Duration implements arithmetic traits:
let mut d = Duration::from_secs(0);
d += Duration::from_millis(50);
d -= Duration::from_millis(8);
assert_eq!(d, Duration::from_millis(42));

d  /= 2_u32;
assert_eq!(d, Duration::from_millis(21));
assert_eq!(d * 2_u32, Duration::from_millis(42));

// You can add/subtract StdDuration as well:
let sd = StdDuration::from_millis(100);
assert_eq!(sd, d + StdDuration::from_millis(79));
// It's implemented both ways:
assert_eq!(d, sd - Duration::from_millis(79));

// You can add/sub Duration from a SystemTime:
#[cfg(feature = "std")]
{
	let mut now = std::time::SystemTime::now();
	now -= Duration::from_secs(2);
	now += Duration::from_secs(50);
}

// Finally, you can also compare Duration and StdDuration:
assert_eq!(
	Duration::from_nanos(30),
	StdDuration::from_nanos(30),
);

可选功能

  • alloc:通过使 Error::InvalidUnit 存储有问题的字符串来使错误消息略为详细。
  • std:使 Error 实现 std::error::Error。 (自动启用 alloc 功能)
  • serde:启用 [Duration] 的 serde 反序列化。 (自动启用 alloc 功能)
  • clap:使 Duration 可以直接作为 clap 中的 Arg 使用。 (自动启用 std 功能)

语法

Dur 理解形如 "N 单位" 或 "N1 单位1 N' 单位2" 的持续时间。

数字和单位之间的空格是可选的。

数字可以是十进制:1.2.55.

数字不能为负。

单位不区分大小写。

支持的单位

  • 纳秒,纳秒,纳斯,ns
  • 微秒,微秒,微斯,us,µs
  • 毫秒,毫秒,毫利,ms
  • 秒,秒,秒,s
  • 分钟,分钟,分钟,m
  • 小时,小时,小时,h
  • 天,天,d
  • 周,周,w
  • 年,年,年,y

一个例外是只包含一个非负整数的字符串(例如 "1234"):这些被解析为毫秒。

依赖

~5.5–7.5MB
~142K SLoC