#Rust #serde #chrono
https://serde.rs/custom-date-format.html
[[Chrono]]を使う。`Cargo.toml`には`features`を指定する。
```toml
chrono = { version = "0.4.19", features = ["serde"] }
```
## Custom formatの設定
[[RFC3339]]のフォーマット以外を使う場合はCustom formatの指定が必要。 たとえば`YYYYMMDD`形式..(例: 20200228)を扱う場合は以下のmoduleを定義する。
```rust
pub mod yyyymmdd {
use chrono::NaiveDate;
use serde::{self, Deserialize, Deserializer, Serializer};
const FORMAT: &str = "%Y%m%d";
pub fn serialize<S>(date: &NaiveDate, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = format!("{}", date.format(FORMAT));
serializer.serialize_str(&s)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDate, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveDate::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
}
}
```
### 参考
- [[timezoneのない日付のみを表す (Chrono)]]
## serdeでcustom formatを適応
```rust
// serde_chrono_customは先ほど定義したモジュール
use crate::serde_chrono_custom::yyyymmdd;
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
pub struct Calendar {
#[serde(with = "yyyymmdd")]
start_date: NaiveDate,
}
```
これで`20200228`は`2020年2月28日`の`NaiveDate`としてSerialize/Deserializeできる。