Skip to content

reconsider whether civil datetimes can be parsed from strings that contain offsets #323

@BurntSushi

Description

@BurntSushi

Currently, this program runs and the assertion passes:

fn main() -> anyhow::Result<()> {
    let dt: jiff::civil::DateTime = "2025-07-19T17:50-04".parse()?;
    assert_eq!(dt.to_string(), "2025-07-19T17:50:00");
    Ok(())
}

This behavior is borrowed from Temporal. In general, Temporal allows parsing "smaller" types from "bigger" strings. Although, Jiff, like Temporal, does specifically reject the case when the offset is Z. This program:

fn main() -> anyhow::Result<()> {
    let dt: jiff::civil::DateTime = "2025-07-19T17:50Z".parse()?;
    assert_eq!(dt.to_string(), "2025-07-19T17:50:00");
    Ok(())
}

gives this output:

Error: cannot parse civil date from string with a Zulu offset, parse as a `Timestamp` and convert to a civil datetime instead

I believe this was done because the specific case of trying to interpret an RFC 3339 timestamp in Zulu time as local time is a particularly common source of bugs.

I do question whether the broader category of "parsing local time from a string that identifies an instant" is also a potential source of bugs.

I lean towards following in Temporal's footsteps here, but:

  • This would be a breaking change, so if we do it, it needs to be done at or before jiff 1.0 is released.
  • The conservative position is to do this breaking change, and if use cases really warrant this kind of parsing succeeding, then we can remove the error in a semver compatible release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking changeIssues that require a breaking change for resolution.questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions