php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71693 Date Interval Subtraction for Leap Day
Submitted: 2016-03-01 00:09 UTC Modified: 2016-03-01 02:37 UTC
From: snyderpa at gmail dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 5.5.32 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: snyderpa at gmail dot com
New email:
PHP Version: OS:

 

 [2016-03-01 00:09 UTC] snyderpa at gmail dot com
Description:
------------
I had a test begin to fail.  I was naively expecting subtraction of an interval 'P18Y' to yield a date on which all users born that day would turn 18 years old today.  Although the leap day should be an exception for my test case (https://www.quora.com/If-youre-born-on-February-29th-when-do-you-legally-turn-one-year-older) I noticed that there appears to be some brokenness with subtraction of 'P1D' interval from the leap day, and the subsequent subtraction of the 'P18Y' interval from that result.

p.s. My Turing test asks for the solution to 50 - 32 -- spooky :-)

Test script:
---------------
<?php
/* get some significant dates */
$today = new DateTime();
echo("\nTODAY\n");
var_export($today);
$minorAgeInterval = new DateInterval('P18Y');
$oneDayInterval = new DateInterval('P1D');
$tomorrow = $today->add($oneDayInterval);
echo("\nTOMORROW\n");
var_export($tomorrow);
$yesterday = $today->sub($oneDayInterval);
echo("\nYESTERDAY\n");
var_export($yesterday);
$todayMinus18 = $today->sub($minorAgeInterval);
echo("\nTODAY MINUS 18\n");
var_export($todayMinus18);
$tomorrowMinus18 = $tomorrow->sub($minorAgeInterval);
echo("\nTOMORROW MINUS 18\n");
var_export($tomorrowMinus18);
$yesterdayMinus18 = $yesterday->sub($minorAgeInterval);
echo("\nYESTERDAY MINUS 18\n");
var_export($yesterdayMinus18);
?>


Expected result:
----------------
paul@paul-VirtualBox:~$ php php_date_fun.php 

TODAY
DateTime::__set_state(array(
   'date' => '2016-02-29 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
TOMORROW
DateTime::__set_state(array(
   'date' => '2016-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
YESTERDAY
DateTime::__set_state(array(
   'date' => '2016-02-28 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
TODAY MINUS 18
DateTime::__set_state(array(
   'date' => '1998-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
TOMORROW MINUS 18
DateTime::__set_state(array(
   'date' => '1980-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
YESTERDAY MINUS 18
DateTime::__set_state(array(
   'date' => '1998-02-28 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))

Actual result:
--------------
paul@paul-VirtualBox:~$ php php_date_fun.php 

TODAY
DateTime::__set_state(array(
   'date' => '2016-02-29 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
TOMORROW
DateTime::__set_state(array(
   'date' => '2016-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
YESTERDAY
DateTime::__set_state(array(
   'date' => '2016-02-29 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
TODAY MINUS 18
DateTime::__set_state(array(
   'date' => '1998-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
TOMORROW MINUS 18
DateTime::__set_state(array(
   'date' => '1980-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
YESTERDAY MINUS 18
DateTime::__set_state(array(
   'date' => '1962-03-01 15:49:56',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-01 00:47 UTC] snyderpa at gmail dot com
Also, $tomorrowMinus18 should be in year 1998, not 1980.
 [2016-03-01 02:37 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2016-03-01 02:37 UTC] requinix@php.net
->add and ->sub *modify* the object. Then they return the instance itself, not a new one.

Try code more like

$tomorrow = clone $today;
$tomorrow->add($oneDayInterval);
echo("\nTOMORROW\n");
var_export($tomorrow);
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Jun 01 12:01:31 2024 UTC