Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Last active August 7, 2020 06:34
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vudaltsov/0bb623b9e2817d6ce359eb88cfbf229d to your computer and use it in GitHub Desktop.
Save vudaltsov/0bb623b9e2817d6ce359eb88cfbf229d to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
/**
* Computes the difference between two dates in milliseconds.
*
* @psalm-pure
*
* @return int $a - $b
*/
function time_diff_ms(DateTimeImmutable $a, DateTimeImmutable $b): int
{
$aMs = (int) $a->format('Uv');
$bMs = (int) $b->format('Uv');
return $aMs - $bMs;
}
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
/**
* @covers \time_diff_ms
* @small
*/
final class TimeDiffMsTest extends TestCase
{
public function testConstructorTime(): void
{
$expected =
1 * 24 * 60 * 60 * 1000 + // 1 day
3 * 60 * 60 * 1000 + // 3 hours
2 * 60 * 60 * 1000 + // 2 timezone hours
4 * 60 * 1000 + // 4 minutes
5 * 1000 + // 5 seconds
315 // 315 milliseconds
;
$actual = time_diff_ms(
new DateTimeImmutable('2020-01-02 03:04:05.315 -02:00'),
new DateTimeImmutable('2020-01-01 00:00:00.000 +00:00')
);
self::assertSame($expected, $actual);
}
public function testConstructorTimezone(): void
{
$expected = 1 * 60 * 60 * 1000; // 1 timezone hour
$actual = time_diff_ms(
new DateTimeImmutable('2020-01-01 00:00:00.000', new DateTimeZone('Europe/Moscow')),
new DateTimeImmutable('2020-01-01 00:00:00.000', new DateTimeZone('Europe/Samara')),
);
self::assertSame($expected, $actual);
}
/**
* DateTimeImmutable::setTimezone() does not change the timestamp!
*
* @see https://www.php.net/manual/ru/datetime.settimezone.php#117514
*/
public function testSetTimezone(): void
{
$now = new DateTimeImmutable();
$actual = time_diff_ms(
$now->setTimezone(new DateTimeZone('Europe/Moscow')),
$now->setTimezone(new DateTimeZone('Australia/Darwin')),
);
self::assertSame(0, $actual);
}
}
@alroniks
Copy link

alroniks commented Aug 6, 2020

Возможно будет полезна такая либа https://github.com/Alroniks/dtms, писал в свое время с целью бесшовно получить возможность оперировать миллисекундами, не сильно меняя код другой огромной библиотеки.

@alroniks
Copy link

alroniks commented Aug 6, 2020

Добавлю еще, что в DateTime и формате с микросекундами иногда случается плавающий баг с daylight переходами. Что-то вроде фиксили в новых версиях PHP, но иногда проскакивает все равно.

@vudaltsov
Copy link
Author

@alroniks, спасибо

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment