Rust时间区间处理库intervallum的使用,高效管理时间范围与间隔计算

Rust时间区间处理库intervallum的使用,高效管理时间范围与间隔计算

Intervallum是一个用于计算算术区间的库,可在Rust稳定版上编译。提供许多集合操作,如并集和交集。区间可以用Interval类型表示,它只是一对整数(例如(0,10),表示0到10之间的值),以及IntervalSet,它是一个区间向量(例如[(0,10), (15,20)]表示0到10之间以及15到20之间的所有值)。

该库可用、经过全面测试和文档化,但仅适用于整数(i8-i64u8-u64usizeisize)。

许可证

根据以下任一许可

  • Apache许可证,版本2.0
  • MIT许可证

由您选择。

贡献

除非您明确声明,否则您为包含在工作中而有意提交的任何贡献均应按照上述双重许可,不附加任何额外条款或条件。

为确保格式化和linting的一致性,请安装pre-commit

pip install pre-commit
pre-commit install

安装

在项目目录中运行以下Cargo命令:

cargo add intervallum

或者将以下行添加到您的Cargo.toml中:

intervallum = "1.4.4"

示例

以下是一个使用intervallum库的完整示例:

use intervallum::{Interval, IntervalSet};

fn main() {
    // 创建单个区间
    let interval1 = Interval::new(0, 10); // 包含0到10的区间
    let interval2 = Interval::new(5, 15); // 包含5到15的区间
    
    // 检查区间是否重叠
    println!("区间1和区间2是否重叠: {}", interval1.overlaps(&interval2));
    
    // 计算区间的交集
    if let Some(intersection) = interval1.intersection(&interval2) {
        println!("交集: {:?}", intersection);
    }
    
    // 创建区间集合
    let mut set1 = IntervalSet::new();
    set1.insert(Interval::new(0, 10));
    set1.insert(Interval::new(20, 30));
    
    let mut set2 = IntervalSet::new();
    set2.insert(Interval::new(5, 15));
    set2.insert(Interval::new(25, 35));
    
    // 计算集合的并集
    let union = set1.union(&set2);
    println!("并集: {:?}", union);
    
    // 计算集合的交集
    let intersection = set1.intersection(&set2);
    println!("交集: {:?}", intersection);
    
    // 检查值是否在集合中
    println!("值7是否在set1中: {}", set1.contains(7));
    println!("值15是否在set1中: {}", set1.contains(15));
}

这个示例展示了如何创建单个区间和区间集合,执行基本的集合操作(如并集和交集),以及检查值是否包含在区间集合中。intervallum库提供了高效的区间运算功能,特别适合处理时间范围和其他数值区间的计算需求。

完整示例代码

use intervallum::{Interval, IntervalSet};

fn main() {
    println!("=== Intervallum库使用示例 ===");
    
    // 1. 创建和操作单个区间
    println!("\n--- 单个区间操作 ---");
    
    // 创建两个重叠的区间
    let time_range1 = Interval::new(0, 10);    // 时间范围0-10
    let time_range2 = Interval::new(5, 15);    // 时间范围5-15
    
    println!("区间1: {:?}", time_range1);
    println!("区间2: {:?}", time_range2);
    
    // 检查区间是否重叠
    println!("区间是否重叠: {}", time_range1.overlaps(&time_range2));
    
    // 计算交集
    match time_range1.intersection(&time_range2) {
        Some(intersect) => println!("交集区间: {:?}", intersect),
        None => println!("区间没有交集"),
    }
    
    // 检查包含关系
    println!("区间1包含7: {}", time_range1.contains(7));
    println!("区间1包含12: {}", time_range1.contains(12));
    
    // 2. 使用区间集合
    println!("\n--- 区间集合操作 ---");
    
    // 创建第一个时间区间集合
    let mut schedule1 = IntervalSet::new();
    schedule1.insert(Interval::new(9, 12));   // 上午9点到12点
    schedule1.insert(Interval::new(14, 18));  // 下午2点到6点
    println!("日程1: {:?}", schedule1);
    
    // 创建第二个时间区间集合
    let mut schedule2 = IntervalSet::new();
    schedule2.insert(Interval::new(10, 15));  // 上午10点到下午3点
    schedule2.insert(Interval::new(16, 20));  // 下午4点到8点
    println!("日程2: {:?}", schedule2);
    
    // 计算并集 - 所有时间段的合并
    let union_schedule = schedule1.union(&schedule2);
    println!("并集(所有时间段): {:?}", union_schedule);
    
    // 计算交集 - 共同空闲时间
    let common_free_time = schedule1.intersection(&schedule2);
    println!("交集(共同空闲时间): {:?}", common_free_time);
    
    // 检查特定时间点的可用性
    println!("11点是否在日程1中: {}", schedule1.contains(11));
    println!("13点是否在日程1中: {}", schedule1.contains(13));
    println!("17点是否在共同空闲时间中: {}", 
             common_free_time.as_ref().map_or(false, |set| set.contains(17)));
    
    // 3. 更复杂的时间管理示例
    println!("\n--- 复杂时间管理示例 ---");
    
    let mut weekly_schedule = IntervalSet::new();
    // 添加工作时段
    weekly_schedule.insert(Interval::new(9, 12));  // 周一至周五上午
    weekly_schedule.insert(Interval::new(14, 18)); // 周一至周五下午
    
    // 添加会议时间
    let mut meetings = IntervalSet::new();
    meetings.insert(Interval::new(10, 11));  // 周一会议
    meetings.insert(Interval::new(15, 16));  // 周三会议
    
    // 计算实际工作时间(减去会议时间)
    let actual_work_time = weekly_schedule.difference(&meetings);
    println!("实际工作时间: {:?}", actual_work_time);
    
    // 验证时间点
    let check_times = [9, 10, 11, 15, 17];
    for &time in &check_times {
        println!("时间{}: 总日程={}, 会议={}, 实际工作={}", 
                time,
                weekly_schedule.contains(time),
                meetings.contains(time),
                actual_work_time.contains(time));
    }
}

这个完整示例展示了intervallum库在实际时间管理场景中的应用,包括单个区间操作、集合运算以及复杂的时间调度逻辑。通过这个示例,您可以了解如何使用该库来处理各种时间区间计算需求。


1 回复

Rust时间区间处理库intervallum的使用指南

介绍

intervallum是一个专门用于处理时间区间和间隔计算的Rust库。它提供了强大的功能来处理时间范围的创建、比较、合并、分割和计算交集等操作,特别适合需要处理日程安排、时间调度和时段管理的应用场景。

主要特性

  • 时间区间创建和验证
  • 区间关系判断(包含、重叠、相邻等)
  • 区间运算(并集、交集、差集)
  • 时间间隔计算
  • 时区支持
  • 序列化和反序列化

安装方法

在Cargo.toml中添加依赖:

[dependencies]
intervallum = "0.3"
chrono = "0.4"

基本使用方法

创建时间区间

use intervallum::Interval;
use chrono::{DateTime, Utc, Duration};

// 创建时间区间
let start = DateTime::parse_from_rfc3339("2023-01-01T00:00:00Z").unwrap();
let end = DateTime::parse_from_rfc3339("2023-01-01T23:59:59Z").unwrap();
let interval = Interval::new(start, end).unwrap();

// 使用时间戳创建
let interval = Interval::new(
    Utc::now(),
    Utc::now() + Duration::hours(24)
).unwrap();

区间关系判断

let interval1 = Interval::new(
    DateTime::parse_from_rfc3339("2023-01-01T00:00:00Z").unwrap(),
    DateTime::parse_from_rfc3339("2023-01-01T12:00:00Z").unwrap()
).unwrap();

let interval2 = Interval::new(
    DateTime::parse_from_rfc3339("2023-01-01T06:00:00Z").unwrap(),
    DateTime::parse_from_rfc3339("2023-01-01T18:00:00Z").unwrap()
).unwrap();

// 检查是否重叠
println!("是否重叠: {}", interval1.overlaps(&interval2));

// 检查是否包含
println!("是否包含: {}", interval1.contains(&interval2));

区间运算

// 计算交集
if let Some(intersection) = interval1.intersection(&interval2) {
    println!("交集: {:?}", intersection);
}

// 计算并集
if let Some(union) = interval1.union(&interval2) {
    println!("并集: {:?}", union);
}

// 计算差集
let differences = interval1.difference(&interval2);
for diff in differences {
    println!("差集部分: {:?}", diff);
}

时间间隔计算

// 获取区间持续时间
let duration = interval1.duration();
println!("区间时长: {}秒", duration.num_seconds());

// 分割区间
let split_intervals = interval1.split(Duration::hours(2));
for sub_interval in split_intervals {
    println!("分割后的子区间: {:?}", sub_interval);
}

高级用法:处理多个区间

use intervallum::IntervalSet;

// 创建区间集合
let mut interval_set = IntervalSet::new();
interval_set.insert(interval1);
interval_set.insert(interval2);

// 合并重叠区间
let merged = interval_set.merge();
println!("合并后的区间: {:?}", merged);

// 查找空闲时间段
let gaps = interval_set.gaps();
for gap in gaps {
    println!("空闲时间段: {:?}", gap);
}

实用技巧

  1. 输入验证:intervallum会自动验证输入的时间区间是否有效(结束时间不能早于开始时间)
  2. 边界处理:支持开区间、闭区间和半开区间的处理
  3. 性能优化:内部使用高效的数据结构和算法,适合处理大量时间区间
  4. 错误处理:所有操作都返回Result类型,便于错误处理

注意事项

  • 确保时间格式的一致性,建议统一使用UTC时间
  • 处理大时间范围时注意整数溢出问题
  • 序列化时考虑时区信息的保存

intervallum库为Rust开发者提供了完整的时间区间处理解决方案,可以大大简化时间范围相关的编程工作。

完整示例demo

use intervallum::{Interval, IntervalSet};
use chrono::{DateTime, Utc, Duration, TimeZone};

fn main() {
    // 示例1:创建时间区间
    println!("=== 创建时间区间示例 ===");
    
    // 从RFC3339字符串创建时间区间
    let start = DateTime::parse_from_rfc3339("2023-01-01T08:00:00Z").unwrap();
    let end = DateTime::parse_from_rfc3339("2023-01-01T17:00:00Z").unwrap();
    let work_interval = Interval::new(start, end).unwrap();
    println!("工作时间区间: {:?}", work_interval);
    
    // 使用当前时间创建区间
    let now = Utc::now();
    let future_interval = Interval::new(now, now + Duration::hours(2)).unwrap();
    println!("未来2小时区间: {:?}", future_interval);

    // 示例2:区间关系判断
    println!("\n=== 区间关系判断示例 ===");
    
    let meeting1 = Interval::new(
        Utc.with_ymd_and_hms(2023, 1, 1, 9, 0, 0).unwrap(),
        Utc.with_ymd_and_hms(2023, 1, 1, 10, 0, 0).unwrap()
    ).unwrap();
    
    let meeting2 = Interval::new(
        Utc.with_ymd_and_hms(2023, 1, 1, 9, 30, 0).unwrap(),
        Utc.with_ymd_and_hms(2023, 1, 1, 11, 0, 0).unwrap()
    ).unwrap();
    
    println!("会议1是否与会议2重叠: {}", meeting1.overlaps(&meeting2));
    println!("工作时间是否包含会议1: {}", work_interval.contains(&meeting1));

    // 示例3:区间运算
    println!("\n=== 区间运算示例 ===");
    
    // 计算交集
    if let Some(common_time) = meeting1.intersection(&meeting2) {
        println!("会议交集时间: {:?}", common_time);
    }
    
    // 计算差集
    let free_times = work_interval.difference(&meeting1);
    for free_time in free_times {
        println!("空闲时间段: {:?}", free_time);
    }

    // 示例4:时间间隔计算
    println!("\n=== 时间间隔计算示例 ===");
    
    let meeting_duration = meeting1.duration();
    println!("会议时长: {}分钟", meeting_duration.num_minutes());
    
    // 分割工作时间段
    let break_intervals = work_interval.split(Duration::hours(3));
    for (i, interval) in break_intervals.iter().enumerate() {
        println!("分段{}: {:?}", i + 1, interval);
    }

    // 示例5:处理多个区间
    println!("\n=== 多区间处理示例 ===");
    
    let mut schedule = IntervalSet::new();
    schedule.insert(meeting1);
    schedule.insert(meeting2);
    
    // 合并重叠的会议时间
    let merged_schedule = schedule.merge();
    println!("合并后的日程: {:?}", merged_schedule);
    
    // 查找空闲时间段
    let available_slots = schedule.gaps();
    for slot in available_slots {
        println!("可用时间段: {:?}", slot);
    }

    // 示例6:错误处理
    println!("\n=== 错误处理示例 ===");
    
    // 尝试创建无效区间(结束时间早于开始时间)
    let invalid_start = Utc.with_ymd_and_hms(2023, 1, 1, 12, 0, 0).unwrap();
    let invalid_end = Utc.with_ymd_and_hms(2023, 1, 1, 10, 0, 0).unwrap();
    
    match Interval::new(invalid_start, invalid_end) {
        Ok(interval) => println!("创建成功: {:?}", interval),
        Err(e) => println!("创建失败: {}", e),
    }
}

这个完整示例演示了intervallum库的主要功能,包括时间区间的创建、关系判断、数学运算、时间间隔计算以及多区间处理。示例中还包含了错误处理的演示,展示了如何正确处理无效的时间区间输入。

回到顶部