Dates7 min readExamples run on PHP 8.5.10

date_interval_create_from_date_string()

Learn how date_interval_create_from_date_string() turns relative date text such as '2 months' into a DateInterval, with tested PHP 8.4 examples and pitfalls.

Signature

date_interval_create_from_date_string(string $datetime): DateInterval|false
Available since PHP 5.3.07.48.08.18.28.38.48.5All versions →

Purpose

date_interval_create_from_date_string() builds a DateInterval object from human-readable relative text such as 1 year + 2 months or 10 days. The manual describes it as an alias of DateInterval::createFromDateString(), so both forms behave the same way. Use the procedural name when your code is function-based, and the static method when you prefer an object-oriented style.

The resulting interval can be passed to DateTime::add(), DateTimeImmutable::sub(), date_add(), or to a DatePeriod as its step.

Signature

Parameters and defaults

  • $datetime: a string using the same relative-format vocabulary that PHP's date parser understands, for example 3 days, 1 year + 2 months + 3 days or 2 weeks. There are no optional parameters and no defaults.

The text describes a relative amount, not a calendar date. Passing 2024-01-31 is not what this function is for.

Return value and failure cases

On success you get a DateInterval. If the string cannot be parsed, the function returns false (and PHP also reports a warning). Because of that, code that handles user-supplied text should compare the result to false before using it. The function does not throw for unparsable input, so a try/catch alone will not protect you.

Example 1: reading the components

The parsed units are stored in the interval's properties.

Example
<?php
$interval = date_interval_create_from_date_string('1 year + 2 months + 3 days');
echo json_encode([$interval->y, $interval->m, $interval->d]), "\n";
Output
[1,2,3]

The years, months and days are separate components, so the array above holds one value for each of them.

Example 2: adding a month to a fixed date

An interval is a recipe, not a fixed number of seconds. The calendar decides the result when you apply it. Setting UTC keeps the example deterministic.

Example
<?php
date_default_timezone_set('UTC');
$start = new DateTimeImmutable('2024-01-31 10:00:00');
$interval = date_interval_create_from_date_string('1 month');
echo $start->add($interval)->format('Y-m-d H:i:s'), "\n";
Output
2024-03-02 10:00:00

January 31 plus one month would be February 31, which does not exist. PHP rolls the extra days into March, and because 2024 is a leap year, the result is March 2.

Example 3: stepping a DatePeriod

A DatePeriod needs an interval to know how far to move between dates. The end date is exclusive by default.

Example
<?php
date_default_timezone_set('UTC');
$period = new DatePeriod(
    new DateTimeImmutable('2024-03-01'),
    date_interval_create_from_date_string('10 days'),
    new DateTimeImmutable('2024-03-31')
);
$dates = [];
foreach ($period as $date) {
    $dates[] = $date->format('Y-m-d');
}
echo json_encode($dates), "\n";
Output
["2024-03-01","2024-03-11","2024-03-21"]

The next step after March 21 would land exactly on March 31, which is the excluded end date, so only three dates appear.

Edge cases

  • Months and years are not fixed lengths. The same 1 month interval can move a date by 28, 29, 30 or 31 days depending on the starting point. Always test with boundary dates such as the 31st or February 29.
  • Relative words may live outside the simple properties. Some phrases that the date parser understands are stored as relative information rather than plain y, m or d values. If an interval is meant to be applied to dates, verify behavior by applying it to a fixed date instead of only inspecting properties.
  • Time zones matter when time is involved. When you add an interval to a date-time in a zone with daylight saving changes, set the zone explicitly so the result is reproducible.
  • Invalid text returns false. An empty or misspelled unit should be treated as an error path in your code.

Common mistakes

  1. Confusing it with the constructor. new DateInterval('P1D') expects an ISO 8601 duration. date_interval_create_from_date_string('1 day') expects relative English text. Mixing the two formats leads to errors or false.
  2. Using it to measure the gap between two dates. To find the difference between known dates, use date_diff() or DateTimeInterface::diff(). This function only converts descriptive text into an interval.
  3. Skipping the false check. Calling ->d on false is a bug. Validate the return value when the text is not a literal in your code.
  4. Assuming a month is 30 days. If you need an exact number of days, ask for days explicitly.
  5. Depending on the current date. Examples and tests should use fixed start dates, not now, so results stay stable.
  • DateInterval::createFromDateString(): the method form of the same operation.
  • date_add() and date_sub(): apply an interval to a date object.
  • date_diff(): compute an interval between two dates.
  • DatePeriod: iterate over recurring dates using an interval.
  • DateTime::modify(): change a date directly with relative text, without creating an interval first.

Recap

date_interval_create_from_date_string() converts relative text like 10 days into a DateInterval, returning false when parsing fails. It is an alias of DateInterval::createFromDateString(). Remember that month and year amounts depend on the date they are applied to, check for false with dynamic input, and use fixed dates and UTC in examples so the output stays predictable.

Tested examples

Reading the components of a parsed interval
<?php
$interval = date_interval_create_from_date_string('1 year + 2 months + 3 days');
echo json_encode([$interval->y, $interval->m, $interval->d]), "\n";
Output
[1,2,3]
Adding a month to a fixed date
<?php
date_default_timezone_set('UTC');
$start = new DateTimeImmutable('2024-01-31 10:00:00');
$interval = date_interval_create_from_date_string('1 month');
echo $start->add($interval)->format('Y-m-d H:i:s'), "\n";
Output
2024-03-02 10:00:00
Stepping a DatePeriod
<?php
date_default_timezone_set('UTC');
$period = new DatePeriod(
    new DateTimeImmutable('2024-03-01'),
    date_interval_create_from_date_string('10 days'),
    new DateTimeImmutable('2024-03-31')
);
$dates = [];
foreach ($period as $date) {
    $dates[] = $date->format('Y-m-d');
}
echo json_encode($dates), "\n";
Output
["2024-03-01","2024-03-11","2024-03-21"]