| 1: | <?php |
| 2: | declare(strict_types=1); |
| 3: | |
| 4: | namespace om\ICal\Value; |
| 5: | |
| 6: | use DateInterval; |
| 7: | use Exception; |
| 8: | |
| 9: | |
| 10: | |
| 11: | |
| 12: | final class Duration { |
| 13: | public static function parse(string $value): ?DateInterval { |
| 14: | $value = strtoupper(trim($value)); |
| 15: | |
| 16: | if (!preg_match('/^([+-])?P(?:(\d{1,9})W)?(?:(\d{1,9})D)?(?:T(?:(\d{1,9})H)?(?:(\d{1,9})M)?(?:(\d{1,9})S)?)?$/D', $value, $match) || !preg_match('/\d/', $value)) { |
| 17: | return null; |
| 18: | } |
| 19: | $days = (int) ($match[2] ?? 0) * 7 + (int) ($match[3] ?? 0); |
| 20: | try { |
| 21: | $interval = new DateInterval(sprintf('P%dDT%dH%dM%dS', $days, (int) ($match[4] ?? 0), (int) ($match[5] ?? 0), (int) ($match[6] ?? 0))); |
| 22: | } catch (Exception) { |
| 23: | return null; |
| 24: | } |
| 25: | $interval->invert = ($match[1] ?? '') === '-' ? 1 : 0; |
| 26: | return $interval; |
| 27: | } |
| 28: | |
| 29: | |
| 30: | |
| 31: | |
| 32: | |
| 33: | public static function format(DateInterval $interval): string { |
| 34: | $days = $interval->days !== false && ($interval->y || $interval->m) ? $interval->days : $interval->d; |
| 35: | $time = ($interval->h ? $interval->h . 'H' : '') . ($interval->i ? $interval->i . 'M' : '') . ($interval->s ? $interval->s . 'S' : ''); |
| 36: | $result = 'P' . ($days ? $days . 'D' : '') . ($time !== '' ? 'T' . $time : ''); |
| 37: | return ($interval->invert ? '-' : '') . ($result === 'P' ? 'PT0S' : $result); |
| 38: | } |
| 39: | } |
| 40: | |