3 个不稳定版本
0.2.0 | 2021年10月5日 |
---|---|
0.1.1 | 2021年9月10日 |
0.1.0 | 2021年9月10日 |
#163 in 日期和时间
205KB
4.5K SLoC
edtf
本 crate 实现了截至 2019-02 规范的扩展日期/时间格式。它包含对每个级别 0、1(以及 2,但尚未)的单独实现。每个级别所做选择的说明可在模块级别的文档中找到。
安装
[dependencies]
edtf = "0.2.0"
特性
- 无损。每个解析的 Edtf 可以再次格式化,以输出完全相同的字符串。
- 严格。拒绝规范拒绝的所有解析错误。所有类型都使得构建一个无效的
Edtf
对象成为不可能,直到闰年。 - 通过可选的
features = ["chrono"]
与广泛使用的 chrono crate 集成。同样,在serde
功能下提供可选的 serde 实现。 - 三种实现,而不是一种,因此您可以选择兼容性级别。
关于 EDTF 和 ISO 8601 日历系统的一些说明
可能还没有多次声明,EDTF 和 ISO 8601 只支持一种日历系统,即一个有零年的修改过的 前摄格列高利日历。⚠️ 这意味着您可能需要将旧的历史记录从不同的日历系统转换为可准确使用 EDTF 的格式。
以下是 EDTF 使用的摘要
- 用
BCE
写的年份会减一。1BCE 在 EDTF 中是 0000 年。100BCE 在 EDTF 中是 -0099。 - 正数年份(即 CE)已经是正确的。
- 注意转录在本地采用格列高利日历之前写下完整的日期。您可能无意中转录了一个儒略日期或其他日历,这将由 EDTF 重新解释为前摄格列高利日期并表现不正确。
- 检查历史记录创建地的 格列高利日历的本地采用。许多西方司法管辖区在 1582 年采用了它,但例如,英国直到 1752-09 才切换过来。
- 请注意,尤其是如果您试图天真地将EDTF用作年/月/日组合的简单存储区域,那么您可能会无意中写入无效的ISO日期,因为在采用之前删除了大约每25个闰年。 该库验证解析的EDTF日期实际上存在于ISO日历中。
这里有一个由Stephen P. Morse制作的在线儒略历与公历转换器,他是设计英特尔8086芯片的人。更多转换工具和有关一系列日历系统的详细信息可以在他的优秀一步网页网站上找到。
那里有一项有用的信息是,儒略历的年通常不会在1月1日增加。在英国,它在3月25日增加,这曾经是那里的财政年末,直到他们转向公历并在这个过程中减少了11天。从那时起,税务日是4月5日!1月1日至3月25日的儒略日期通常为“双重日期”,即
...两个年份由斜杠分隔。第一年是当地使用的儒略历年份,第二年是如果他们在1月1日更改年份的话,它将会是哪一年的年份。
例如,1683/4年2月19日。
edtf
crate的示例用法
第0级
use edtf::level_0::Edtf;
let edtf = Edtf::parse("2019-01-07/2020-01").unwrap();
match edtf {
Edtf::Date(d) => println!("date: {}", d),
Edtf::Interval(from, to) => {
println!("interval: {} to {}", from, to);
println!("year parts: {} to {}", from.year(), to.year());
}
Edtf::DateTime(dt) => println!("datetime: {}", dt),
}
// prints:
// interval: 2019-01-07 to 2020-01
// year parts: 2019 to 2020
第1级
use edtf::level_1::{Date, Edtf, Certainty, Precision, Terminal};
use edtf::{DateTime, Time, DateComplete, TzOffset};
let edtf = Edtf::parse("2021-07-15");
assert_eq!(edtf, Ok(Edtf::Date(Date::from_ymd(2021, 07, 15))));
let edtf = Edtf::parse("2019-01-XX?").unwrap();
match edtf {
Edtf::Date(date) => {
// precision deconstructs a date into variants like
// 2019, 2019-01, 2019-01-01, 20XX, 201X, 2019-XX, 2019-01-XX, 2019-XX-XX.
// certainty is the ? (Uncertain) / ~ (Approximate) / % (Both) value.
assert_eq!(date.precision(), Precision::DayOfMonth(2019, 01));
assert_eq!(date.certainty(), Certainty::Uncertain);
}
_ => panic!("not matched")
}
let edtf = Edtf::parse("2019-XX/..").unwrap();
match edtf {
Edtf::IntervalFrom(from_date, terminal) => {
assert_eq!(from_date.precision(), Precision::MonthOfYear(2019));
assert_eq!(terminal, Terminal::Open);
}
_ => panic!("not matched"),
}
let edtf = Edtf::parse("Y-12000").unwrap();
match edtf {
Edtf::YYear(yy) => assert_eq!(yy.value(), -12000i64),
_ => panic!("not matched"),
}
let edtf = Edtf::parse("2012-11-30T12:04:56Z").unwrap();
match edtf {
Edtf::DateTime(dt) => {
assert_eq!(dt.date(), DateComplete::from_ymd(2012, 11, 30));
assert_eq!(dt.time(), Time::from_hmsz(12, 04, 56, TzOffset::Utc));
},
_ => panic!("not matched"),
}
// Edtf's parsing + Display implementation is lossless, so you can render back
// out the same string.
let string = "2019-01-XX~/2020-XX";
assert_eq!(Edtf::parse(string).unwrap().to_string(), string);
许可:MPL-2.0
依赖项
~1–1.7MB
~30K SLoC