8 个版本
0.1.6 | 2023年10月17日 |
---|---|
0.1.5 | 2023年10月16日 |
#120 在 日期和时间
每月 52 次下载
230KB
3K SLoC
cftime-rs
cftime-rs
是 cf 时间规范的 rust
实现。该项目提供了 Python 绑定,并使用优秀的 maturin 库。Python 绑定受到由 Unidata 开发的 cftime Python 包的极大启发。
文档 : Rust | Python
包 : Rust | Python
仓库 : Github
Rust
安装
cargo install cftime-rs
示例
解码
解码需要单位、日历,可以与 i32
、i64
、f32
、f64
以及它们对应的向量类型 Vec<i32>
、Vec<i64>
、Vec<f32>
和 Vec<f64>
一起工作。从这些类型中,它返回一个 CFDatetime
对象或一个 Vec<CFDatetime>
。
use cftime_rs::calendars::Calendar;
use cftime_rs::decoder::*;
use std::str::FromStr;
fn main() {
let to_decode = vec![0, 1, 2, 3, 4, 5];
let units = "days since 2000-01-01 00:00:00";
let calendar = Calendar::from_str("standard").unwrap();
let datetimes = to_decode.decode_cf(units, calendar).unwrap();
for datetime in datetimes {
println!("{}", datetime);
}
}
将打印
2000-01-01 00:00:00.000
2000-01-02 00:00:00.000
2000-01-03 00:00:00.000
2000-01-04 00:00:00.000
2000-01-05 00:00:00.000
2000-01-06 00:00:00.000
编码
编码需要单位和日历,可以将一个 CFDatetime
对象转换为 i32
,i64
,f32
或 f64
,或者将 Vec<CFDatetime>
转换为 Vec<i32>
,Vec<i64>
,Vec<f32>
或 Vec<f64>
。
use cftime_rs::calendars::Calendar;
use cftime_rs::datetime::CFDatetime;
use cftime_rs::encoder::*;
use cftime_rs::errors::Error;
use std::str::FromStr;
fn main() {
let calendar = Calendar::from_str("standard").unwrap();
// Create vector of datetimes and convert Vec<Result<CFDatetime, Error>>
// into Result<Vec<CFDatetime>, Error>
let to_encode: Result<Vec<CFDatetime>, Error> = vec![
CFDatetime::from_ymd(2000, 1, 1, calendar),
CFDatetime::from_ymd(2000, 1, 2, calendar),
CFDatetime::from_ymd(2000, 1, 3, calendar),
CFDatetime::from_ymd(2000, 1, 4, calendar),
CFDatetime::from_ymd(2000, 1, 5, calendar),
CFDatetime::from_ymd(2000, 1, 6, calendar),
]
.into_iter()
.collect();
// define the units
let units = "days since 2000-01-01 00:00:00";
// The type annotation for result allow us to cast to type we want
// here we use Vec<i64>
let results: Vec<i64> = to_encode.unwrap().encode_cf(units, calendar).unwrap();
for result in results {
println!("{}", result);
}
}
将打印
0
1
2
3
4
5
Python
安装
pip install cftime-rs
示例
解码为 PyCfDatetimes
import cftime_rs
to_decode = [0, 1, 2, 3, 4, 5]
units = "days since 2000-01-01 00:00:00"
calendar = "standard"
datetimes = cftime_rs.num2date(arr, units, calendar)
for datetime in datetimes:
print(datetime)
将打印
2000-01-01 00:00:00.000
2000-01-02 00:00:00.000
2000-01-03 00:00:00.000
2000-01-04 00:00:00.000
2000-01-05 00:00:00.000
2000-01-06 00:00:00.000
编码 PyCfDatetimes
calendar = cftime_rs.PyCFCalendar.from_str("standard")
to_encode = [
cftime_rs.PyCFDatetime.from_ymd(2000, 1, 1, calendar),
cftime_rs.PyCFDatetime.from_ymd(2000, 1, 2, calendar),
cftime_rs.PyCFDatetime.from_ymd(2000, 1, 3, calendar),
cftime_rs.PyCFDatetime.from_ymd(2000, 1, 4, calendar),
cftime_rs.PyCFDatetime.from_ymd(2000, 1, 5, calendar),
cftime_rs.PyCFDatetime.from_ymd(2000, 1, 6, calendar),
]
units = "days since 2000-01-01 00:00:00"
calendar = "standard"
numbers = cftime_rs.date2num(to_encode, units, calendar, dtype="int")
for number in numbers:
print(number)
将打印
0
1
2
3
4
5
解码为 Python 日期时间
to_decode = [0, 1, 2, 3, 4, 5]
units = "days since 2000-01-01 00:00:00"
calendar = "standard"
datetimes = cftime_rs.num2pydate(to_decode, units, calendar)
for datetime in datetimes:
print(datetime)
将打印
2000-01-01 00:00:00
2000-01-02 00:00:00
2000-01-03 00:00:00
2000-01-04 00:00:00
2000-01-05 00:00:00
2000-01-06 00:00:00
解码 Python 日期时间
to_encode = [
dt.datetime(2000, 1, 1),
dt.datetime(2000, 1, 2),
dt.datetime(2000, 1, 3),
dt.datetime(2000, 1, 4),
dt.datetime(2000, 1, 5),
dt.datetime(2000, 1, 6),
]
units = "days since 2000-01-01 00:00:00"
calendar = "standard"
numbers = cftime_rs.pydate2num(to_encode, units, calendar, dtype="int")
for number in numbers:
print(number)
将打印
0
1
2
3
4
5
已知问题
尽管这个日期计算库可以处理从大约公元前 291,672,107,014 年到公元 291,672,107,014 年的广泛日期,但仍有一些性能考虑因素您应该了解。随着您远离参考日期 1970-01-01 00:00:00,计算时间会增加。这是因为库需要考虑各种历法中的闰年。
以下是在发布模式下使用个人计算机上的 "自 2000-01-01 00:00:00 以来秒数" 单位计算 1_000_000_000_000_000 秒的示例
日历 | 计算时间 |
---|---|
标准日历 | 44.470405ms |
闰日日历 | 8.052179ms |
360 天日历 | 12.834µs |
与 cftime 的比较
以下是在我计算机上对三种方法的基准测试。这并不十分严格,但这是为了提供一个概念。
我们比较了 cftime 与 cftime_rs。第一种方法涉及使用标准日历解码一系列数字,调用 .str() 方法,然后将它们重新编码到相同的单位和日历。第二种方法是不调用 .str(),使用标准日历解码一系列数字并将它们重新编码到相同的单位和日历。第三种方法是将标准日历解码的一系列数字解码为 python 日期时间,然后不调用 .str() 将它们重新编码到相同的单位和日历。
第一种和第二种方法旨在在两个库之间保持公平,因为 cftime_rs 仅使用时间戳 (i64) 作为其内部表示,并且从不重新计算年、月、日、小时、分钟和秒,除非您明确请求此表示。
依赖关系
~4–10MB
~95K SLoC