11

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?

MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77
HellOfACode
  • 1,675
  • 3
  • 18
  • 38
  • 1
    Tried this for versions older than 7.1? https://stackoverflow.com/questions/10600382/add-microseconds-to-a-time-in-php - was added in 7.1 though if you're running. – Statik Stasis Jun 06 '18 at 12:44
  • Note that PHP doesn't support microseconds in php versions lower than 7.1. I don't know which one you are on, but this might just be it. https://3v4l.org/6lfO5 – Loek Jun 06 '18 at 12:45
  • If you're using PH < 7.1 you can't(without hacking your way thru it at least). As of PHP 7.1 you can, using [`modify`](http://www.php.net/manual/en/datetime.modify.php). – Andrei Jun 06 '18 at 12:45
  • so no option for 7.0.30-0ubuntu0.16.04.1? – HellOfACode Jun 06 '18 at 13:05
  • @HellOfACode [Check out my updated answer](https://stackoverflow.com/a/50720776/2191572) – MonkeyZeus Jun 06 '18 at 13:08
  • @Andrew You have to hack your way thru in PHP >= 7.1 anyways since microseconds are buggy :-( – MonkeyZeus Jun 13 '18 at 11:41

1 Answers1

14

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
MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77