Search code examples
rustserde

Rust Serde Serializing Iso8601 Time adds +00 prefix with quick_xml


I cannot for the life of me figure out why a "+00" prefix is being added to the serialized OffsetDateTime in my struct.

Here is an MRP: link

I annotate my struct in the following way:

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Wrapper {
    #[serde(with = "time::serde::iso8601")]
    pub time: OffsetDateTime,
}

But the result is the following string:

+002010-01-01T00:00:00.000000000Z

Perhaps this is a quick_xml bug? I have begun digging into quick_xml, but I was hoping someone might have encountered this issue.


Solution

  • The time crate serializes the year as six digits. I guess to be more future-proof in case your code survives 8,000 years? Not sure. The standard permits that. But you aren't supposed to be reading the serialization format anyway, so as long as both the serializer and deserializer agree on the number of digits, everything is fine.

    The standard also requires a plus or minus sign in case of expanded year digits.

    Edit: Found a github issue that talks about that: #548, and it also tells how to serialize using four digits:

    use time::format_description::well_known::{Iso8601, iso8601};
    const FORMAT: _ = Iso8601<{ iso8601::Config::DEFAULT.set_year_is_six_digits(false).encode() }>;
    time::serde::format_description!(my_format, OffsetDateTime, FORMAT);
    

    That generates a my_format module that you can use in conjunction with #[serde(with)].