Rustで日付と時刻を扱う際は、chrono
クレートを使用するのが一般的です。
この記事では、chrono
クレートを使用してRustで日付を扱う基本的な方法を紹介します。
はじめに
Rustのchrono
クレートは、日付と時刻の操作に関連する機能を提供します。
UTCとタイムゾーン対応の両方の日時、時間の操作、フォーマットと解析など、さまざまな機能が含まれています。chrono
を使用する前に、Cargo.tomlファイルに依存関係を追加する必要があります。
[dependencies]
chrono = "0.4"
chronoが提供する主要なデータ型
chrono
クレートは、Rustで日付と時刻を扱うための複数のデータ型を提供します。
それぞれ用途と精度のニーズに応じて設計されています。主要なデータ型には以下です。
DateTime
: タイムゾーン付きの日時を表します。UTCやローカルタイムゾーンでの日時を扱うのに使用します。NaiveDateTime
: タイムゾーンのない日時を表します。単に年、月、日、時、分、秒を格納しますが、その時間がどのタイムゾーンに属するかは考慮しません。NaiveDate
: タイムゾーンのない日付のみを表します。年、月、日の情報を含みます。NaiveTime
: タイムゾーンのない時刻のみを表します。時、分、秒(および必要に応じてナノ秒)の情報を含みます。Duration
: 期間または時間の長さを表します。日数、時間、分、秒を扱うことができます。
スポンサーリンク
現在時刻の取得
現在の日時を取得するには、chrono
のUtc::now()
またはLocal::now()
を使用します。
UTCで現在時刻を取得
以下はUTCの現在時刻を取得する例です。
use chrono::Utc;
fn main() {
let now = Utc::now();
println!("{}", now);
}
ローカルタイムゾーンで現在時刻を取得
以下はローカルタイムゾーンの現在時刻を取得する例です。
use chrono::Local;
fn main() {
let now = Local::now();
println!("{}", now);
}
指定した日時の日付オブジェクト生成
特定の日時を指定して日付オブジェクトを生成する方法を紹介します。
NaiveDate
// 2023/02/25
let date = NaiveDate::from_ymd_opt(2023, 2, 25).unwrap();
このコードは、NaiveDate::from_ymd_opt
関数を使用して、年月日を指定してNaiveDate
オブジェクトを生成します。この関数は、有効な日付であればSome(NaiveDate)
を返し、無効な日付(例えば、2月に31日を指定した場合など)であればNone
を返します。unwrap()
メソッドを使用することで、Option
から値を取り出していますが、実際のアプリケーションでは無効な日付に対する適切なエラーハンドリングを行うべきです。
NaiveTime
// 12:00:00
let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
NaiveDateTime
NaiveDate::from_ymd
とNaiveTime::from_hms
を組み合わせ、NaiveDateTime
を作成します。
let date = NaiveDate::from_ymd_opt(2023, 2, 25).unwrap();
let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
let datetime: NaiveDateTime = NaiveDateTime::new(date, time);
DateTime<UTC>
let dt: DateTime<Utc> = Utc.with_ymd_and_hms(2015, 5, 15, 0, 0, 0).unwrap();
このコードは、UTCタイムゾーンで特定の年月日と時刻を持つDateTime<Utc>
オブジェクトを生成します。
DateTime<Local>
let dt = Local.with_ymd_and_hms(2022, 7, 5, 10, 14, 31);
println!("{}", dt.unwrap());
このコードは、ローカルタイムゾーンで特定の年月日と時刻を持つDateTime<Local>
オブジェクトを生成します。
日付の加減算
日付の加減算には、chrono::Duration
を使用します。以下の例では、日付に5日を加算し、その後10日を減算します。
use chrono::{Duration, NaiveDate};
fn main() {
let date = NaiveDate::from_ymd(2023, 2, 25);
let after_five_days = date + Duration::days(5);
let before_ten_days = after_five_days - Duration::days(10);
println!("Original date: {}", date);
println!("After 5 days: {}", after_five_days);
println!("Before 10 days from that: {}", before_ten_days);
}
時間の加減算もchrono::Duration
を使用します。以下の例では、日付に5時間を加算し、その後10時間を減算します。
use chrono::{Duration, NaiveDate, NaiveDateTime, NaiveTime};
fn main() {
let after_five_hours = datetime + Duration::hours(5);
let before_ten_hours = after_five_hours - Duration::hours(10);
println!("Original datetime: {}", datetime);
println!("After 5 hours: {}", after_five_hours);
println!("Before 10 hours from that: {}", before_ten_hours);
}
スポンサーリンク
文字列から日時オブジェクトを作成
文字列から日付と時刻のデータをパースすることができます。これは、ユーザー入力や外部データソースから日付や時刻を読み込む場合に特に便利です。以下では、chrono
を使用して異なる日付型のデータを文字列から作成する方法について解説します。
DateTimeの作成
DateTime
はタイムゾーン付きの日時を表します。UTCやローカルタイムゾーンなど、具体的なタイムゾーン情報を持つ日時のパースに使用します。
use chrono::{DateTime, Utc, TimeZone};
fn main() {
let datetime_str = "2023-02-25T12:00:00Z"; // ISO 8601形式の日時文字列
let datetime: DateTime<Utc> = Utc.datetime_from_str(datetime_str, "%+").unwrap();
println!("DateTime in UTC: {}", datetime);
}
このコードでは、ISO 8601形式の日時文字列をDateTime<Utc>
型にパースしています。%+
はchrono
でISO 8601形式の日時を解析するためのフォーマット指定子です。
NaiveDateTimeの作成
NaiveDateTime
はタイムゾーンのない日時を表します。これは、タイムゾーンに依存しないアプリケーションで使用されます。
use chrono::{NaiveDateTime};
fn main() {
let datetime_str = "2023-02-25 12:00:00"; // タイムゾーンのない日時文字列
let naive_datetime = NaiveDateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S").unwrap();
println!("NaiveDateTime: {}", naive_datetime);
}
ここでは、指定されたフォーマットの文字列をNaiveDateTime
にパースしています。フォーマット指定子%Y-%m-%d %H:%M:%S
は、年-月-日 時:分:秒を表します。
NaiveDateの作成
NaiveDate
はタイムゾーンのない日付だけを表します。
use chrono::NaiveDate;
fn main() {
let date_str = "2023-02-25"; // 日付文字列
let naive_date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d").unwrap();
println!("NaiveDate: {}", naive_date);
}
このコードでは、指定されたフォーマットの文字列をNaiveDate
にパースしています。フォーマット指定子%Y-%m-%d
は、年-月-日を表します。
NaiveTimeの作成
NaiveTime
はタイムゾーンのない時刻だけを表します。
use chrono::NaiveTime;
fn main() {
let time_str = "12:00:00"; // 時刻文字列
let naive_time = NaiveTime::parse_from_str(time_str, "%H:%M:%S").unwrap();
println!("NaiveTime: {}", naive_time);
}
ここでは、指定されたフォーマットの文字列をNaiveTime
にパースしています。フォーマット指定子%H:%M:%S
は、時:分:秒を表します。
これらの例を通じて、chrono
クレートを使用して文字列から様々な日付型のデータを作成する方法を学びました。文字列から日付や時刻をパースする際には、適切なフォーマット指定子を使用することが重要です。また、無効な日付やフォーマットの文字列をパースしようとするとNone
が返されるため、適切なエラーハンドリングを行う必要があります。
2つの日時を比較する
DateTime
、NaiveDate
、NaiveTime
の大小比較はシンプルです。基本的な比較演算子で大小比較が可能です。
NaiveDateの比較
NaiveDate
オブジェクトはタイムゾーンのない日付を表し、直接比較することができます。
use chrono::NaiveDate;
fn main() {
let date1 = NaiveDate::from_ymd_opt(2023, 2, 25).unwrap();
let date2 = NaiveDate::from_ymd_opt(2023, 3, 1).unwrap();
if date1 < date2 {
println!("date1 is earlier than date2.");
} else {
println!("date2 is earlier than or equal to date1.");
}
}
NaiveTimeの比較
NaiveTime
オブジェクトもタイムゾーンのない時刻を表し、直接比較が可能です。
use chrono::NaiveTime;
fn main() {
let time1 = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
let time2 = NaiveTime::from_hms_opt(14, 30, 0).unwrap();
if time1 < time2 {
println!("time1 is earlier than time2.");
} else {
println!("time2 is earlier than or equal to time1.");
}
}
異なるタイムゾーンのDateTime
比較
DateTime
オブジェクトはタイムゾーン情報を含んでいるため、異なるタイムゾーンの日時を直接比較することは、意図した結果を得ることができない可能性があります。たとえば、次の例では、UTCの現在時刻とローカルの現在時刻を比較していますが、これら2つの日時は実際には同じ瞬間を指しているにも関わらず、タイムゾーンの差によってUTCの方が「早い」と判断される可能性があります。
use chrono::{DateTime, Utc, Local};
fn main() {
let utc_datetime: DateTime<Utc> = Utc::now();
let local_datetime: DateTime<Local> = Local::now();
if utc_datetime < local_datetime {
println!("UTCの日時が早い");
} else if utc_datetime == local_datetime {
println!("日時が一致している");
} else if utc_datetime > local_datetime {
println!("UTCの日時が遅い");
}
}
異なるタイムゾーンのDateTime
オブジェクトを比較する場合、正確な比較のためには、両方のオブジェクトを同じタイムゾーンに変換することが重要です。以下の例では、with_timezone
メソッドを使用してローカル時刻をUTC時刻に変換し、タイムゾーンを統一してから比較を行っています。これにより、2つの日時が実際に同じ瞬間を指しているかどうかを正確に判断することができます。
use chrono::{DateTime, Utc, Local};
fn main() {
let utc_datetime: DateTime<Utc> = Utc::now();
let local_datetime: DateTime<Local> = Local::now();
// ローカル時刻をUTCに変換して比較
if utc_datetime < local_datetime.with_timezone(&Utc) {
println!("UTCの日時が早い");
} else if utc_datetime == local_datetime.with_timezone(&Utc) {
println!("日時が一致している");
} else if utc_datetime > local_datetime.with_timezone(&Utc) {
println!("UTCの日時が遅い");
}
}
このように、異なるタイムゾーン間での比較を正確に行うためには、比較前にタイムゾーンを揃える手順が不可欠です。with_timezone
メソッドを使うことで、異なるタイムゾーンの日時を同一のタイムゾーンに変換し、その上での比較が可能になります。
スポンサーリンク
2つの日時の日差・時間差を求める
2つの日付または日時の間の差(日差や時間差)を計算し、その結果を取得する方法を紹介します。
2つの日付の日差を求める
use chrono::{NaiveDate, Duration};
fn main() {
let date1 = NaiveDate::from_ymd_opt(2023, 2, 25).unwrap();
let date2 = NaiveDate::from_ymd_opt(2023, 2, 28).unwrap();
let time_delta: Duration = date2 - date1;
println!("date1とdate2の差は{}日です", time_delta.num_days());
}
この例では、NaiveDate::from_ymd_opt
関数を使用して2つのNaiveDate
オブジェクトを生成し、これらの日付の差を計算しています。date2 - date1
により、Duration
型のオブジェクトが生成され、このオブジェクトのnum_days
メソッドを使用して、2つの日付の差の日数を取得しています。
2つの日時の時間差を求める
use chrono::{NaiveDateTime, Duration};
fn main() {
let datetime1 = NaiveDateTime::parse_from_str("2023-02-25 12:00:00", "%Y-%m-%d %H:%M:%S").unwrap();
let datetime2 = NaiveDateTime::parse_from_str("2023-02-25 15:30:00", "%Y-%m-%d %H:%M:%S").unwrap();
let time_delta: Duration = datetime2 - datetime1;
println!("datetime1とdatetime2の差は{}分です", time_delta.num_minutes());
}
この例では、NaiveDateTime::parse_from_str
関数を使用して2つのNaiveDateTime
オブジェクトを生成し、これらの日時の差を計算しています。datetime2 - datetime1
により、Duration
型のオブジェクトが生成され、このオブジェクトのnum_minutes
メソッドを使用して、2つの日時の差の分数を取得しています。
Duration
の主要な関数
chrono
のDuration
型は、2つの日付や日時の差を表すために使用されます。Duration
オブジェクトは、以下のような主要な関数を提供しています:
num_seconds()
: 総秒数を返します。num_minutes()
: 総分数を返します。num_hours()
: 総時間数を返します。num_days()
: 総日数を返します。num_weeks()
: 総週数を返します。
0 件のコメント:
コメントを投稿