bretterer/iso_duration_converter
Lightweight PHP helper to convert ISO 8601 duration strings (e.g., PT1H30M, P2DT3H) into usable values like seconds or formatted time. Handy for parsing API durations, validating inputs, and normalizing durations in Laravel or any PHP app.
Installation
composer require bretterer/iso_duration_converter
No service provider or facade needed—use the Bretterer\IsoDurationConverter\DurationConverter class directly.
First Use Case Convert an ISO duration string to seconds (e.g., for API timeouts or scheduling):
use Bretterer\IsoDurationConverter\DurationConverter;
$converter = new DurationConverter();
$seconds = $converter->toSeconds('PT15M'); // Returns 900
Key Methods
toSeconds(string $duration) → Returns duration in seconds.toMinutes(string $duration) → Returns duration in minutes.toHours(string $duration) → Returns duration in hours.validate(string $duration) → Checks if the string is a valid ISO 8601 duration.API Request Validation Sanitize and convert incoming duration strings (e.g., from frontend or third-party APIs):
$rawDuration = request('timeout');
if ($converter->validate($rawDuration)) {
$timeoutSeconds = $converter->toSeconds($rawDuration);
// Use $timeoutSeconds in Carbon::now()->addSeconds() or DB queries
}
Scheduling Jobs
Parse cron-like durations (e.g., from a config file) into Laravel’s now()->add() methods:
$delay = $converter->toSeconds('P1DT2H'); // 93600 seconds
YourJob::dispatch()->delay($delay);
Database/ORM Integration Normalize durations for storage or queries:
$durationSeconds = $converter->toSeconds('PT30M');
DB::table('timeouts')->where('duration_sec', $durationSeconds)->update(...);
Form Input Handling Convert user-submitted durations (e.g., "1 hour 30 minutes") to a standardized format:
$userInput = 'PT1H30M';
$standardized = $converter->toSeconds($userInput); // 5400
Form Request Validation:
Use the validate() method in Laravel’s FormRequest:
public function rules()
{
return [
'duration' => 'required|string',
];
}
public function withValidator($validator)
{
$validator->after(function ($validator) {
if (!$this->converter->validate($this->input('duration'))) {
$validator->errors()->add('duration', 'Invalid ISO 8601 duration format.');
}
});
}
Model Casting:
Cast a duration attribute to seconds in a model:
protected $casts = [
'duration' => function ($value) {
return (new DurationConverter())->toSeconds($value);
},
];
API Responses: Normalize durations in responses for consistency:
return response()->json([
'timeout' => $converter->toSeconds($request->timeout),
]);
Unsupported Formats
P1Y), months (P2M), or weeks (P3W). These will throw exceptions or return null.Edge Cases in Parsing
null values will throw exceptions. Always validate first:
if (empty($duration) || !$converter->validate($duration)) {
throw new \InvalidArgumentException('Invalid duration');
}
-PT1H) may not be handled. Test thoroughly if your use case includes them.Floating-Point Precision
PT1.5S) may lose precision when converted to minutes/hours.Time Zone Awareness
Carbon, ensure consistency:
$carbonInstance = Carbon::now()->addSeconds($converter->toSeconds('PT2H'));
Invalid Inputs:
Use validate() to catch malformed strings early. For debugging, log the raw input:
if (!$converter->validate($duration)) {
\Log::error("Invalid duration received: {$duration}");
}
Unexpected Outputs: Test with boundary values:
$converter->toSeconds('PT0S'); // 0
$converter->toSeconds('P1DT24H'); // 100800 (1 day + 24 hours)
Custom Units: Extend the converter to support non-standard units (e.g., "weeks") by subclassing:
class ExtendedDurationConverter extends DurationConverter {
public function toWeeks(string $duration) {
return $this->toSeconds($duration) / 604800; // 7 days in seconds
}
}
Integration with Carbon: Create a helper to bridge ISO durations and Carbon:
function durationToCarbon(string $duration): Carbon {
return Carbon::now()->addSeconds((new DurationConverter())->toSeconds($duration));
}
Localization:
Add human-readable parsing (e.g., "1 hour 30 minutes") by combining with a library like league/iso8601.
DurationConverter class.$converter = app()->make(DurationConverter::class); // Laravel container
// or
$converter = new DurationConverter(); // Global instance
How can I help you explore Laravel packages today?