Oihana PHP Standards

Iso8601Duration

Represents and manipulates ISO 8601 duration strings.

This class provides a convenient wrapper around PHP's DateInterval with additional functionality for working with ISO 8601 duration format. It maintains synchronization between the string representation and the DateInterval object.

ISO 8601 duration format: P[n]Y[n]M[n]DT[n]H[n]M[n]S

  • P: duration designator (required)
  • T: time designator (separates date and time components)
  • Y/M/D: years, months, days
  • H/M/S: hours, minutes, seconds (after T)
Tags
example
// Create from ISO 8601 string
$duration = new Iso8601Duration('P1Y2M3D');
echo $duration->iso; // "P1Y2M3D"

// Create from DateInterval
$interval = new DateInterval('PT30M');
$duration = new Iso8601Duration($interval);
echo $duration->toSeconds(); // 1800

// Modify using ISO string
$duration->iso = 'PT30M';

// Modify using DateInterval
$duration->interval = new DateInterval('P5D');
echo $duration->iso; // "P5D"

// Add to a date
$date = new DateTime('2024-01-01');
$newDate = $duration->addTo($date);
echo $newDate->format('Y-m-d'); // "2024-01-06"
link

ISO 8601 Duration specification

PHP DateInterval documentation

author

Marc Alcaraz (ekameleon)

since
1.0.1

Table of Contents

Constants

DAY  : string = 'D'
Day designator.
HOUR  : string = 'H'
Hour designator.
MINUTE  : string = 'M'
Minute designator (used in time component after T).
MONTH  : string = 'M'
Month designator (used in date component before T).
PATTERN  : string = '/^P(?:(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(?:T(\d+H)?(...
ISO 8601 duration regex pattern : P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S or P[n]W
PERIOD  : string = 'P'
Duration designator (required at the start of every duration string).
SECOND  : string = 'S'
Second designator.
TIME  : string = 'T'
Time designator (separates date and time components).
WEEK  : string = 'W'
Week designator (alternative to day specification).
YEAR  : string = 'Y'
Year designator.
ZERO  : string = 'P0D'
Zero duration constant.

Properties

$days  : int
Gets the number of days in the duration.
$hours  : int
Gets the number of hours in the duration.
$interval  : DateInterval
Gets or sets the DateInterval representation of the duration.
$iso  : string
Gets or sets the ISO 8601 string representation of the duration.
$minutes  : int
Gets the number of minutes in the duration.
$months  : int
Gets the number of months in the duration.
$seconds  : int
Gets the number of seconds in the duration.
$years  : int
Gets the number of years in the duration.
$_interval  : DateInterval
The internal DateInterval representing the duration.
$_iso  : string
The ISO 8601 string representation of the duration.

Methods

__construct()  : mixed
Creates a new Iso8601Duration instance from an ISO 8601 string or a DateInterval.
__toString()  : string
Returns the string representation of the duration.
addTo()  : DateTime
Adds this duration to a given DateTime and returns a new DateTime object.
subtractFrom()  : DateTime
Subtracts this duration from a given DateTime and returns a new DateTime object.
toSeconds()  : int
Converts the duration to an approximate number of seconds.

Constants

MINUTE

Minute designator (used in time component after T).

public string MINUTE = 'M'

MONTH

Month designator (used in date component before T).

public string MONTH = 'M'

PATTERN

ISO 8601 duration regex pattern : P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S or P[n]W

public string PATTERN = '/^P(?:(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(?:T(\d+H)?(\d+M)?(\d+(?:\.\d+)?S)?)?|0[YMWD]|T0S)$/'

PERIOD

Duration designator (required at the start of every duration string).

public string PERIOD = 'P'

TIME

Time designator (separates date and time components).

public string TIME = 'T'

WEEK

Week designator (alternative to day specification).

public string WEEK = 'W'

Properties

$days read-only virtual

Gets the number of days in the duration.

public int $days
Tags
example
$duration = new Iso8601Duration('P5D');
echo $duration->days; // 5
Hooks
public int get

$hours read-only virtual

Gets the number of hours in the duration.

public int $hours
Tags
example
$duration = new Iso8601Duration('PT4H30M');
echo $duration->hours; // 4
Hooks
public int get

$interval virtual

Gets or sets the DateInterval representation of the duration.

public DateInterval $interval

When setting this property, the internal DateInterval is cloned to prevent external modifications, and the ISO 8601 string is automatically regenerated.

Tags
example
$duration = new Iso8601Duration('P1D');
$interval = $duration->interval; // Get DateInterval

$duration->interval = new DateInterval('PT30M'); // Set new interval
echo $duration->iso; // "PT30M" (automatically updated)
Hooks
public DateInterval get public set

$iso virtual

Gets or sets the ISO 8601 string representation of the duration.

public string $iso

When setting this property, the DateInterval is automatically updated and validated. Invalid ISO 8601 strings will throw an exception.

Tags
throws
InvalidArgumentException

If the provided ISO 8601 string is invalid

example
$duration = new Iso8601Duration('P1D');
echo $duration->iso; // "P1D"

$duration->iso = 'PT2H'; // Update duration
echo $duration->toSeconds(); // 7200
Hooks
public string get public set

$minutes read-only virtual

Gets the number of minutes in the duration.

public int $minutes
Tags
example
$duration = new Iso8601Duration('PT4H30M');
echo $duration->minutes; // 30
Hooks
public int get

$months read-only virtual

Gets the number of months in the duration.

public int $months
Tags
example
$duration = new Iso8601Duration('P2Y3M');
echo $duration->months; // 3
Hooks
public int get

$seconds read-only virtual

Gets the number of seconds in the duration.

public int $seconds
Tags
example
$duration = new Iso8601Duration('PT1M45S');
echo $duration->seconds; // 45
Hooks
public int get

$years read-only virtual

Gets the number of years in the duration.

public int $years
Tags
example
$duration = new Iso8601Duration('P2Y3M');
echo $duration->years; // 2
Hooks
public int get

$_interval

The internal DateInterval representing the duration.

private DateInterval $_interval

$_iso

The ISO 8601 string representation of the duration.

private string $_iso

Methods

__construct()

Creates a new Iso8601Duration instance from an ISO 8601 string or a DateInterval.

public __construct([string|DateInterval|null $duration = null ]) : mixed
Parameters
$duration : string|DateInterval|null = null

ISO 8601 duration string (e.g., "P1Y2M", "PT4H30M", "P1W"), a DateInterval object, or null for zero duration (P0D)

Tags
throws
InvalidArgumentException

If the ISO 8601 string is invalid or malformed

example
// From ISO 8601 string
$duration = new Iso8601Duration('P1Y2M3D');
$duration = new Iso8601Duration('PT2H30M');
$duration = new Iso8601Duration('P1W'); // 1 week

// From DateInterval
$interval = new DateInterval('P5D');
$duration = new Iso8601Duration($interval);

// From date difference
$start = new DateTime('2024-01-01');
$end = new DateTime('2024-12-31');
$duration = new Iso8601Duration($start->diff($end));

// Zero duration (default)
$duration = new Iso8601Duration(); // Equivalent to 'P0D'
$duration = new Iso8601Duration(null); // Same as above

__toString()

Returns the string representation of the duration.

public __toString() : string

This magic method allows the object to be used in string contexts, returning the ISO 8601 duration string.

Tags
example
$duration = new Iso8601Duration('P1Y2M3D');
echo $duration; // "P1Y2M3D"
echo "Duration: " . $duration; // "Duration: P1Y2M3D"
Return values
string

The ISO 8601 duration string

addTo()

Adds this duration to a given DateTime and returns a new DateTime object.

public addTo(DateTime $date) : DateTime

The original DateTime is not modified; a clone is created and modified instead. This method properly handles calendar arithmetic including leap years, varying month lengths, and daylight saving time transitions.

Parameters
$date : DateTime

The reference date to add the duration to

Tags
example
$duration = new Iso8601Duration('P1M');
$date = new DateTime('2024-01-31');
$result = $duration->addTo($date);
echo $result->format('Y-m-d'); // "2024-02-29" (leap year)

$duration = new Iso8601Duration('PT2H30M');
$date = new DateTime('2024-03-10 01:30:00'); // DST transition
$result = $duration->addTo($date);
echo $result->format('Y-m-d H:i:s'); // Properly handles DST
Return values
DateTime

A new DateTime object with the duration added

subtractFrom()

Subtracts this duration from a given DateTime and returns a new DateTime object.

public subtractFrom(DateTime $date) : DateTime

The original DateTime is not modified; a clone is created and modified instead. This method properly handles calendar arithmetic including leap years, varying month lengths, and daylight saving time transitions.

Parameters
$date : DateTime

The reference date to subtract the duration from

Tags
throws
DateInvalidOperationException

If the subtraction would result in an invalid date

example
$duration = new Iso8601Duration('P1M');
$date = new DateTime('2024-03-31');
$result = $duration->subtractFrom($date);
echo $result->format('Y-m-d'); // "2024-02-29" (leap year)

$duration = new Iso8601Duration('P5D');
$date = new DateTime('2024-01-10');
$result = $duration->subtractFrom($date);
echo $result->format('Y-m-d'); // "2024-01-05"
Return values
DateTime

A new DateTime object with the duration subtracted

toSeconds()

Converts the duration to an approximate number of seconds.

public toSeconds() : int

This method provides an estimation by converting:

  • 1 year = 365 days
  • 1 month = 30 days
  • 1 day = 86400 seconds

For exact calculations that account for actual calendar variations (leap years, different month lengths), use addTo() with a specific reference date instead.

Tags
example
$duration = new Iso8601Duration('PT1H30M');
echo $duration->toSeconds(); // 5400 (1.5 hours)

$duration = new Iso8601Duration('P1Y');
echo $duration->toSeconds(); // 31536000 (365 days)

$duration = new Iso8601Duration('P1M');
echo $duration->toSeconds(); // 2592000 (30 days - approximate)
Return values
int

The approximate number of seconds in the duration

On this page

Search results