Search code examples
phpdatetimephp-7.0

Adding one microsecond to Datetime object in PHP


I need to add a microsecond to a Datetime object in PHP. I am trying to do it adding a time interfal a fraction of a second to the Datetime but it is not working.

$date = new Datetime('2018-06-05 09:06:46.7487');
$date->add(new DateInterval('PT0.00001S'));
echo $date->format('Y-m-d H:i:s.u');

I am not able to accomplish it though i think it should be simple. How can i add fractions of a second to a Datetime?


Solution

  • PHP >= 7.1 - works but there's a bug!

    If you have PHP 7.1 or later then this should do it:

    $date = new Datetime('2018-06-05 09:06:46.7487');
    $date->modify('+1 microsecond');
    echo $date->format('Y-m-d H:i:s.u');
    

    Output:

    2018-06-05 09:06:46.748701
    

    Caution: this fails for .999999

    $date = new Datetime('2018-06-05 09:06:46.999999');
    $date->modify('+1 microsecond');
    echo $date->format('Y-m-d H:i:s.u');
    

    Output:

    2018-06-05 09:06:46.1000000
    

    PHP >= 5.2.0 "hack" but not buggy!

    If you have PHP 7.0 or earlier then you can extract the microseconds and perform the math yourself in a "hacky" way:

    $date = new Datetime('2018-06-05 09:06:46.7487');
    
    // Use bcadd() to add .000001 seconds to the "microtime()" of the date
    $microtime = bcadd( $date->getTimestamp().'.'.$date->format( 'u' ), '.000001', 6 );
    
    // Reconstruct the date for consumption by __construct
    $date->__construct(
        date( 'Y-m-d H:i:s.', explode( '.', $microtime )[ 0 ] ).explode( '.', $microtime )[ 1 ]
    );
    
    echo $date->format('Y-m-d H:i:s.u');
    

    Output:

    2018-06-05 09:06:46.748701
    

    The hacky solution also works if the microsecond is at .999999

    $date = new Datetime('2018-06-05 09:06:46.999999');
    
    // Use bcadd() to add .000001 seconds to the "microtime()" of the date
    $microtime = bcadd( $date->getTimestamp().'.'.$date->format( 'u' ), '.000001', 6 );
    
    // Reconstruct the date for consumption by __construct
    $date->__construct(
        date( 'Y-m-d H:i:s.', explode( '.', $microtime )[ 0 ] ).explode( '.', $microtime )[ 1 ]
    );
    
    echo $date->format('Y-m-d H:i:s.u');
    

    Output:

    2018-06-05 09:06:47.000000