1.2.785. Next Month Trap

Avoid using +1 month with strtotime().

strtotime() calculates the next month by incrementing the month number. For day number that do not exist from one month to the next, strtotime() fixes them by setting them in the next-next month.

This happens to January, March, May, July, August and October. January is also vulnerable for 29 (not every year), 30 and 31.

To use ‘+1 month’, rely on ‘first day of next month’ or ‘last day of next month’ to extract the next month’s name. For longer interfaces, start from ‘first day of next month’. Note that Datetime and DatetimeImmutable are also subject to the same trap.

<?php

// Base date is October 31 => 10/31
// +1 month adds +1 to 10 => 11/31
// Since November 31rst doesn't exists, it is corrected to 12/01.
echo date('F', strtotime('+1 month',mktime(0,0,0,$i,31,2017))).PHP_EOL;

// Base date is October 31 => 10/31
echo date('F', strtotime('first day of next month',mktime(0,0,0,$i,31,2017))).PHP_EOL;

?>

See also It is the 31st again.

1.2.785.1. Suggestions

  • Review strtotime() usage for month additions

  • Base your calculations for the next/previous months on the first day of the month (or any day before the 28th)

  • Avoid using ‘+n month’ with Datetime() after the 28th of any month (sic)

1.2.785.2. Specs

Short name

Structures/NextMonthTrap

Rulesets

All, Analyze, CE, CI-checks, Top10

Exakat since

1.0.1

PHP Version

All

Severity

Major

Time To Fix

Instant (5 mins)

Precision

High

Features

date

Examples

Contao, Edusoho

Available in

Entreprise Edition, Community Edition, Exakat Cloud