Rust时间处理库yore的使用,高效解析、格式化和操作日期时间的工具库

Rust时间处理库yore的使用,高效解析、格式化和操作日期时间的工具库

Yore是一个Rust库,用于基于OEM代码页解码和编码字符集。

yore at crates.io yore at docs.rs

特性

  • 快速性能
  • 使用Cowshrink_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);
}

性能提示

  1. 对于频繁解析的相同格式,考虑预编译格式字符串
  2. 批量操作时,使用DateTime&mut self方法可以避免不必要的复制
  3. 时区转换开销较大,尽量避免不必要的转换

yore库提供了简单直观的API来处理大多数日期时间场景,同时保持了良好的性能表现。

回到顶部