如何用Rust从DuckDB正确获取datetime类型并解决日期转换异常?
问题原因
DuckDB的DATE类型在duckdb = { version = "0.10.2", features = ["bundled"] }中,默认以自1970-01-01(Unix纪元)以来的天数返回,而NaiveDate::from_num_days_from_ce的计数基准是公元1年1月1日(CE),两者基准差了近2000年,直接转换必然得到错误日期。
比如你提到的2017-12-18,在DuckDB中对应的天数是17532(从1970-01-01到该日期的天数),将这个数值直接传入from_num_days_from_ce,得到的就是公元48年12月17日,和你看到的结果完全匹配。
修复方案
有两种可靠的转换方式:
方式一:基于Unix纪元偏移计算
利用chrono的日期加减能力,先构造Unix纪元起始日期,再加上DuckDB返回的天数:
use chrono::{NaiveDate, Duration}; // 替换原代码中scan_date的定义行 let unix_epoch = NaiveDate::from_ymd(1970, 1, 1); let scan_date = unix_epoch + Duration::days(scan_date_days as i64);
方式二:固定基准差值转换
先算出1970-01-01对应的CE起始天数(固定值为719163),将DuckDB返回的天数加上该值后再调用from_num_days_from_ce:
use chrono::NaiveDate; const UNIX_EPOCH_CE_DAYS: i32 = 719163; // 替换原代码中scan_date的定义行 let scan_date = NaiveDate::from_num_days_from_ce(scan_date_days + UNIX_EPOCH_CE_DAYS);
关于无法使用
from_num_days_from_ce_opt的说明 from_num_days_from_ce_opt是chrono 0.4.20及以上版本新增的方法,如果你的chrono依赖版本低于这个范围,就无法调用。检查Cargo.toml中的chrono版本,升级到最新稳定版即可解决。
内容的提问来源于stack exchange,提问作者alanwilter
相关产品推荐
相关产品推荐

