Adding one microsecond to Datetime object in PHP
Asked Answered
M

2

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?

Mier answered 6/6, 2018 at 12:41 Comment(6)
Tried this for versions older than 7.1? #10600882 - was added in 7.1 though if you're running.Obsolesce
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. 3v4l.org/6lfO5Pushkin
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.Gilstrap
so no option for 7.0.30-0ubuntu0.16.04.1?Mier
@Mier Check out my updated answerPharmacology
@Andrew You have to hack your way thru in PHP >= 7.1 anyways since microseconds are buggy :-(Pharmacology
P
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
Pharmacology answered 6/6, 2018 at 12:46 Comment(3)
While the code is elegant, this adds 10 microseconds, and won't work if the time is later than x.999998Acculturation
@Acculturation I think +1 microsecond is buggy when it comes to .999999, see my edit.Pharmacology
Note that this bug was fixed in PHP 7.2.Kid
P
0

Update PHP 8.4

The new getMicrosecond and setMicrosecond methods are now available on both DateTimeImmutable and DateTime classes in PHP 8.4 and later versions.

class DateTime {
// ...
   public function getMicrosecond(): int {}

   public function setMicrosecond(int $microsecond): static {}
// ...
}

Here the getMicrosecond() method returns the microsecond part of the datetime as an integer and the setMicrosecond() method accepts an integer value to set the microsecond part of the datetime.

So to add a microsecond to a Datetime object in PHP 8.4 or later versions, the following code works.

$date = new Datetime('2018-06-05 09:06:46.7487');
$microseconds->getMicrosecond();
$microseconds = $microseconds+1;
$date->setMicrosecond($microseconds);
echo $date->format('Y-m-d H:i:s.u');
Pantaloons answered 21/8 at 9:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.