【Rust】SystemTimeをString型の年月日に変換したい

2022/03/21に公開

Rustを使ってファイルのメタデータ(ファイルの作成日時)を取得
String型にして、ファイルの作成日時が名前になっているフォルダを作成し
ファイルを振り分けるプログラムを組もうと思っていたのですが、
メタデータから取得した作成日時をString型にするところで
つまづいたので備忘録として残そうと思います。

メタデータの取得

以下の方法でメタデータを取得しました。

use std::fs::{File, Metadata};

fn get_meta_data(file: File) -> Result<Metadata, Box<dyn, std::error::Error>>{
    let meta = file.metadata()?;
    Ok(meta)
}

これで取得したMetadataから
作成日時を取得するにはcreatedメソッドで取れるのですが、
型がSystemTimeのため
ここからどうやってString型に変換しようか……という状態でした。

let open_file = match File::open("Your file path"){
    Ok(val) => val,
    Err(e) => {
        println!("ファイルのオープンに失敗しました。: {}", e);
    }
}

let meta = match get_meta_data(open_file){
    Ok(val) => val,
    Err(e) => {
        println!("メタデータの取得に失敗しました。: {}", e);
    } 
}

let created_time = meta.created().unwrap();

chronoクレートを使って変換するのじゃ

公式ドキュメントやStackOverflowに似たような内容がないか
いろいろ調べ回り、
最終的にchronoを使うのがいいのじゃ
という結論に行きつきました。

chronoを使うためにはCargo.tomldependenciesに以下を追加し
cargo buildする必要があります。

chrono = "0.4.18"

文字列で取得するコードは以下

extern crate chrono;
use chrono::prelude::{DateTime, Utc, Datelike};

[中略]

let created_time = meta.created().unwrap();
let created_time: DateTime<Utc> = crated_time.into();
let created_time = format_utc_to_string(&created_time);

fn format_utc_to_string(utc_time: &DateTime<Utc>) -> String{
    format!("{}{:02}{:02}", utc_time.year(), utc_time.month(), utc_time.day())
}

C#やPythonでは簡単に取得するメソッドがあったりするのですが、
Rustは少し遠回りする必要があるのと、
遠回りするために新しい知識を勉強できるので楽しいですね!

Discussion