Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoding/Decoding ISO-8601 #43

Closed
anowell opened this issue Aug 19, 2015 · 8 comments
Closed

Encoding/Decoding ISO-8601 #43

anowell opened this issue Aug 19, 2015 · 8 comments

Comments

@anowell
Copy link

anowell commented Aug 19, 2015

What are your thoughts on serialization to and from ISO-8601 strings?

I'm looking to decode an API response with something along these lines:

#[derive(RustcDecodable)]
struct Foo {
  name: String,
  created_at: DateTime<UTC>, // or perhaps a type the Derefs into DateTime?
}

let json_str = r#"{name: "bar", "created_at": "2015-05-01T21:48:27.000Z"}"#;
let foo: Foo = json::decode(json_str).unwrap();

Currently such decode returns in Err(ExpectedError("Object", "\"2015-05-01T21:48:27.000Z\""))

Just trying to figure out if I'll be re-inventing the wheel, or if this is something that fits within the scope of Chrono.

@anowell
Copy link
Author

anowell commented Aug 21, 2015

For anybody who stumbles onto this with the same problem, here's how I'm accomplishing this for now:

#[derive(Debug)]
pub struct FileEntry {
    pub filename: String,
    pub size: u64,
    pub last_modified: DateTime<UTC>,
}

impl Decodable for FileEntry {
    fn decode<D: Decoder>(d: &mut D) -> Result<FileEntry, D::Error> {
        d.read_struct("root", 0, |d| {
            Ok(FileEntry{
                filename: try!(d.read_struct_field("filename", 0, |d| Decodable::decode(d))),
                size: try!(d.read_struct_field("size", 0, |d| Decodable::decode(d))),
                last_modified: {
                    let json_str: String = try!(d.read_struct_field("last_modified", 0, |d| Decodable::decode(d)));
                    match json_str.parse() {
                        Ok(datetime) => datetime,
                        Err(err) => return Err(d.error(err.description())),
                    }
                },
            })
        })
    }
}

@lifthrasiir
Copy link
Contributor

Probably fixing this would also fix #42 and vice versa. I'm almost dormant nowadays but looking forward to fix this. Thank you for reports.

@lifthrasiir lifthrasiir self-assigned this Aug 23, 2015
@eugene-bulkin
Copy link

Is there anything particularly bad about the following implementations of Decodable and Encodable?

impl Decodable for DateTime<UTC> {
  fn decode<D: Decoder>(d: &mut D) -> Result<Outcome, D::Error> {
    let field = try!(d.read_str());
    match field.parse() {
      Ok(result) => Ok(result),
      Err(_) => Err(d.error(&*format!("Could not parse '{}' as a DateTime<UTC>.", field)))
    }
  }
}

impl Encodable for DateTime<UTC> {
  fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
    s.emit_str(self.to_rfc3339())
  }
}

@dbrgn
Copy link
Contributor

dbrgn commented Mar 22, 2016

I'm also facing this problem. Serialization to ISO format would be great.

@WangBoxue
Copy link

I am facing this problem too.

I want to use rustc-serialize to encode DateTime<UTC>, but the format is not what I want.

{"datetime":{"date":{"ymdf":16517731},"time":{"secs":13054,"frac":411723000}},"offset":{}}

It will be great if it can be encoded to ISO-8601.
I know I can implement Encodable for my struct and use &+ to format the datetime field, but I have to encode other fields.

Is there any way to specify the format for DateTime when serializaiton?

@jonas-schievink
Copy link

There are now functions for this, but they might not be completely correct: I'd expect 19980717T14:08:55 to parse successfully, but it currently report an "input contains invalid characters" error.

@lifthrasiir
Copy link
Contributor

@jonas-schievink I think the documentation for parse_from_rfc3339 method clearly states that RFC 3339 is a subset (or more accurately, a profile) of ISO 8601 syntax. RFC 3339 requires you to have - and :.

(Why is the "full" ISO 8601 syntax unsupported? That's because ISO 8601 is in some sense a standard template, and requires a reasonable subset to be actually implemented. ISO 8601 covers very large usage cases and implementing all of them is close to waste---for example, you can write something like 2016-08-13T15:37.1234 to specify a fractional minute. There are also several edge cases that need the explicit agreement among clients, including dates before 1583 CE [for proleptic Gregorian] and also before 1 BCE [for extended format for year numbers]. A well-known and widely-used subsets like RFC 3339 are enough for Chrono's intended use cases.)

@pitdicker
Copy link
Collaborator

The rustc-serialize feature is deprecated, so I am going to close this issue.
We have #587 for parsing the full ISO 8601 format, and an open PR #1143.

@pitdicker pitdicker closed this as not planned Won't fix, can't repro, duplicate, stale Sep 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants