Categories
PHP

The DateInterval Class

How to add or subtract a date/time period from a DateTime object using the add() and sub() methods.

Adding and Subtracting Dates and Times

The DateTime class contains add() and sub() methods to manipulate a DateTime instance’s value. Both methods accept a DateInterval class instance as the argument that specifies the amount of time added to or subtracted from a DateTime instance.

The DateInterval class constructor takes a string argument, $duration, that provides an interval specification. The format of interval specification is:

  • P – The format must start with the letter P (period), the following designators represent the period:
    • Y (years): P2Y means 2 years.
    • M (months): P2Y3M means 2 years and 3 months.
    • D (days): P2Y3M29D means 2 years, 3 months, and 29 days.
    • W (weeks): P2Y3M2W means 2 years, 3 months, and 2 weeks.
  • T – The time portion of the interval specification is represented by T (time).
    • H (hours): PT2H means 2 hours, P2Y3M29DT2H means 2 years, 3 months, 29 days, and 2 hours.
    • M (minutes): PT2H5M means 2 hours and 5 minutes. P2YT2H5M means 2 years, 2 hours, and 5 minutes.
    • S (seconds): PT59S means 59 seconds only. P3MT5S means 3 months, and 5 seconds.

The interval specification can also be represented as a date time. For example, the P2YT2H5M format can be written as P0002-00-00T02:05:00.

Example: Adding two weeks to the DateTime object

<?php
 $interval = new DateInterval('P2W'); # 2-week
 $date = new DateTime('Jan 01, 2022 2:00:00PM');
 echo $date->format('d-M-Y H:i:s') . '<br>';
 # 01-Jan-2022 14:00:00
 
 $date->add($interval);
 echo $date->format('d-M-Y H:i:s') . '<br>';
 # 15-Jan-2022 14:00:00

 // Adding the same interval again 
 $date->add($interval);
 echo $date->format('d-M-Y H:i:s');
 # 29-Jan-2022 14:00:00

Example: Subtracting two weeks to the DateTime object

<?php
 $interval = new DateInterval('P2W'); # 2-week
 $date = new DateTime('Jan 01, 2022 2:00:00PM');
 echo $date->format('d-M-Y H:i:s') . '<br>';
 # 01-Jan-2022 14:00:00
 
 $date->sub($interval);
 echo $date->format('d-M-Y H:i:s') . '<br>';
 # 18-Dec-2021 14:00:00

 // Subtracting the same interval again 
 $date->sub($interval);
 echo $date->format('d-M-Y H:i:s');
 # 04-Dec-2021 14:00:00

DateInterval::createFromDateString

Alternatively, you can use the static createFromDateString() method, which takes as an argument an English relative date string in the same way as strtotime() function does. So, the P2W is equal to “2 weeks“, P1D is equal to “1 day“, PT36S is equal to “36 seconds“, etc. see the following code:

<?php
 $interval = DateInterval::createFromDateString('2 weeks');

 $date = new DateTime('Jan 01, 2022 2:00:00PM');
 echo $date->format('d-M-Y H:i:s') . '<br>';
 # 01-Jan-2022 14:00:00
 
 $date->sub($interval);
 echo $date->format('d-M-Y H:i:s') . '<br>';
 # 18-Dec-2021 14:00:00

 // Subtracting the same interval again 
 $date->add($interval);
 echo $date->format('d-M-Y H:i:s');
 # 01-Jan-2022 14:00:00

DateInterval::format

Use the following characters to format the interval, each character must be prefixed by % sign:

  • %Y (years): 01, 08, 22
  • %y (years): 1, 8, 22 (without leading zero)
  • %M (months): 01, 03, 12
  • %m (months): 1, 3, 12 (without leading zero)
  • %D (days): 01, 08, 31
  • %d (days): 1, 8, 31 (without leading zero)
  • %a Total number of days as a result of a DateTime::diff()
  • %H (hours): 01, 07, 22
  • %h (hours): 1, 7, 22 (without leading zero)
  • %I (minutes): 01, 06, 59
  • %i (minutes), 1, 6, 59 (without leading zero)
  • %S (seconds): 01, 03, 55
  • %s (seconds): 1, 3, 55 (without leading zero)
  • %F (microseconds), at least 6 digits; 000701, 005273, 424288
  • %f (microseconds),701, 5273, 424288 (without leading zero)
  • %R + or – sign for positive and negative value
  • %r – sign when negative, empty when positive

Example: Formatting interval

<?php
 $interval = DateInterval::createFromDateString('-10 day');
 echo $interval->format('%r%d days'). '<br>';
 # Prints: -10 days
 
 $interval = new DateInterval('P1DT1H');
 echo $interval->format('%R%D days and %R%h hours');
 # Prints: +01 days and +1 hours

The Date and Time Tutorials: