3个版本 (破坏性)
0.3.0 | 2022年11月5日 |
---|---|
0.2.0 | 2022年11月1日 |
0.1.0 | 2022年10月31日 |
#261 in 日期和时间
每月316次下载
30KB
286 行
chrono-intervals:Rust的时间间隔分组
创建按“每日”、“每周”等间隔的chrono时间间隔。
用法
获取间隔的最方便方式是创建一个 IntervalGenerator
。
use chrono::{DateTime, TimeZone, Utc};
use chrono_intervals::{IntervalGenerator};
let begin = DateTime::parse_from_rfc3339("2022-06-25T08:23:45.000000Z").unwrap();
let end = DateTime::parse_from_rfc3339("2022-06-27T09:31:12.000000Z").unwrap();
let daily_intervals = IntervalGenerator::new().get_intervals(begin, end);
assert_eq!(
daily_intervals,
vec![
(
Utc.ymd(2022, 6, 25).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 25).and_hms_milli(23, 59, 59, 999),
),
(
Utc.ymd(2022, 6, 26).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 26).and_hms_milli(23, 59, 59, 999),
),
(
Utc.ymd(2022, 6, 27).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 27).and_hms_milli(23, 59, 59, 999),
),
]
);
IntervalGenerator
可以以多种方式配置。让我们看看获取每月间隔但位于太平洋夏令时(PDT)时区的示例
use chrono::{DateTime, TimeZone, Utc};
use chrono_intervals::{Grouping, IntervalGenerator};
// We want to obtain monthly intervals for month in PDT instead of in UTC.
let begin = DateTime::parse_from_rfc3339("2022-06-10T12:23:45.000000-07:00").unwrap();
let end = DateTime::parse_from_rfc3339("2022-08-26T12:23:45.000000-07:00").unwrap();
// PDT is 7h behind of UTC (towards the **west**), thus the
// `offset_west_seconds` are 7*3600
let pdt_offset_west_seconds = 7 * 3600;
let monthly_intervals = IntervalGenerator::new()
.with_grouping(Grouping::PerMonth)
.with_offset_west_secs(pdt_offset_west_seconds)
.get_intervals(begin, end);
// In UTC, we expect the intervals to start 7h after the month boundary.
assert_eq!(
monthly_intervals,
vec![
(
Utc.ymd(2022, 6, 1).and_hms(7, 0, 0),
Utc.ymd(2022, 7, 1).and_hms_milli(6, 59, 59, 999),
),
(
Utc.ymd(2022, 7, 1).and_hms(7, 0, 0),
Utc.ymd(2022, 8, 1).and_hms_milli(6, 59, 59, 999),
),
(
Utc.ymd(2022, 8, 1).and_hms(7, 0, 0),
Utc.ymd(2022, 9, 1).and_hms_milli(6, 59, 59, 999),
),
]
);
配置选项和默认值
以下是可配置选项及其默认值的概述
- 间隔分组:您可以选择
Grouping
中表示的任何分组,默认为PerDay
。 - 一个间隔的结束和下一个间隔的开始之间的时间跨度(精度):默认为1毫秒,但可以通过传递任意值来覆盖。您可能希望将其设置为仍认为合理的最短时间跨度,例如毫秒或微秒。
- 相对于您本地时区的西偏秒数:如果您想获取太平洋夏令时(PDT)的间隔,例如在GMT-7,您需要传递
7*3600
秒的时间差,西偏值以正数表示。例如,中欧时间(CET)在GMT+1,需要-3600
秒的西偏值。 - 第一个间隔是否扩展到
begin
之前:默认情况下,第一个间隔将在begin
的边界之前开始。如果您想只有完全在begin
之后的完整间隔,可以关闭此选项。 - 最后一个间隔是否扩展到
end
之后:默认情况下,最后一个间隔将在end
的边界之后结束。如果您想只有完全在end
之前的完整间隔,可以关闭此选项。
让我们看看使用所有配置选项的示例
use chrono::{DateTime, Duration, TimeZone, Utc};
use chrono_intervals::{Grouping, IntervalGenerator};
let begin = DateTime::parse_from_rfc3339("2022-10-02T08:23:45.000000Z").unwrap();
let end = DateTime::parse_from_rfc3339("2022-10-18T08:23:45.000000Z").unwrap();
let inter_gen = IntervalGenerator::new()
.with_grouping(Grouping::PerWeek)
.with_precision(Duration::microseconds(1))
.with_offset_west_secs(-3600)
.without_extended_begin()
.without_extended_end();
let weekly_intervals = inter_gen.get_intervals(begin, end);
assert_eq!(
weekly_intervals,
vec![
(
Utc.ymd(2022, 10, 2).and_hms(23, 0, 0),
Utc.ymd(2022, 10, 9).and_hms_micro(22, 59, 59, 999999),
),
(
Utc.ymd(2022, 10, 9).and_hms(23, 0, 0),
Utc.ymd(2022, 10, 16).and_hms_micro(22, 59, 59, 999999),
),
]
);
使用函数而不是生成器
生成器是最方便的方法。但是,您也可以使用两种不同的函数来获取间隔。
get_extended_utc_intervals
返回包含begin
和end
的分组区间,精度为 1 毫秒。这与默认的IntervalGenerator
行为非常相似,只是您需要指定一个Grouping
。get_utc_intervals_opts
返回分组区间,并允许指定生成器接受的全部选项。
示例
使用默认选项获取两个时间之间的每日区间
use chrono::{DateTime, TimeZone, Utc};
use chrono_intervals::{Grouping, get_extended_utc_intervals};
let begin = DateTime::parse_from_rfc3339("2022-06-25T08:23:45.000000Z").unwrap();
let end = DateTime::parse_from_rfc3339("2022-06-27T09:31:12.000000Z").unwrap();
let daily_intervals =
get_extended_utc_intervals(begin, end, &Grouping::PerDay, 0);
assert_eq!(
daily_intervals,
vec![
(
Utc.ymd(2022, 6, 25).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 25).and_hms_milli(23, 59, 59, 999),
),
(
Utc.ymd(2022, 6, 26).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 26).and_hms_milli(23, 59, 59, 999),
),
(
Utc.ymd(2022, 6, 27).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 27).and_hms_milli(23, 59, 59, 999),
),
]
);
使用默认选项在太平洋夏令时 (PDT) 时区获取月度区间
use chrono::{DateTime, TimeZone, Utc};
use chrono_intervals::{Grouping, get_extended_utc_intervals};
// We want to obtain monthly intervals for months in PDT instead of in UTC.
let begin = DateTime::parse_from_rfc3339("2022-06-10T12:23:45.000000-07:00").unwrap();
let end = DateTime::parse_from_rfc3339("2022-08-26T12:23:45.000000-07:00").unwrap();
// PDT is 7h behind of UTC (towards the **west**), thus the
// `offset_west_seconds` are 7*3600
let pdt_offset_west_seconds = 7 * 3600;
let monthly_intervals =
get_extended_utc_intervals(begin, end, &Grouping::PerMonth, pdt_offset_west_seconds);
// In UTC, we expect the intervals to start 7h after the day boundary.
assert_eq!(
monthly_intervals,
vec![
(
Utc.ymd(2022, 6, 1).and_hms(7, 0, 0),
Utc.ymd(2022, 7, 1).and_hms_milli(6, 59, 59, 999),
),
(
Utc.ymd(2022, 7, 1).and_hms(7, 0, 0),
Utc.ymd(2022, 8, 1).and_hms_milli(6, 59, 59, 999),
),
(
Utc.ymd(2022, 8, 1).and_hms(7, 0, 0),
Utc.ymd(2022, 9, 1).and_hms_milli(6, 59, 59, 999),
),
]
);
为 get_utc_intervals_opts
指定选项
use chrono::{DateTime, Duration, TimeZone, Utc};
use chrono_intervals::{Grouping, get_utc_intervals_opts};
let begin = DateTime::parse_from_rfc3339("2022-06-15T08:23:45.000000Z").unwrap();
let end = DateTime::parse_from_rfc3339("2022-06-30T09:31:12.000000Z").unwrap();
let weekly_intervals =
get_utc_intervals_opts(
begin,
end,
&Grouping::PerWeek,
0,
Duration::microseconds(1), // interval end is 1µs before the next
false, // start on the boundary after `start`
true, // end at the boundary after `end`
);
assert_eq!(
weekly_intervals,
vec![
(
// First interval begins **after** `begin`
Utc.ymd(2022, 6, 20).and_hms(0, 0, 0),
Utc.ymd(2022, 6, 26).and_hms_micro(23, 59, 59, 999999),
),
(
Utc.ymd(2022, 6, 27).and_hms(0, 0, 0),
// Last interval ends **after** `end`
Utc.ymd(2022, 7, 3).and_hms_micro(23, 59, 59, 999999),
),
]
);
依赖项
~1MB
~18K SLoC