Enlever les microsecondes d'un objet DateTime PHP

Publié le 23/01/2021 • Mis à jour le 23/01/2021


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

Dans ce bout de code, nous allons voir comment enlever les microsecondes d'un objet DateTime PHP. C'était un changement très impactant de PHP 7.0 à PHP 7.1 : quand on créé un nouvel object \DateTime, celui-ci inclue désormais les microsecondes, ce n'était pas le cas pour PHP 7.0. Avec des objets immuables utilisez $now = $this->removeAboveSeconds($now);. À noter qu'on a ici on a un bel exemple de cas d'utilisation des union types de PHP 8. Dans la fonction removeAboveSeconds(), avec PHP 8 on pourrait typer le paramètre \DateTime|\DateTimeImmutable $dateTime, supprimer l'annotation relative et le test instanceof, une belle simplification ! Si vous voulez juste avoir le jour courant sans le temps, vous pouvez utiliser new \DateTime('today').


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

/**
 * J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
 * Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
 * ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Les services sont injectés dans le constructeur du contrôleur principal.
 */
trait Snippet131Trait
{
    public function snippet131(): void
    {
        $now = new \DateTime();
        var_dump($now);

        $this->removeAboveSeconds($now);
        var_dump($now);

        $today = new \DateTime('today');
        var_dump($today);

        echo 'OK'; // That's it! 😁
    }

    public function removeAboveSeconds(\DateTimeInterface $dateTime): \DateTimeInterface
    {
        if (!$dateTime instanceof \DateTime) {
            throw new \InvalidArgumentException('Invalid date object.');
        }

        return $dateTime->setTime(
            (int) $dateTime->format('G'), // hours
            (int) $dateTime->format('i'), // minutes
            (int) $dateTime->format('s')  // seconds
        );
    }
}

 Exécuter le snippet  ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  Plus sur Stackoverflow   Lire la doc  Plus sur le web

<?php

declare(strict_types=1);

namespace App\Tests\Controller\Snippets;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @covers Snippet131Trait
 */
final class Snippet131Test extends KernelTestCase
{
    /**
     * @covers Snippet131Trait::snippet131
     */
    public function testSnippet131(): void
    {
        $now = new \DateTime();
        $this->removeAboveSeconds($now);

        self::assertSame(0, (int) $now->format('u'));
        self::assertSame(0, (int) $now->format('v'));

        $now = new \DateTime('today');
        self::assertSame(0, (int) $now->format('G'));
        self::assertSame(0, (int) $now->format('i'));
        self::assertSame(0, (int) $now->format('u'));
        self::assertSame(0, (int) $now->format('v'));
    }

    public function removeAboveSeconds(\DateTime $dateTime): \DateTimeInterface
    {
        return $dateTime->setTime(
            (int) $dateTime->format('G'), // hours
            (int) $dateTime->format('i'), // minutes
            (int) $dateTime->format('s')  // seconds
        );
    }
}