index/tests/DateTimeTest.php

386 lines
17 KiB
PHP

<?php
// DateTimeTest.php
// Created: 2021-06-14
// Updated: 2024-07-31
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use Index\DateTime;
use Index\TimeSpan;
use Index\TimeZoneInfo;
#[CoversClass(DateTime::class)]
#[CoversClass(TimeSpan::class)]
#[CoversClass(TimeZoneInfo::class)]
final class DateTimeTest extends TestCase {
public function testAttributes(): void {
$index = new DateTime('2021-06-14T21:07:14.359324 CEST');
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 21);
$this->assertEquals($index->getMinute(), 7);
$this->assertEquals($index->getSecond(), 14);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
$this->assertEquals($index->getDayOfWeek(), DateTime::MONDAY);
$this->assertEquals($index->getDayOfYear(), 165);
$this->assertEquals($index->getWeek(), 24);
$this->assertTrue($index->isDaylightSavingTime());
$this->assertFalse($index->isLeapYear());
$this->assertFalse($index->isUTC());
$indexDate = $index->getDate();
$this->assertEquals($indexDate->getYear(), 2021);
$this->assertEquals($indexDate->getMonth(), 6);
$this->assertEquals($indexDate->getDay(), 14);
$this->assertEquals($indexDate->getHour(), 0);
$this->assertEquals($indexDate->getMinute(), 0);
$this->assertEquals($indexDate->getSecond(), 0);
$this->assertEquals($indexDate->getMillisecond(), 0);
$this->assertEquals($indexDate->getMicrosecond(), 0);
$this->assertEquals($indexDate->getDayOfWeek(), DateTime::MONDAY);
$this->assertEquals($indexDate->getDayOfYear(), 165);
$this->assertEquals($indexDate->getWeek(), 24);
$indexTime = $index->getTimeOfDay();
$this->assertEquals($indexTime->getHours(), 21);
$this->assertEquals($indexTime->getMinutes(), 7);
$this->assertEquals($indexTime->getSeconds(), 14);
$this->assertEquals($indexTime->getMilliseconds(), 359);
$this->assertEquals($indexTime->getMicroseconds(), 359324);
}
public function testTimeZone(): void {
$index1 = DateTime::utcNow();
$index2 = DateTime::now(new TimeZoneInfo('Australia/Melbourne'));
$this->assertEquals($index1->getUnixTimeSeconds(), $index2->getUnixTimeSeconds());
}
public function testSetters(): void {
$index = new DateTime('2021-06-14T21:07:14.359324 CEST');
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 21);
$this->assertEquals($index->getMinute(), 7);
$this->assertEquals($index->getSecond(), 14);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
$index = $index->setDate(2005, 3, 9);
$this->assertEquals($index->getYear(), 2005);
$this->assertEquals($index->getMonth(), 3);
$this->assertEquals($index->getDay(), 9);
$this->assertEquals($index->getHour(), 21);
$this->assertEquals($index->getMinute(), 7);
$this->assertEquals($index->getSecond(), 14);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
$index = $index->setISODate(2011, 20, 5);
$this->assertEquals($index->getYear(), 2011);
$this->assertEquals($index->getMonth(), 5);
$this->assertEquals($index->getDay(), 20);
$this->assertEquals($index->getHour(), 21);
$this->assertEquals($index->getMinute(), 7);
$this->assertEquals($index->getSecond(), 14);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
$index = $index->setTime(10, 46, 50, 987654);
$this->assertEquals($index->getYear(), 2011);
$this->assertEquals($index->getMonth(), 5);
$this->assertEquals($index->getDay(), 20);
$this->assertEquals($index->getHour(), 10);
$this->assertEquals($index->getMinute(), 46);
$this->assertEquals($index->getSecond(), 50);
$this->assertEquals($index->getMillisecond(), 987);
$this->assertEquals($index->getMicrosecond(), 987654);
$index = $index->setTimestamp(1623702634);
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 22);
$this->assertEquals($index->getMinute(), 30);
$this->assertEquals($index->getSecond(), 34);
$this->assertEquals($index->getMillisecond(), 0);
$this->assertEquals($index->getMicrosecond(), 0);
$this->assertFalse($index->isUTC());
}
public function testUnixTimestamp(): void {
$index = DateTime::fromUnixTimeSeconds(1623696039);
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 18);
$this->assertEquals($index->getMinute(), 40);
$this->assertEquals($index->getSecond(), 39);
$this->assertEquals($index->getMillisecond(), 0);
$this->assertEquals($index->getMicrosecond(), 0);
$this->assertEquals($index->getUnixTimeSeconds(), 1623696039);
$this->assertEquals($index->getUnixTimeMilliseconds(), 1623696039000);
$this->assertTrue($index->isUTC());
$index = DateTime::fromUnixTimeMilliseconds(1623696422656);
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 18);
$this->assertEquals($index->getMinute(), 47);
$this->assertEquals($index->getSecond(), 2);
$this->assertEquals($index->getMillisecond(), 656);
$this->assertEquals($index->getMicrosecond(), 656000);
$this->assertEquals($index->getUnixTimeSeconds(), 1623696422);
$this->assertEquals($index->getUnixTimeMilliseconds(), 1623696422656);
$this->assertTrue($index->isUTC());
}
// verify the results of this at some point
public function testAdding(): void {
$index = new DateTime('2021-06-14T21:07:14.359324Z');
// Confirm initial state
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 21);
$this->assertEquals($index->getMinute(), 7);
$this->assertEquals($index->getSecond(), 14);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
// Add
$index = $index->add(TimeSpan::create(1, 0, 10, 0));
$this->assertEquals($index->getDay(), 15);
$this->assertEquals($index->getMinute(), 17);
// Add years
$index = $index->addYears(1);
$this->assertEquals($index->getYear(), 2022);
$this->assertEquals($index->getMonth(), 6);
$index = $index->addYears(1.5);
$this->assertEquals($index->getYear(), 2023);
$this->assertEquals($index->getMonth(), 12);
// Add months
$index = $index->addMonths(1);
$this->assertEquals($index->getMonth(), 12);
$this->assertEquals($index->getDay(), 16);
$index = $index->addMonths(1.5);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 15);
// Add days
$index = $index->addDays(1);
$this->assertEquals($index->getDay(), 16);
$this->assertEquals($index->getHour(), 21);
$index = $index->addDays(1.5);
$this->assertEquals($index->getDay(), 18);
$this->assertEquals($index->getHour(), 9);
// Add hours
$index = $index->addHours(1);
$this->assertEquals($index->getHour(), 10);
$this->assertEquals($index->getMinute(), 17);
$index = $index->addHours(1.5);
$this->assertEquals($index->getHour(), 11);
$this->assertEquals($index->getMinute(), 47);
// Add minutes
$index = $index->addMinutes(1);
$this->assertEquals($index->getMinute(), 48);
$this->assertEquals($index->getSecond(), 14);
$index = $index->addMinutes(1.5);
$this->assertEquals($index->getMinute(), 49);
$this->assertEquals($index->getSecond(), 44);
// Add seconds
$index = $index->addSeconds(1);
$this->assertEquals($index->getSecond(), 45);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
$index = $index->addSeconds(1.5);
$this->assertEquals($index->getSecond(), 46);
$this->assertEquals($index->getMillisecond(), 859);
$this->assertEquals($index->getMicrosecond(), 859324);
// Add milliseconds
$index = $index->addMilliseconds(1);
$this->assertEquals($index->getMillisecond(), 860);
$this->assertEquals($index->getMicrosecond(), 860324);
$index = $index->addMilliseconds(1.5);
$this->assertEquals($index->getMillisecond(), 861);
$this->assertEquals($index->getMicrosecond(), 861824);
// Add microseconds
$index = $index->addMicroseconds(1);
$this->assertEquals($index->getMicrosecond(), 861825);
$index = $index->addMicroseconds(1.5);
$this->assertEquals($index->getMicrosecond(), 861826);
}
public function testSubtract(): void {
$index = new DateTime('2021-06-14T21:07:14.359324Z');
// Confirm initial state
$this->assertEquals($index->getYear(), 2021);
$this->assertEquals($index->getMonth(), 6);
$this->assertEquals($index->getDay(), 14);
$this->assertEquals($index->getHour(), 21);
$this->assertEquals($index->getMinute(), 7);
$this->assertEquals($index->getSecond(), 14);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
// Subtract
$index = $index->subtract(TimeSpan::fromDays(400.12));
$this->assertEquals($index->getYear(), 2020);
$this->assertEquals($index->getMonth(), 5);
$this->assertEquals($index->getDay(), 10);
$this->assertEquals($index->getHour(), 18);
$this->assertEquals($index->getMinute(), 14);
$this->assertEquals($index->getSecond(), 26);
$this->assertEquals($index->getMillisecond(), 359);
$this->assertEquals($index->getMicrosecond(), 359324);
}
public function testDifference(): void {
$index1 = new DateTime('2021-06-14T21:07:14Z');
$index2 = DateTime::create(2013, 1, 27, 23, 14, 44, 0, new TimeZoneInfo('Europe/Amsterdam'));
$diff = $index1->difference($index2);
$this->assertEquals($diff->getDays(), 3061);
$this->assertEquals($diff->getHours(), 22);
$this->assertEquals($diff->getMinutes(), 52);
$this->assertEquals($diff->getSeconds(), 30);
$this->assertTrue($diff->isNegative());
$this->assertEquals($diff->totalDays(), 3061.953125);
$this->assertEquals($diff->totalHours(), 73486.875);
$this->assertEquals($diff->totalMinutes(), 4409212.5);
$this->assertEquals($diff->totalSeconds(), 264552750);
$this->assertEquals($diff->totalMilliseconds(), 264552750000);
$this->assertEquals($diff->totalMicroseconds(), 264552750000000);
$negated = $diff->negate();
$this->assertEquals($negated->getDays(), 3061);
$this->assertEquals($negated->getHours(), 22);
$this->assertEquals($negated->getMinutes(), 52);
$this->assertEquals($negated->getSeconds(), 30);
$this->assertFalse($negated->isNegative());
}
public function testModify(): void {
$index = new DateTime('2021-06-14T21:07:14Z');
$this->assertEquals($index->getMonth(), 6);
$index = $index->modify('+1 month');
$this->assertEquals($index->getMonth(), 7);
}
public function testCreate(): void {
$index = DateTime::create(2013, 1, 27, 23, 14, 44, 0, new TimeZoneInfo('Europe/Amsterdam'));
$this->assertEquals($index->getYear(), 2013);
$this->assertEquals($index->getMonth(), 1);
$this->assertEquals($index->getDay(), 27);
$this->assertEquals($index->getHour(), 23);
$this->assertEquals($index->getMinute(), 14);
$this->assertEquals($index->getSecond(), 44);
$index = $index->setTimezone(new TimeZoneInfo('UTC'));
$this->assertEquals($index->getHour(), 22);
$index = $index->setTimezone(new TimeZoneInfo('Asia/Tokyo'));
$this->assertEquals($index->getDay(), 28);
$this->assertEquals($index->getHour(), 7);
$index = $index->setTimezone(new TimeZoneInfo('America/New_York'));
$this->assertEquals($index->getDay(), 27);
$this->assertEquals($index->getHour(), 17);
$index = DateTime::createFromFormat('Y-m-d H:i:s', '2012-05-20 10:14:28');
$this->assertEquals($index->format('Y-m-d H:i:s'), '2012-05-20 10:14:28');
$this->assertFalse(DateTime::createFromFormat('Y-m-d H:i:s', 'mewow'));
$mutable = new \DateTime('2021-06-14T20:20:46Z');
$index = DateTime::createFromInterface($mutable);
$this->assertEquals($index->getUnixTimeMilliseconds(), (float)$mutable->format('Uv'));
$this->assertEquals($index->getTimezone()->getName(), '+00:00');
$index = DateTime::createFromMutable($mutable);
$this->assertEquals($index->getUnixTimeMilliseconds(), (float)$mutable->format('Uv'));
}
public function testToString(): void {
$dateTime = DateTime::create(2013, 1, 27, 23, 14, 44, 0, new TimeZoneInfo('Europe/Amsterdam'));
$this->assertEquals((string)$dateTime, '2013-01-27T23:14:44+01:00');
$this->assertEquals(json_encode($dateTime), '"2013-01-27T23:14:44+01:00"');
$this->assertEquals((string)$dateTime->toISO8601String(), '2013-01-27T23:14:44+01:00');
$this->assertEquals((string)$dateTime->toCookieString(), 'Sunday, 27-Jan-2013 23:14:44 CET');
$this->assertEquals((string)$dateTime->toRFC822String(), 'Sun, 27 Jan 13 23:14:44 +0100');
$dateTime = $dateTime->setTimezone(TimeZoneInfo::utc());
$this->assertEquals((string)$dateTime, '2013-01-27T22:14:44+00:00');
$this->assertEquals(json_encode($dateTime), '"2013-01-27T22:14:44+00:00"');
$this->assertEquals((string)$dateTime->toISO8601String(), '2013-01-27T22:14:44+00:00');
$this->assertEquals((string)$dateTime->toCookieString(), 'Sunday, 27-Jan-2013 22:14:44 UTC');
$this->assertEquals((string)$dateTime->toRFC822String(), 'Sun, 27 Jan 13 22:14:44 +0000');
}
public function testCompare(): void {
$index1 = new DateTime('2021-06-14T21:07:14Z');
$index2 = DateTime::create(2013, 1, 27, 23, 14, 44, 0, new TimeZoneInfo('Europe/Amsterdam'));
$this->assertGreaterThan(0, $index1->compare($index2));
$this->assertLessThan(0, $index2->compare($index1));
$this->assertEquals(0, $index1->compare($index1));
}
public function testEquals(): void {
$index1 = new DateTime('2021-06-14T21:07:14Z');
$index2 = DateTime::create(2013, 1, 27, 23, 14, 44, 0, new TimeZoneInfo('Europe/Amsterdam'));
$this->assertFalse($index1->equals($index2));
$this->assertFalse($index2->equals($index1));
$this->assertTrue($index1->equals($index1));
}
public function testCasting(): void {
$nativeDT = new \DateTime;
$this->assertInstanceOf(DateTime::class, $nativeDTCast = DateTime::cast($nativeDT));
$this->assertNotSame($nativeDT, $nativeDTCast);
$indexDT = new DateTime;
$this->assertInstanceOf(DateTime::class, $indexDTCast = DateTime::cast($indexDT));
$this->assertSame($indexDT, $indexDTCast);
}
public function testTimeZoneOrder(): void {
$all = TimeZoneInfo::all(true);
$lastOffset = null;
$lastString = null;
foreach($all as $timeZone) {
$offset = $timeZone->getOffset();
$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;
}
}
}