20个版本
0.2.0-alpha.8 | 2023年1月9日 |
---|---|
0.2.0-alpha.7 | 2023年1月4日 |
0.2.0-alpha.6 | 2022年9月15日 |
0.1.12 | 2022年9月8日 |
0.0.1 | 2022年8月6日 |
#564 in 编码
每月 84 次下载
94KB
2K SLoC
calends
calends 是一个用于持续时间、时间间隔和其他日历相关操作的库。它旨在与chrono一起使用。
理由
Calends 是为了扩展生态系统中现有的日期时间工具(如chrono)而构建的。其主要重点是查找和处理更复杂的事物,例如时间间隔、持续时间(专注于月份或更长时间,chrono 不支持月份),以及复杂的重复规则,例如“每月第3天重复3次”。
除了支持日期时间逻辑,还应考虑 ISO8601-2:2019。该标准是为了扩展当前的 ISO8601 标准并添加对间隔、持续时间、重复时间的支持而创建的。这并不是一个广泛采用的标准(可能由于其封闭和非常昂贵的性质)。
此库中的许多概念都受到了 ISO8601-2:2019 标准和 CalConnect 的影响。
时间持续时间
相对持续时间 是一个可以将日期应用于其中以产生另一个日期的时间单位。
use calends::RelativeDuration;
use chrono::NaiveDate;
// This will allow you to add one month and then go back two days from the added month
let rd = RelativeDuration::months(1).with_days(-2);
// It also compatible with NaiveDate
assert_eq!(
NaiveDate::from_ymd(2022, 1, 1) + rd,
NaiveDate::from_ymd(2022, 1, 30)
);
将持续时间应用于日期时,如果最大单位首先应用,则按顺序应用,例如,月份将在周之前。因此,当构建类似于 1 个月、-1 天的持续时间时,它将先向前移动 1 个月,然后向后移动 1 天。
序列化
有两种方法可以序列化相对持续时间
- 第一种方法将其序列化为一个对象。
- 第二种方法是一个与 ISO8601-2:2019 兼容的序列化器。因为格式尚未广泛使用,所以我们没有将其设置为默认(反)序列化器。
use calends::RelativeDuration;
use calends::rd_iso8601;
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct S {
#[serde(
deserialize_with = "rd_iso8601::deserialize",
serialize_with = "rd_iso8601::serialize"
)]
rd: RelativeDuration,
}
let rd = RelativeDuration::default().with_days(1).with_months(23).with_weeks(-1);
let s = S { rd };
let rd_string = serde_json::to_string(&s).unwrap();
assert_eq!(rd_string, r#"{"rd":"P23M-1W1D"}"#);
let parsed: S = serde_json::from_str(&rd_string).unwrap();
assert_eq!(rd, parsed.rd)
重复和规则
[重复] 允许您指定事件(日期)在时间上重复的规则集。
use calends::{Recurrence, Rule};
use chrono::NaiveDate;
let date = NaiveDate::from_ymd(2022, 1, 1);
let end = NaiveDate::from_ymd(2022, 3, 1);
let mut recur = Recurrence::with_start(Rule::monthly(), date).until(end);
assert_eq!(recur.next(), Some(NaiveDate::from_ymd(2022, 1, 1)));
assert_eq!(recur.next(), Some(NaiveDate::from_ymd(2022, 2, 1)));
assert_eq!(recur.next(), None);
时间间隔
时间间隔是一段可以绑定或不绑定的持续时间。有三个重要的情况需要考虑:封闭的、无界起始和无限终止。
- 封闭的时间间隔具有起始和终止,并且可以重复。
- 无界起始的时间间隔没有起始,只有终止。
- 无界终止的时间间隔没有终止,但有起始。
封闭时间间隔
结合相对持续时间,您可以执行诸如迭代月份倒数第二天之类的事情。
use calends::{Interval, RelativeDuration};
use chrono::NaiveDate;
let duration = RelativeDuration::months(1).with_days(-2);
let start = NaiveDate::from_ymd(2022, 1, 1);
let mut interval = Interval::closed_from_start(start, duration);
序列化
有三种方法可以序列化时间间隔
- 第一种方法将其序列化为一个对象。
- 第二种方法是一个与 ISO8601-2:2019 兼容的序列化器。因为格式尚未广泛使用,所以我们没有将其设置为默认(反)序列化器。
use chrono::NaiveDate;
use calends::{Interval, RelativeDuration, IntervalLike};
use calends::interval::marker::Start;
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct S {
i: Interval,
}
let rd = RelativeDuration::default().with_days(1).with_months(23).with_weeks(-1);
let int = Interval::closed_from_start(NaiveDate::from_ymd(2022, 1, 1), rd);
let s = S { i: int.clone() };
let int_string = serde_json::to_string(&s).unwrap();
assert_eq!(int_string, r#"{"i":"2022-01-01/2023-11-25"}"#);
let parsed: S = serde_json::from_str(&int_string).unwrap();
assert_eq!(parsed.i.start_opt().unwrap(), int.start_opt().unwrap())
许可证: MIT
依赖项
~2.3–3.5MB
~62K SLoC