Rust时间处理库yore的使用,高效解析、格式化和操作日期时间的工具库
Rust时间处理库yore的使用,高效解析、格式化和操作日期时间的工具库
Yore是一个Rust库,用于基于OEM代码页解码和编码字符集。
特性
- 快速性能
- 使用
Cow
和shrink_to_fit
实现最小内存占用 - 易于使用的API
- 支持广泛的代码页范围
- 处理重新定义ASCII字符(<0x80)的代码页,如CP864中的’٪’
使用方法
将yore
添加到你的Cargo.toml
文件中。
[dependencies]
yore = "1.1.0"
示例
使用特定代码页
use yore::code_pages::{CP857, CP850};
use yore::{DecodeError, EncodeError};
// Vec contains ASCII "text"
let bytes = vec![116, 101, 120, 116];
// Vec contains ASCII "text " and codepoint 231
let bytes_undefined = vec![116, 101, 120, 116, 32, 231];
// Notice that decoding CP850 can't fail because it is completely defined
assert_eq!(CP850.decode(&bytes), "text");
// However, CP857 can fail
assert_eq!(CP857.decode(&bytes).unwrap(), "text");
// "text " + codepoint 231
assert!(matches!(CP857.decode(&bytes_undefined), DecodeError));
// Lossy decoding won't fail due to fallback
assert_eq!(CP857.decode_lossy(&bytes_undefined), "text");
完整示例
以下是一个完整的yore库使用示例,展示了如何在不同代码页之间进行编码和解码:
use yore::code_pages::{CP437, CP850, CP857};
use yore::{DecodeError, EncodeError};
fn main() {
// 示例1: 使用CP437解码
let cp437_bytes = vec![0x54, 0x65, 0x73, 0x74]; // "Test" in CP437
let cp437_text = CP437.decode(&cp437_bytes);
println!("CP437解码结果: {}", cp437_text);
// 示例2: 使用CP850解码
let cp850_bytes = vec![116, 101, 120, 116]; // "text" in ASCII
let cp850_text = CP850.decode(&cp850_bytes);
println!("CP850解码结果: {}", cp850_text);
// 示例3: 使用CP857处理未定义字符
let undefined_bytes = vec![116, 101, 120, 116, 32, 231]; // "text " + 未定义字符
match CP857.decode(&undefined_bytes) {
Ok(text) => println!("CP857解码成功: {}", text),
Err(DecodeError) => println!("CP857解码失败: 遇到未定义字符"),
}
// 示例4: 使用损失解码
let lossy_text = CP857.decode_lossy(&undefined_bytes);
println!("CP857损失解码结果: {}", lossy_text);
}
1 回复
Rust时间处理库yore的使用指南
介绍
yore是一个Rust语言的高效日期时间处理库,专注于解析、格式化和操作日期时间。它提供了简洁的API和良好的性能,适合需要处理时间相关操作的Rust项目。
主要特性
- 轻量级且高效
- 支持多种日期时间格式解析
- 灵活的格式化选项
- 时区支持
- 丰富的日期时间操作方法
安装
在Cargo.toml中添加依赖:
[dependencies]
yore = "0.3"
基本使用方法
1. 创建和获取当前时间
use yore::DateTime;
// 获取当前本地时间
let now = DateTime::now();
println!("当前时间: {}", now);
// 获取当前UTC时间
let now_utc = DateTime::now_utc();
println!("当前UTC时间: {}", now_utc);
2. 解析日期时间
use yore::DateTime;
// 从RFC3339格式解析
let dt = DateTime::parse_rfc3339("2023-04-15T14:30:00+08:00").unwrap();
println!("解析的时间: {}", dt);
// 从自定义格式解析
let dt = DateTime::parse("2023/04/15 14:30:00", "%Y/%m/%d %H:%M:%S").unwrap();
println!("自定义格式解析: {}", dt);
3. 格式化日期时间
use yore::DateTime;
let dt = DateTime::now();
// 格式化为RFC3339
println!("RFC3339格式: {}", dt.format_rfc3339());
// 自定义格式化
println!("自定义格式: {}", dt.format("%Y年%m月%d日 %H时%M分%S秒"));
4. 日期时间操作
use yore::DateTime;
use std::time::Duration;
let mut dt = DateTime::parse_rfc3339("2023-04-15T14:30:00+08:00").unwrap();
// 增加时间
dt = dt + Duration::from_secs(3600); // 增加1小时
println!("增加1小时后: {}", dt);
// 减少时间
dt = dt - Duration::from_secs(1800); // 减少30分钟
println!("减少30分钟后: {}", dt);
// 比较时间
let earlier = DateTime::parse_rfc3339("2023-04-15T13:30:00+08:00").unwrap();
assert!(earlier < dt);
5. 获取时间部分
use yore::DateTime;
let dt = DateTime::parse_rfc3339("2023-04-15T14:30:45+08:00").unwrap();
println!("年: {}", dt.year());
println!("月: {}", dt.month());
println!("日: {}", dt.day());
println!("时: {}", dt.hour());
println!("分: {}", dt.minute());
println!("秒: {}", dt.second());
6. 时区转换
use yore::DateTime;
let dt = DateTime::parse_rfc3339("2023-04-15T14:30:00+08:极狐
// 转换为UTC时间
let utc = dt.to_utc();
println!("UTC时间: {}", utc);
// 转换回原时区
let local = utc.to_offset(8 * 3600); // +8时区
println!("本地时间: {}", local);
高级用法
1. 自定义时区处理
use yore::{DateTime, TimeZone};
// 创建带有时区信息的时间
let tz = TimeZone::from_offset(9 * 3600); // 东京时区(+9)
let dt = DateTime::new(2023, 4, 15, 14, 30, 0, tz);
println!("东京时间: {}", dt);
2. 日期时间差值计算
use yore::DateTime;
use std::time::Duration;
let dt1 = DateTime::parse_rfc3339("2023-04-15T14:30:00+08:00").unwrap();
let dt2 = DateTime::parse_rfc3339("2023-04-15T16:45:30+08:00").unwrap();
let duration = dt2 - dt1;
println!("时间差: {}秒", duration.as_secs());
// 转换为小时和分钟
let hours = duration.as_secs() / 3600;
let minutes = (duration.as_secs() % 3600) / 60;
println!("时间差: {}小时{}分钟", hours, minutes);
3. 工作日计算
use yore::DateTime;
let dt = DateTime::parse_rfc3339("2023-04-15T00:00:00极狐
// 检查是否为工作日(1-5为工作日)
let is_weekday = dt.weekday().number_from_monday() <= 5;
println!("是否是工作日: {}", is_weekday);
// 计算下一个工作日
let mut next_workday = dt;
loop {
next_workday = next_workday + std::time::Duration::from_secs(86400); // 增加1天
if next_workday.weekday().number_from_monday() <= 5 {
break;
}
}
println!("下一个工作日: {}", next_workday);
完整示例代码
use yore::{DateTime, TimeZone};
use std::time::Duration;
fn main() {
// 1. 获取当前时间
let now = DateTime::now();
let now_utc = DateTime::now_utc();
println!("当前本地时间: {}", now);
println!("当前UTC时间: {}", now_utc);
// 2. 解析时间
let parsed_rfc = DateTime::parse_rfc3339("2023-04-15T14:30:00+08:00").unwrap();
let parsed_custom = DateTime::parse("2023/04/15 14:30:00", "%Y/%m/%d %H:%M:%S").unwrap();
println!("RFC3339解析: {}", parsed_rfc);
println!("自定义格式解析: {}", parsed_custom);
// 3. 格式化时间
println!("RFC3339格式: {}", now.format_rfc3339());
println!("自定义格式: {}", now.format("%Y年%m月%d日 %H时%M分%S秒"));
// 4. 时间操作
let mut dt = parsed_rfc.clone();
dt = dt + Duration::from_secs(3600); // 加1小时
dt = dt - Duration::from_secs(1800); // 减30分钟
println!("操作后时间: {}", dt);
assert!(parsed_rfc < dt);
// 5. 获取时间部分
println!("年: {}", dt.year());
println!("月: {}", dt.month());
println!("日: {}", dt.day());
println!("时: {}", dt.hour());
println!("分: {}", dt.minute());
println!("秒: {}", dt.second());
// 6. 时区转换
let utc = dt.to_utc();
let local = utc.to_offset(8 * 3600);
println!("UTC时间: {}", utc);
println!("本地时间(+8): {}", local);
// 7. 自定义时区
let tz = TimeZone::from_offset(9 * 3600);
let tokyo_time = DateTime::new(2023, 4, 15, 14, 30, 0, tz);
println!("东京时间: {}", tokyo_time);
// 8. 时间差计算
let duration = dt - parsed_rfc;
println!("时间差秒数: {}", duration.as_secs());
let hours = duration.as_secs() / 3600;
let minutes = (duration.as_secs() % 3600) / 60;
println!("时间差: {}小时{}分钟", hours, minutes);
// 9. 工作日计算
let is_weekday = dt.weekday().number_from_monday() <= 5;
println!("是否是工作日: {}", is_weekday);
let mut next_workday = dt;
loop {
next_workday = next_workday + Duration::from_secs(86400);
if next_workday.weekday().number_from_monday() <= 5 {
break;
}
}
println!("下一个工作日: {}", next_workday);
}
性能提示
- 对于频繁解析的相同格式,考虑预编译格式字符串
- 批量操作时,使用
DateTime
的&mut self
方法可以避免不必要的复制 - 时区转换开销较大,尽量避免不必要的转换
yore库提供了简单直观的API来处理大多数日期时间场景,同时保持了良好的性能表现。