この記事は、Rustアドベントカレンダー15日目の記事です。
Rustで日付の計算を行う便利なcrateにtimeというものがあります。
timeは、二種類あって、rust本体に組み込まれているtimeとcrateに分離されているtimeがあります。
std::time
https://doc.rust-lang.org/beta/std/time/index.html
crate time
https://github.com/rust-lang-deprecated/time
std::timeの方は、stable では 現状Duration(時間間隔) の計算しか行うことが出来ず、不便です。
let five_seconds = Duration::new(5, 0);
let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
let ten_millis = Duration::from_millis(10);
それと比べて crate の time の方は、現在時間が取得できたり、日付をstrftimeで出力できたりと便利な機能が揃っています。
crates.io にも公開されているので、crates 版 time を使ってしまいそうになると思いますが、URLから分かる通り(rust-lang-deprecated)、非推奨なcrateなのです。
なので、極力 std:time の方を使ったほうが良いのですが、そもそもnowもなかったりするので、使いたくても使いにくい状況ではあります。
どうしてもcrate版timeを使いたい時の注意点
どうしてもcrate版timeを使いたいときは注意点があります。
これはJST環境で、2015-12-14 20:40:01
のタイミングで実行した結果ですが、
extern crate time as crateTime;
use crateTime::Duration as crareTimeDuration;
fn main() {
// 今の日時
let now = crateTime::now();
println!("{:?}", crateTime::strftime("%Y-%m-%d %H:%M:%S", &now).unwrap());
// => "2015-12-14 20:40:01"
// 日付の計算
let yesterday = now - crareTimeDuration::days(1);
println!("{:?}", crateTime::strftime("%Y-%m-%d %H:%M:%S", &yesterday).unwrap());
// => "2015-12-13 11:40:01"
// 本当の日付の計算
let real_yesterday = now - crareTimeDuration::days(1) + crareTimeDuration::hours(9);
println!("{:?}", crateTime::strftime("%Y-%m-%d %H:%M:%S", &real_yesterday).unwrap());
// => "2015-12-13 20:40:01"
}
なんということでしょう。。。
今の日時は、正常な日付を出力しているのに、日付の計算を行うと、強制的にUTCになります。UTC環境のシステムであれば問題ないですが、JST環境においては日付の計算を行う際に、9時間加算する必要があります。
最後に
この記事では、
rust 1.4.0
time 0.1.34
の環境で実行しています。