<?php
// XDateTimeTest.php
// Created: 2021-06-14
// Updated: 2024-07-31

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use Index\XDateTime;

#[CoversClass(XDateTime::class)]
final class XDateTimeTest extends TestCase {
    public function testToString(): void {
        $dateTime = new DateTime('2013-01-27T23:14:44', new DateTimeZone('Europe/Amsterdam'));
        $this->assertEquals(XDateTime::toISO8601String($dateTime), '2013-01-27T23:14:44+01:00');
        $this->assertEquals(XDateTime::toCookieString($dateTime), 'Sunday, 27-Jan-2013 23:14:44 CET');
        $this->assertEquals(XDateTime::toRFC822String($dateTime), 'Sun, 27 Jan 13 23:14:44 +0100');

        $dateTime = $dateTime->setTimezone(new DateTimeZone('UTC'));
        $this->assertEquals(XDateTime::toISO8601String($dateTime), '2013-01-27T22:14:44+00:00');
        $this->assertEquals(XDateTime::toCookieString($dateTime), 'Sunday, 27-Jan-2013 22:14:44 UTC');
        $this->assertEquals(XDateTime::toRFC822String($dateTime), 'Sun, 27 Jan 13 22:14:44 +0000');

        $this->assertEquals(XDateTime::toISO8601String(1359324884), '2013-01-27T22:14:44+00:00');
        $this->assertEquals(XDateTime::toCookieString(1359324884), 'Sunday, 27-Jan-2013 22:14:44 GMT');
        $this->assertEquals(XDateTime::toRFC822String(1359324884), 'Sun, 27 Jan 13 22:14:44 +0000');

        $this->assertEquals(XDateTime::toISO8601String('January 27th 2013 22:14:44 UTC'), '2013-01-27T22:14:44+00:00');
        $this->assertEquals(XDateTime::toCookieString('January 27th 2013 22:14:44 UTC'), 'Sunday, 27-Jan-2013 22:14:44 GMT');
        $this->assertEquals(XDateTime::toRFC822String('January 27th 2013 22:14:44 UTC'), 'Sun, 27 Jan 13 22:14:44 +0000');
    }

    public function testCompare(): void {
        $dt1 = '2021-06-14T21:07:14Z';
        $dt2 = new DateTimeImmutable('2013-01-27T23:14:44', new DateTimeZone('Europe/Amsterdam'));

        $this->assertGreaterThan(0, XDateTime::compare($dt1, $dt2));
        $this->assertLessThan(0, XDateTime::compare($dt2, $dt1));
        $this->assertEquals(0, XDateTime::compare($dt1, $dt1));
        $this->assertEquals(0, XDateTime::compare($dt2, $dt2));
    }

    public function testTimeZoneOrder(): void {
        $timeZones = XDateTime::listTimeZones(true);
        $lastOffset = null;
        $lastString = null;

        $now = XDateTime::now();
        foreach($timeZones as $timeZone) {
            $offset = $timeZone->getOffset($now);
            $string = $timeZone->getName();

            if($lastOffset !== null) {
                $diff = $lastOffset <=> $offset;
                $this->assertLessThanOrEqual(0, $diff);

                if($diff === 0)
                    $this->assertLessThanOrEqual(0, $lastString <=> $string);
            }

            $lastOffset = $offset;
            $lastString = $string;
        }
    }
}