lab_resource_manager/interface/slack/utility/
datetime_parser.rs

1//! 日付・時刻パースユーティリティ
2
3use chrono::{DateTime, Local, NaiveDate, NaiveTime, TimeZone, Utc};
4
5/// 日付文字列と時刻文字列をUTC DateTimeにパース
6///
7/// # 引数
8/// * `date_str` - 日付文字列 (YYYY-MM-DD形式)
9/// * `time_str` - 時刻文字列 (HH:MM形式)
10///
11/// # 戻り値
12/// パースされたUTC DateTime
13///
14/// # エラー
15/// - 日付または時刻のフォーマットが不正な場合
16/// - 無効な日時の場合
17pub fn parse_datetime(
18    date_str: &str,
19    time_str: &str,
20) -> Result<DateTime<Utc>, Box<dyn std::error::Error + Send + Sync>> {
21    // 日付をパース (YYYY-MM-DD形式)
22    let date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d")
23        .map_err(|e| format!("日付のパースに失敗: {} ({})", date_str, e))?;
24
25    // 時刻をパース (HH:MM形式)
26    let time = NaiveTime::parse_from_str(time_str, "%H:%M")
27        .map_err(|e| format!("時刻のパースに失敗: {} ({})", time_str, e))?;
28
29    // 日付と時刻を結合
30    let naive_datetime = date.and_time(time);
31
32    // ローカルタイムゾーンでDateTime<Local>を作成してからUTCに変換
33    let local_datetime = Local
34        .from_local_datetime(&naive_datetime)
35        .single()
36        .ok_or_else(|| {
37            format!(
38                "無効な日時: {} {} (夏時間の切り替え時刻の可能性があります)",
39                date_str, time_str
40            )
41        })?;
42
43    Ok(local_datetime.with_timezone(&Utc))
44}