Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 337
HellOfACode Avatar asked Jun 06 '18 12:06

HellOfACode


1 Answers

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

All PHP versions "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
like image 79
MonkeyZeus Avatar answered Sep 23 '22 01:09

MonkeyZeus