一个基于 nom 解析器组合库的高性能 ISO 8601 日期时间解析库,完全使用 Rust 编写。
特性
🚀 核心功能
- 完整的 ISO 8601 支持:解析所有标准日期、时间、日期时间和持续时间格式
- 零拷贝解析:基于 nom 的高效解析器,最小化内存分配
- 强类型安全:Rust 的类型系统保证解析结果的正确性
- 丰富的错误信息:详细的错误类型帮助快速定位问题
📅 支持的格式
- 日期 :
YYYY-MM-DD,YYYYMMDD,YYYY-Www-D,YYYYWwwD,YYYY-DDD,YYYYDDD - 时间 :
hh:mm:ss,hhmmss,hh:mm,hhmm,hh(支持小数秒和时区) - 日期时间 :
YYYY-MM-DDThh:mm:ss±hh:mm等各种组合 - 持续时间 :
PnYnMnDTnHnMnS,PnW等完整持续时间格式 - 重复间隔 :
R[n]/start/interval重复时间间隔
🔧 可选集成
- Chrono 支持:与流行的 chrono 日期时间库无缝集成
- Serde 序列化:支持所有数据结构的序列化和反序列化
- no_std 兼容:可在嵌入式等受限环境中使用
快速开始
安装
在 Cargo.toml 中添加依赖:
toml
[dependencies]
iso8601 = "0.6"
启用所有特性:
toml
[dependencies]
iso8601 = { version = "0.6", features = ["chrono", "serde"] }
基本用法
rust
use iso8601;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 解析日期
let date = iso8601::date("2023-10-25")?;
println!("解析日期: {:?}", date);
// 解析时间
let time = iso8601::time("14:30:45.123+08:00")?;
println!("解析时间: {:?}", time);
// 解析日期时间
let datetime = iso8601::datetime("2023-10-25T14:30:45Z")?;
println!("解析日期时间: {:?}", datetime);
// 解析持续时间
let duration = iso8601::duration("P1Y2M3DT4H5M6.5S")?;
println!("解析持续时间: {:?}", duration);
Ok(())
}
高级示例
与 Chrono 集成
rust
use iso8601;
use chrono::{DateTime, Utc, NaiveDate};
// 启用 chrono 特性后可以直接转换
#[cfg(feature = "chrono")]
fn chrono_integration() {
let iso_date = iso8601::date("2023-10-25").unwrap();
let chrono_date: NaiveDate = iso_date.into();
println!("Chrono 日期: {}", chrono_date);
let iso_datetime = iso8601::datetime("2023-10-25T14:30:00Z").unwrap();
let chrono_datetime: DateTime<Utc> = iso_datetime.into();
println!("Chrono 日期时间: {}", chrono_datetime);
}
Serde 序列化
rust
use iso8601;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Event {
name: String,
#[serde(with = "iso8601")]
start_time: iso8601::DateTime,
duration: iso8601::Duration,
}
fn serde_example() -> Result<(), Box<dyn std::error::Error>> {
let event = Event {
name: "会议".to_string(),
start_time: iso8601::datetime("2023-10-25T14:30:00Z")?,
duration: iso8601::duration("PT1H30M")?,
};
let json = serde_json::to_string(&event)?;
println!("序列化事件: {}", json);
let deserialized: Event = serde_json::from_str(&json)?;
println!("反序列化事件: {:?}", deserialized.name);
Ok(())
}
错误处理
rust
use iso8601;
fn robust_parsing() {
match iso8601::date("2023-02-30") {
Ok(date) => println!("有效日期: {:?}", date),
Err(iso8601::Error::OutOfRange) => {
eprintln!("错误: 日期超出有效范围");
}
Err(e) => {
eprintln!("解析错误: {}", e);
}
}
// 处理部分解析
match iso8601::datetime("2023-10-25T14:30") {
Ok(datetime) => println!("解析成功: {:?}", datetime),
Err(e) => {
eprintln!("部分日期时间解析失败: {}", e);
// 可以尝试只解析日期部分
if let Ok(date) = iso8601::date("2023-10-25") {
println!("至少日期部分有效: {:?}", date);
}
}
}
}
API 参考
主要函数
| 函数 | 描述 | 示例 |
|---|---|---|
date() |
解析 ISO 8601 日期 | date("2023-10-25") |
time() |
解析 ISO 8601 时间 | time("14:30:45Z") |
datetime() |
解析 ISO 8601 日期时间 | datetime("2023-10-25T14:30:45+08:00") |
duration() |
解析 ISO 8601 持续时间 | duration("P1DT2H3M4S") |
数据结构
Date
rust
let date = Date {
year: 2023,
month: 10,
day: 25,
};
Time
rust
let time = Time {
hour: 14,
minute: 30,
second: 45,
millisecond: 0,
tz_offset_minutes: Some(480), // UTC+8
};
Duration
rust
let duration = Duration {
years: 1,
months: 2,
days: 3,
hours: 4,
minutes: 5,
seconds: 6,
nanoseconds: 500_000_000, // 0.5 秒
};
性能特点
- 零分配解析:大部分解析操作不需要堆分配
- 快速失败:无效输入能够快速识别并返回错误
- 流式处理:支持处理大型数据流中的日期时间字符串
- 内存安全:Rust 的所有权系统保证内存安全
与其他库比较
| 特性 | iso8601 | chrono | time |
|---|---|---|---|
| ISO 8601 专门化 | ✅ 专注 | ❌ 通用 | ❌ 通用 |
| 零依赖核心 | ✅ | ❌ | ✅ |
| nom 解析器 | ✅ | ❌ | ❌ |
| Chrono 集成 | ✅ 可选 | ✅ 原生 | ❌ |
| 序列化支持 | ✅ 可选 | ✅ | ✅ |
开发状态
当前版本:0.6.3 - 生产就绪
稳定性
- ✅ 核心解析功能稳定
- ✅ 错误处理完善
- ✅ 文档完整
- ✅ 测试覆盖全面
兼容性
- Rust 版本:2018 及更高版本
- nom 版本:8.x
- 可选:chrono 0.4, serde 1.0
开发设置
bash
# 克隆仓库
git clone https://github.com/badboy/iso8601.git
cd iso8601
# 运行测试
cargo test
# 运行所有特性的测试
cargo test --all-features
# 生成文档
cargo doc --open
# 运行基准测试
cargo bench
许可证
MIT 许可证 - 详见 <LICENSE> 文件。
致谢