You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Rust Chrono中解析Zulu时间后缀应使用哪种格式?

Chrono与Python strptime解析Zulu时间的差异及解决方案

问题描述

我在使用Rust的Chrono库解析时间字符串时遇到了如下问题:

  • 当时间字符串为"2000-01-01T01:23+01:00"时,用格式字符串"%Y-%m-%dT%H:%M%z"可以正常解析:
use chrono::{DateTime};

fn main() {
    let parse_from_str = DateTime::parse_from_str;
    let ts = "2000-01-01T01:23+01:00";
    let fmt = "%Y-%m-%dT%H:%M%z";
    let parsed = parse_from_str(ts, fmt);
    println!("{:?}", parsed);
}

运行结果:

Ok(2000-01-01T01:23:00+01:00)
  • 但将时间字符串改为"2000-01-01T01:23Z"(Zulu时间,代表UTC+00:00)时,用相同格式字符串解析失败,返回:
Err(ParseError(Invalid))

而在Python中,使用完全相同的格式字符串"%Y-%m-%dT%H:%M%z"却能成功解析该Zulu时间:

import datetime as dt
dt.datetime.strptime("2000-01-01T01:23Z", "%Y-%m-%dT%H:%M%z")
# 输出:datetime.datetime(2000, 1, 1, 1, 23, 0, tzinfo=datetime.timezone.utc)

我有两个疑问:

  1. 这两种解析方式哪种是正确的?
  2. 我已知用let fmt = "%+";可以解析Zulu时间,但想知道能不能通过显式指定完整格式字符串实现解析?

问题解答

1. 两种解析方式的正确性

两种解析都是符合各自库的实现规范的,核心差异在于对%z格式符的定义不同:

  • Python的strptime对%z做了扩展实现,不仅支持标准的±HH:MM/±HHMM时区偏移格式,还兼容单独的Z字符(将其识别为UTC+00:00)
  • Rust Chrono库的%z严格遵循传统strftime的定义,仅匹配带符号的时区偏移格式(如+01:00、-0500),不识别单独的Z字符

2. 显式指定格式字符串解析Zulu时间

可以通过显式格式字符串实现,分两种场景处理:

仅解析Zulu时间(带Z的字符串)

直接把格式字符串中的时区部分指定为Z即可:

use chrono::{DateTime};

fn main() {
    let parse_from_str = DateTime::parse_from_str;
    let ts = "2000-01-01T01:23Z";
    let fmt = "%Y-%m-%dT%H:%MZ";
    let parsed = parse_from_str(ts, fmt);
    println!("{:?}", parsed);
}

运行结果:

Ok(2000-01-01T01:23:00+00:00)

同时兼容时区偏移和Zulu时间

Chrono的格式语法不支持正则分支或可选匹配,无法用单一格式字符串同时兼容两种情况。这种场景下可以:

  • 先用一种格式尝试解析,失败后再尝试另一种
  • 使用Chrono提供的parse_from_rfc3339方法(原生支持RFC3339标准中的所有时区表示,包括Z和偏移格式)
  • 或者使用你已经知道的%+格式(本质是RFC3339的完整格式)

内容的提问来源于stack exchange,提问作者ignoring_gravity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:25:35