note 88679 deleted from function.strtotime by derick
| From: | derick@php.net | Date: | Sun, 14 Dec 2014 11:31:57 +0000 |
| Subject: | note 88679 deleted from function.strtotime by derick | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-201159@lists.php.net to get a copy of this message | ||
Note Submitter: akniep at rayo dot info
----
The "+1 month" issue solved as in MySQL.
========================================
As noted in several comments, PHP's strtotime() solves the "+1 month" ("next
month") issue on days that do not exist in the subsequent month differently than other
implementations like for example MySQL.
// PHP: 2009-03-03
<?php
echo date( "Y-m-d", strtotime( "2009-01-31 +1 month" ) );
?>
// MySQL: 2009-02-28
<?php
SELECT DATE_ADD( '2009-01-31', INTERVAL 1 MONTH );
?>
========================================
If not for consistency with MySQL there are several reasons why one may need a PHP-function that
calculates "+1 month" as MySQL does. Certainly, for various kinds of business logic it
seems much more intuitiv to land on a date within the subsequent month rather than on a date within
the next but one if you calculate "next month" ("+1 month").
The following function calculates a date X months in the future of a given date ($base_time).
<?php
/**
* Calculates a date lying a given number of months in the future of a given date.
* The results resemble the logic used in MySQL where '2009-01-31 +1 month' is
'2009-02-28' rather than '2009-03-03' (like in PHP's strtotime).
*
* @author akniep
* @since 2009-02-03
* @param $base_time long, The timestamp used to calculate the returned value .
* @param $months int, The number of months to jump to the future of the given $base_time.
* @return long, The timestamp of the day $months months in the future of $base_time
*/
function get_x_months_to_the_future( $base_time = null, $months = 1 )
{
if (is_null($base_time))
$base_time = time();
$x_months_to_the_future = strtotime( "+" . $months . " months", $base_time );
$month_before = (int) date( "m", $base_time ) + 12 * (int) date( "Y",
$base_time );
$month_after = (int) date( "m", $x_months_to_the_future ) + 12 * (int) date(
"Y", $x_months_to_the_future );
if ($month_after > $months + $month_before)
$x_months_to_the_future = strtotime( date("Ym01His", $x_months_to_the_future) . "
-1 day" );
return $x_months_to_the_future;
} //get_x_months_to_the_future()
// Tests
// =======
// returns 2009-02-28
echo date( "Y-m-d H:i:s", get_x_months_to_the_future( strtotime( '2009-01-31' )
) ), "\n";
// returns 2008-02-29
echo date( "Y-m-d H:i:s", get_x_months_to_the_future( strtotime( '2008-01-31' )
) ), "\n";
// returns 2009-09-30 12:00:00
echo date( "Y-m-d H:i:s", get_x_months_to_the_future( strtotime( '2009-05-31
12:00:00' ), 4 ) ), "\n";
?>