Parse ISO 8601 duration string into total seconds Supports formats like: - P1Y2M3DT4H5M6S (1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds) - PT1H (1 hour) - P1D (1 day) - PT30M (30 minutes) - PT45S (45 seconds) Note: For months and years, we use approximations: - 1 month = 30 days = 2,592,000 seconds - 1 year = 365 days = 31,536,000 seconds
(duration_str: &str)
| 1088 | /// - 1 month = 30 days = 2,592,000 seconds |
| 1089 | /// - 1 year = 365 days = 31,536,000 seconds |
| 1090 | fn parse_iso_duration(duration_str: &str) -> Result<i64, String> { |
| 1091 | if !duration_str.starts_with('P') { |
| 1092 | return Err("Duration must start with 'P'".to_string()); |
| 1093 | } |
| 1094 | |
| 1095 | let mut total_seconds = 0i64; |
| 1096 | let chars = duration_str[1..].chars().peekable(); // Skip the 'P' |
| 1097 | let mut number_str = String::new(); |
| 1098 | let mut in_time_part = false; |
| 1099 | |
| 1100 | for ch in chars { |
| 1101 | match ch { |
| 1102 | 'T' => { |
| 1103 | in_time_part = true; |
| 1104 | continue; |
| 1105 | } |
| 1106 | '0'..='9' => { |
| 1107 | number_str.push(ch); |
| 1108 | } |
| 1109 | 'Y' => { |
| 1110 | if let Ok(years) = number_str.parse::<i64>() { |
| 1111 | total_seconds += years * 365 * 24 * 3600; // Approximate: 1 year = 365 days |
| 1112 | } |
| 1113 | number_str.clear(); |
| 1114 | } |
| 1115 | 'M' if !in_time_part => { |
| 1116 | if let Ok(months) = number_str.parse::<i64>() { |
| 1117 | total_seconds += months * 30 * 24 * 3600; // Approximate: 1 month = 30 days |
| 1118 | } |
| 1119 | number_str.clear(); |
| 1120 | } |
| 1121 | 'D' => { |
| 1122 | if let Ok(days) = number_str.parse::<i64>() { |
| 1123 | total_seconds += days * 24 * 3600; // 1 day = 86,400 seconds |
| 1124 | } |
| 1125 | number_str.clear(); |
| 1126 | } |
| 1127 | 'H' => { |
| 1128 | if let Ok(hours) = number_str.parse::<i64>() { |
| 1129 | total_seconds += hours * 3600; // 1 hour = 3,600 seconds |
| 1130 | } |
| 1131 | number_str.clear(); |
| 1132 | } |
| 1133 | 'M' if in_time_part => { |
| 1134 | if let Ok(minutes) = number_str.parse::<i64>() { |
| 1135 | total_seconds += minutes * 60; // 1 minute = 60 seconds |
| 1136 | } |
| 1137 | number_str.clear(); |
| 1138 | } |
| 1139 | 'S' => { |
| 1140 | if let Ok(seconds) = number_str.parse::<i64>() { |
| 1141 | total_seconds += seconds; |
| 1142 | } |
| 1143 | number_str.clear(); |
| 1144 | } |
| 1145 | _ => { |
| 1146 | return Err(format!("Invalid duration character: '{}'", ch)); |
| 1147 | } |