Parse ISO 8601 datetime string into DateTime Supports formats like: - 2024-01-15T10:30:45Z - 2024-01-15T10:30:45.123Z - 2024-01-15T10:30:45+00:00 - 2024-01-15T10:30:45.123+00:00
(datetime_str: &str)
| 1043 | /// - 2024-01-15T10:30:45+00:00 |
| 1044 | /// - 2024-01-15T10:30:45.123+00:00 |
| 1045 | fn parse_iso_datetime(datetime_str: &str) -> Result<DateTime<Utc>, String> { |
| 1046 | // Try different ISO 8601 formats |
| 1047 | let formats = [ |
| 1048 | "%Y-%m-%dT%H:%M:%SZ", // 2024-01-15T10:30:45Z |
| 1049 | "%Y-%m-%dT%H:%M:%S%.3fZ", // 2024-01-15T10:30:45.123Z |
| 1050 | "%Y-%m-%dT%H:%M:%S%z", // 2024-01-15T10:30:45+00:00 |
| 1051 | "%Y-%m-%dT%H:%M:%S%.3f%z", // 2024-01-15T10:30:45.123+00:00 |
| 1052 | "%Y-%m-%dT%H:%M:%S", // 2024-01-15T10:30:45 (assume UTC) |
| 1053 | ]; |
| 1054 | |
| 1055 | // First try chrono's built-in RFC 3339 parser (most robust) |
| 1056 | if let Ok(datetime) = DateTime::parse_from_rfc3339(datetime_str) { |
| 1057 | return Ok(datetime.with_timezone(&Utc)); |
| 1058 | } |
| 1059 | |
| 1060 | // Try manual parsing with different formats |
| 1061 | for format in &formats { |
| 1062 | if let Ok(datetime) = DateTime::parse_from_str(datetime_str, format) { |
| 1063 | return Ok(datetime.with_timezone(&Utc)); |
| 1064 | } |
| 1065 | } |
| 1066 | |
| 1067 | // Try parsing as naive datetime and assume UTC |
| 1068 | if let Ok(naive_dt) = chrono::NaiveDateTime::parse_from_str(datetime_str, "%Y-%m-%dT%H:%M:%S") { |
| 1069 | return Ok(DateTime::from_naive_utc_and_offset(naive_dt, Utc)); |
| 1070 | } |
| 1071 | |
| 1072 | Err(format!( |
| 1073 | "Unable to parse datetime '{}' - expected ISO 8601 format", |
| 1074 | datetime_str |
| 1075 | )) |
| 1076 | } |
| 1077 | |
| 1078 | /// Parse ISO 8601 duration string into total seconds |
| 1079 | /// |
no outgoing calls