从 NaiveDateTime 转换为 DateTime<Local>

10
Rust的chrono在处理时区转换方面非常令人沮丧。
例如:我的用户输入一个字符串。我使用NaiveDateTime::parse_from_str将其解析为本地日期时间。现在我想将其转换为DateTime<Local>
不幸的是,我似乎找不到如何做到这一点。使用Local::From不起作用。使用DateTime<Local>::from()也不起作用。两个结构体都没有从NaiveDateTime进行转换的方法,而NaiveDateTime也没有将其转换为Local的方法。
然而,我们可以做到这样的事情:someLocalDateTime.date().and_time(some_naive_time)。那么为什么我们不能只做Local::new(some_naive_date_time)呢?
此外,为什么我们不能跳过解析中的某些字段?我不需要秒和年份。为了假定当前年份和0秒,我必须手动编写解析代码并从ymd hms构造日期时间。
1个回答

13

这个功能由chrono::offset::TimeZone trait提供。具体来说,TimeZone::from_local_datetime方法几乎完全符合您的需求。

use chrono::{offset::TimeZone, DateTime, Local, NaiveDateTime};

fn main() {
    let naive = NaiveDateTime::parse_from_str("2020-11-12T5:52:46", "%Y-%m-%dT%H:%M:%S").unwrap();
    let date_time: DateTime<Local> = Local.from_local_datetime(&naive).unwrap();
    println!("{:?}", date_time);
}

(游乐场)


至于另一个关于假设解析的问题,我不确定是否已经存在这样的工具。如果ParseResult允许您在展开(或类似操作)结果之前手动设置特定值,那将是很酷的。

一个想法是手动将额外的字段添加到解析字符串中,这样您仍然可以使用chrono的解析器。

例如:

use chrono::{offset::TimeZone, DateTime, Datelike, Local, NaiveDateTime};

fn main() {
    let time_string = "11-12T5:52"; // no year or seconds
    let current_year = Local::now().year();
    let modified_time_string = format!("{}&{}:{}", time_string, current_year, 0);

    let naive = NaiveDateTime::parse_from_str(&modified_time_string, "%m-%dT%H:%M&%Y:%S").unwrap();
    let date_time: DateTime<Local> = Local.from_local_datetime(&naive).unwrap();
    println!("{:?}", date_time); // prints (as of 2020) 2020-11-12T05:52:00+00:00
}

(playground)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接