###### tags: `Rust` `chrono` `chrono-tz` `time`
# Rust 時刻ライブラリ chrono
Rustにおける、事実上の標準ライブラリ
時刻やタイムゾーンの取得&計算を行う
Rustは標準ライブラリに入れるような機能も外部ライブラリにする。
標準ライブラリにしてしまうと、機能のアップデートが慎重になってしまうため
# 主な概念
## Datetime
日付、時刻、タイムゾーン情報の入った、最も重要なコアオブジェクト
ジェネリック型であり、4種類ある
- Datetime\<Utc> : ユニバーサル時間
- Datetime\<Local> : 実行しているPCのTZを使った時間
- DateTime\<FixedOffset> : UTCから手動でN時間づらされた日時型
```rust=
extern crate chrono;
use chrono::{DateTime, Local};
let utc: DateTime<Utc> = Utc::now();
let local: DateTime<Local> = Local::now();
```
とりあえず、now()から作り出す方法だけ覚えとけばOk
## Duration
1日, 1時間, 1分, 1秒など
時刻ではなく間隔を表すオブジェクト
```rust=
use chrono::{Duration};
let seconds: Duration = Duration::seconds(3);
let minutes: Duration = Duration::minutes(4);
let day: Duration = Duration::days(1);
day.num_days();
day.num_hours();
day.num_minutes();
day.num_seconds();
```
# 日付の計算
```rust=
// 日付の足し算
let three_days_ago = utc + three_days;
println!("{}", three_days_ago);
// 日付の引き算
let today = three_days_ago - three_days;
println!("{}", today);
let new_duration: chrono::Duration = three_days_ago - today;
println!("{}", new_duration.num_days());
// UTC と Local TZ 同士は計算できない
let new_date = utc - local; //error
```
いくつかのパターンが有る
- Datetime - Datetime = Duration
- Datetime +- Duration = Datetime
- Duration +- Duration = Duration
# Datetime を 文字列フォーマットに変換
比較的メジャーなフォーマットである
- RFC3339
- タイムスタンプのインターネット標準。
- 今後登場する新しいプロトコルで標準的に利用される。
- "YYYY-MM-DDTHH:MM:SS+-HH:MM"
- RFC2822
- 電子メール、HTTPヘッダの標準日時
- "Wek, DD MMM YYYY HH:MM:SS +-HHMM"
には普通にデフォルトで相互変換できる
## メソッド
- Datetime.to_rfcXXXX()
- chrono::DateTime::parse_from_rfcXXXX(&str)
```rust=
#[test]
fn test(){
extern crate chrono;
let utc = chrono::Utc::now();
let rfc3339 = utc.to_rfc3339();
let new_date = chrono::DateTime::parse_from_rfc3339(&rfc3339);
println!("{:?}", new_date);
}
```
参考
https://www.kanzaki.com/docs/html/dtf.html
# UNIX time
## 類義語
- エポック秒
- POSIX time
## 概要
UNIXエポック = 協定世界時間 = UTC における、
1970年1月1日午前0時0分0秒 からの形式的な経過秒数のこと
多くのコンピューターでつかえる、フォーマルな単位
## chronoのDatetimeを unix秒 に変換する
```rust=
extern crate chrono;
let utc = chrono::Utc::now();
// i64型で帰ってくる。
let unix_sec = utc.timestamp() as f64;
let unix_nanosec = utc.timestamp_nanos() as f64;
// nano秒までを f64型で表現する
let sec = unix_sec + unix_nanosec / 1e9;
```
# 参考サイト
- Rustで日時を扱う
https://qiita.com/fujitayy/items/ae6175118cbed7134594
- Rustの日付時刻処理(std::time, time, chrono)
https://qnighy.hatenablog.com/entry/2019/04/21/190000
- Rustで日付、時刻を計算する
http://kikei.github.io/rust/2018/11/24/rust-chrono.html