Rust时间格式化库timeago的使用,timeago提供简洁易用的时间间隔计算与人性化展示功能

timeago

在Rust中,将Duration格式化为类似"1小时前"或"01hou"的字符串。

目前它不考虑日历,并假设每个月大约有30.4天。

将此字符串解析回Duration超出了此crate的范围。也许可以看看chrono-english crate。

当isolang功能关闭时,它支持从版本1.24开始的Rust。

API

简化API摘录(伪代码):

pub struct Formatter<L : Language = English>{...}

impl Formatter {
    pub fn new() -> Formatter<English>;
    pub fn with_language(l: Language) -> Self;
    pub fn num_items(&mut self, x: usize) -> &mut Self;
    pub fn max_unit(&mut self, x: TimeUnit) -> &mut Self;
    pub fn min_unit(&mut self, x: TimeUnit) -> &mut Self;
    pub fn too_low(&mut self, x: &'static str) -> &mut Self;
    pub fn too_high(&mut self, x: &'static str) -> &mut Self;
    pub fn max_duration(&mut self, x: Duration) -> &mut Self;
    pub fn ago(&mut self, x: &'static str) -> &mut Self;
    
    pub fn convert(&self, d: Duration) -> String;
    pub fn convert_chrono(&self, from: chrono::DateTime, to: chrono::DateTime) -> String;
}

pub fn from_isolang(x : isolang::Language) -> Option<Box<Language>>;

pub fn format_5chars(d: Duration) -> String;

可以从isolang::Language构造Language。

翻译

  • 英语
  • 俄语
  • 法语
  • 葡萄牙语(贡献)
  • 德语(未检查)
  • 白俄罗斯语(未检查)
  • 波兰语(未检查)
  • 西班牙语(贡献)
  • 中文(贡献)
  • 罗马尼亚语(贡献)
  • 瑞典语(贡献)
  • 土耳其语(贡献)
  • 日语(贡献)
  • 丹麦语(贡献)
  • 意大利语(贡献)
  • 乌克兰语(贡献)
  • 泰语(贡献)

如果您检查了某种语言并确认它正确,请提交一个拉取请求,删除上面列表中的"(未检查)“或”(贡献)"。

工具

有一个辅助命令行工具,可以在添加新翻译时更容易地进行实验:

$ cargo run --features isolang en
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/timeago en`
60
1 minute ago
7200
2 hours ago

另请参阅

  • chrono-humanize
  • compound_duration - 将Duration拆分为周/天/分钟/等部分

完整示例代码:

use std::time::Duration;
use timeago::{Formatter, English};

fn main() {
    // 创建默认的英语格式化器
    let mut formatter = Formatter::new();
    
    // 设置显示的时间单位数量
    formatter.num_items(2);
    
    // 创建一些时间间隔
    let durations = vec![
        Duration::from_secs(60),        // 1分钟
        Duration::from_secs(3600),      // 1小时
        Duration::from_secs(86400),     // 1天
        Duration::from_secs(2592000),   // 约30天
    ];
    
    // 格式化并显示时间间隔
    for duration in durations {
        let formatted = formatter.convert(duration);
        println!("{} seconds -> {}", duration.as_secs(), formatted);
    }
    
    // 使用5字符格式函数
    let short_format = timeago::format_5chars(Duration::from_secs(3660));
    println!("5字符格式: {}", short_format);
}

以下是一个完整的示例demo:

use std::time::Duration;
use timeago::{Formatter, English};
use chrono::{Utc, TimeZone};

fn main() {
    // 示例1:使用默认格式化器
    println!("=== 示例1:基本使用 ===");
    let mut formatter = Formatter::new();
    
    let test_durations = vec![
        Duration::from_secs(30),        // 30秒
        Duration::from_secs(120),       // 2分钟
        Duration::from_secs(7200),      // 2小时
        Duration::from_secs(172800),    // 2天
        Duration::from_secs(5184000),   // 约60天
    ];
    
    for duration in test_durations {
        let formatted = formatter.convert(duration);
        println!("{}秒 -> {}", duration.as_secs(), formatted);
    }
    
    // 示例2:使用中文格式化
    println!("\n=== 示例2:中文格式化 ===");
    if let Some(chinese_lang) = timeago::from_isolang(isolang::Language::Cmn) {
        let mut chinese_formatter = Formatter::with_language(*chinese_lang);
        chinese_formatter.num_items(1);
        
        let durations = vec![
            Duration::from_secs(60),
            Duration::from_secs(3600),
            Duration::from_secs(86400),
        ];
        
        for duration in durations {
            let formatted = chinese_formatter.convert(duration);
            println!("{}秒 -> {}", duration.as_secs(), formatted);
        }
    }
    
    // 示例3:使用chrono时间点
    println!("\n=== 示例3:使用chrono时间点 ===");
    let now = Utc::now();
    let past_time = Utc.with_ymd_and_hms(2023, 1, 1, 12, 0, 0).unwrap();
    
    let time_diff = formatter.convert_chrono(past_time, now);
    println!("时间差: {}", time_diff);
    
    // 示例4:5字符短格式
    println!("\n=== 示例4:5字符短格式 ===");
    let short_durations = vec![
        Duration::from_secs(59),        // 59秒
        Duration::from_secs(60),        // 1分钟
        Duration::from_secs(3600),      // 1小时
        Duration::from_secs(86400),     // 1天
    ];
    
    for duration in short_durations {
        let short_format = timeago::format_5chars(duration);
        println!("{}秒 -> {}", duration.as_secs(), short_format);
    }
    
    // 示例5:自定义配置
    println!("\n=== 示例5:自定义配置 ===");
    let mut custom_formatter = Formatter::new();
    custom_formatter
        .num_items(3)                   // 显示最多3个时间单位
        .max_unit(timeago::TimeUnit::Days) // 最大显示到天
        .min_unit(timeago::TimeUnit::Minutes) // 最小显示到分钟
        .too_low("刚刚")                 // 设置时间太短的显示文本
        .too_high("很久以前")            // 设置时间太长的显示文本
        .ago("之前");                    // 设置时间后缀
    
    let custom_durations = vec![
        Duration::from_secs(30),        // 时间太短
        Duration::from_secs(3661),      // 1小时1分钟1秒
        Duration::from_secs(90000),     // 1天1小时(超过最大单位)
    ];
    
    for duration in custom_durations {
        let formatted = custom_formatter.convert(duration);
        println!("{}秒 -> {}", duration.as_secs(), formatted);
    }
}

1 回复

Rust时间格式化库timeago使用指南

timeago是一个轻量级的Rust时间格式化库,用于计算时间间隔并以人性化的方式展示时间差。

安装方法

在Cargo.toml中添加依赖:

[dependencies]
timeago = "0.2"

基本用法

use timeago::{Formatter, TimeUnit};
use std::time::Duration;

fn main() {
    // 创建格式化器
    let formatter = Formatter::new();
    
    // 计算时间差并格式化
    let duration = Duration::from_secs(3600); // 1小时前
    let result = formatter.convert(duration);
    
    println!("{}", result); // 输出: 1 hour ago
}

示例代码

use timeago::{Formatter, TimeUnit};
use std::time::{Duration, SystemTime};

fn main() {
    let formatter = Formatter::new();
    
    // 不同时间间隔示例
    let intervals = vec![
        Duration::from_secs(30),    // 30秒
        Duration::from_secs(120),   // 2分钟
        Duration::from_secs(7200),  // 2小时
        Duration::from_secs(86400), // 1天
    ];
    
    for duration in intervals {
        let formatted = formatter.convert(duration);
        println!("{}秒 -> {}", duration.as_secs(), formatted);
    }
    
    // 实际时间差计算
    let now = SystemTime::now();
    let past = now - Duration::from_secs(150);
    let duration = now.duration_since(past).unwrap();
    
    println!("实际时间差: {}", formatter.convert(duration));
}

自定义配置

use timeago::{Formatter, TimeUnit};

fn custom_formatter() {
    let mut formatter = Formatter::new();
    
    // 自定义时间单位显示
    formatter.ago("之前"); // 将"ago"替换为"之前"
    
    // 自定义时间单位名称
    formatter.num_seconds(1, "1秒");
    formatter.num_minutes(1, "1分钟");
    
    let duration = std::time::Duration::from_secs(65);
    println!("{}", formatter.convert(duration)); // 输出: 1分钟之前
}

多语言支持

use timeago::{Formatter, Languages};

fn multi_language_example() {
    // 中文格式化
    let chinese_formatter = Formatter::with_language(Languages::ChineseSimplified);
    let duration = std::time::Duration::from_secs(3665); // 1小时1分5秒
    println!("中文: {}", chinese_formatter.convert(duration));
    
    // 英文格式化
    let english_formatter = Formatter::with_language(Languages::English);
    println!("English: {}", english_formatter.convert(duration));
}

高级用法

use timeago::{Formatter, TimeUnit};

fn precise_formatting() {
    let formatter = Formatter::new();
    
    // 获取详细的时间单位信息
    let duration = std::time::Duration::from_secs(3665); // 1小时1分5秒
    let precise = formatter.convert_precise(duration);
    
    println!("精确格式: {}", precise);
    // 输出包含所有时间单位的详细分解
}

完整示例demo

use timeago::{Formatter, Languages, TimeUnit};
use std::time::{Duration, SystemTime};

fn main() {
    println!("=== timeago库完整使用示例 ===");
    
    // 基本用法示例
    println!("\n1. 基本用法:");
    let formatter = Formatter::new();
    let durations = vec![
        Duration::from_secs(30),     // 30秒
        Duration::from_secs(120),    // 2分钟
        Duration::from_secs(3600),   // 1小时
        Duration::from_secs(86400),  // 1天
        Duration::from_secs(259200), // 3天
    ];
    
    for duration in durations {
        let formatted = formatter.convert(duration);
        println!("{}秒 -> {}", duration.as_secs(), formatted);
    }
    
    // 实际时间差计算
    println!("\n2. 实际时间差计算:");
    let now = SystemTime::now();
    let past_times = vec![
        now - Duration::from_secs(45),     // 45秒前
        now - Duration::from_secs(300),    // 5分钟前
        now - Duration::from_secs(7200),   // 2小时前
    ];
    
    for past in past_times {
        if let Ok(duration) = now.duration_since(past) {
            println!("实际时间差: {}", formatter.convert(duration));
        }
    }
    
    // 自定义配置示例
    println!("\n3. 自定义配置:");
    let mut custom_formatter = Formatter::new();
    custom_formatter.ago("之前");
    custom_formatter.num_seconds(1, "1秒");
    custom_formatter.num_minutes(1, "1分钟");
    custom_formatter.num_hours(1, "1小时");
    
    let test_durations = vec![
        Duration::from_secs(30),   // 30秒
        Duration::from_secs(65),   // 1分5秒
        Duration::from_secs(3665), // 1小时1分5秒
    ];
    
    for duration in test_durations {
        println!("{}秒 -> {}", duration.as_secs(), custom_formatter.convert(duration));
    }
    
    // 多语言支持示例
    println!("\n4. 多语言支持:");
    let chinese_formatter = Formatter::with_language(Languages::ChineseSimplified);
    let english_formatter = Formatter::with_language(Languages::English);
    
    let multi_durations = vec![
        Duration::from_secs(30),
        Duration::from_secs(300),
        Duration::from_secs(3600),
    ];
    
    for duration in multi_durations {
        println!("{}秒:", duration.as_secs());
        println!("  中文: {}", chinese_formatter.convert(duration));
        println!("  英文: {}", english_formatter.convert(duration));
    }
    
    // 精确格式示例
    println!("\n5. 精确格式:");
    let precise_formatter = Formatter::new();
    let precise_duration = Duration::from_secs(3665); // 1小时1分5秒
    let precise_result = precise_formatter.convert_precise(precise_duration);
    println!("精确格式: {}", precise_result);
    
    println!("\n=== 示例运行完成 ===");
}

timeago库提供了简单直观的API来处理时间间隔的格式化,支持多语言和自定义配置,非常适合需要显示相对时间的应用程序。

回到顶部