Calculating the number of days until the end of the year with PHP

Published on 2023-06-21 • Modified on 2023-06-21

This snippet show how to calculate the number of days until the end of the year with PHP. PHP correctly calculates the "z" format even when it's a leap year and will add one day when required.


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

/**
 * I am using a PHP trait to isolate each snippet in a file.
 * This code should be called from a Symfony controller extending AbstractController (as of Symfony 4.2)
 * or Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Services are injected in the main controller constructor.
 */
trait Snippet262Trait
{
    public function snippet262(): void
    {
        $today = new \DateTime('today');
        $lastDayOfYear = new \DateTime(date('Y-12-31'));
        $daysLeft = (int) $lastDayOfYear->format('z') - (int) $today->format('z');
        $isLeapYear = (bool) $today->format('L');

        echo 'Today: '.$today->format('Y-m-d').PHP_EOL;
        echo $today->format('Y').($isLeapYear ? ' IS' : ' IS NOT').' a leap year.'.PHP_EOL;
        echo "There are $daysLeft day(s) until the end of year! Hurry up! (excluding the current day)";

        // That's it! 😁
    }
}

 Run this snippet  ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  More on Stackoverflow   Read the doc  More on the web

  Work with me!

<?php

declare(strict_types=1);

namespace App\Tests\Integration\Controller\Snippets;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @see Snippet262Trait
 */
final class Snippet262Test extends KernelTestCase
{
    /**
     * @return iterable<int, array{0: string, 1: int}>
     */
    public function provideSnippet262(): iterable
    {
        // leap year
        yield ['2020-01-01', 365];
        yield ['2020-02-01', 334];
        yield ['2020-02-28', 307];
        yield ['2020-02-29', 306];
        yield ['2020-03-01', 305];

        // Normal year
        yield ['2023-01-01', 364];
        yield ['2023-02-01', 333];
        yield ['2023-02-28', 306];
        yield ['2023-03-01', 305]; // count since march are identical
    }

    /**
     * @see Snippet262Trait::snippet262
     *
     * @dataProvider provideSnippet262
     */
    public function testSnippet262(string $date, int $expected): void
    {
        $today = new \DateTime($date);
        $lastDayOfYear = new \DateTime(date(\sprintf('%s-12-31', $today->format('Y'))));
        $daysLeft = (int) $lastDayOfYear->format('z') - (int) $today->format('z');

        self::assertSame($expected, $daysLeft, 'Wrong count for '.$date);
    }
}