assertSame('12:13:14.123456', $t->format('H:i:s.u')); $t = new ChronosTime(); $this->assertSame('12:13:14.123456', $t->format('H:i:s.u')); } public function testConstructFromString(): void { $t = new ChronosTime('12:13'); $this->assertSame('12:13:00.000000', $t->format('H:i:s.u')); $t = new ChronosTime('0.0.0.0'); $this->assertSame('00:00:00.000000', $t->format('H:i:s.u')); $t = new ChronosTime('1:01:1.000001'); $this->assertSame('01:01:01.000001', $t->format('H:i:s.u')); $t = new ChronosTime('23:59.59.999999'); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); $t = new ChronosTime('23:59.59.9999991'); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); $t = new ChronosTime('24:59.59.9999991'); $this->assertSame('00:59:59.999999', $t->format('H:i:s.u')); } public function testConstructFromStringWithFractionalSeconds(): void { // The fractional part is a fraction of a second, matching DateTime. $t = new ChronosTime('12:00:00.5'); $this->assertSame('12:00:00.500000', $t->format('H:i:s.u')); $t = new ChronosTime('12:00:00.05'); $this->assertSame('12:00:00.050000', $t->format('H:i:s.u')); $t = new ChronosTime('12:00:00.000005'); $this->assertSame('12:00:00.000005', $t->format('H:i:s.u')); } public function testConstructFromInstance(): void { $t = new ChronosTime(new DateTimeImmutable('23:59:59.999999')); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); $t = new ChronosTime(new Chronos('23:59:59.999999')); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); $t = new ChronosTime(new ChronosTime(new Chronos('23:59:59.999999'))); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); } public function testConstructInvalid(): void { $this->expectException(InvalidArgumentException::class); new ChronosTime('tomorrow'); } public function testConstructIncomplete(): void { $this->expectException(InvalidArgumentException::class); new ChronosTime('23'); } public function testConstructInvalidHours(): void { $this->expectException(InvalidArgumentException::class); new ChronosTime('25:00:00'); } public function testConstructInvalidMinutes(): void { $this->expectException(InvalidArgumentException::class); new ChronosTime('23:60:00'); } public function testConstructInvalidSeconds(): void { $this->expectException(InvalidArgumentException::class); new ChronosTime('23:59:60'); } public function testParse(): void { $t = ChronosTime::parse('23:59:59.999999'); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); Chronos::setTestNow(new Chronos('2001-01-01 12:13:14.123456', 'America/Chicago')); $t = ChronosTime::parse(null, 'America/New_York'); $this->assertSame('13:13:14.123456', $t->format('H:i:s.u')); } public function testNow(): void { Chronos::setTestNow(new Chronos('2001-01-01 12:13:14.123456', 'America/Chicago')); $t = ChronosTime::now(); $this->assertSame('12:13:14.123456', $t->format('H:i:s.u')); $t = ChronosTime::now('America/New_York'); $this->assertSame('13:13:14.123456', $t->format('H:i:s.u')); } public function testMidnight(): void { $t = ChronosTime::midnight(); $this->assertSame('00:00:00.000000', $t->format('H:i:s.u')); } public function testNoon(): void { $t = ChronosTime::noon(); $this->assertSame('12:00:00.000000', $t->format('H:i:s.u')); } public function testEndOfDay(): void { $t = ChronosTime::endOfDay(); $this->assertSame('23:59:59.000000', $t->format('H:i:s.u')); $t = ChronosTime::endOfDay(microseconds: true); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); } public function testSetters(): void { $t = ChronosTime::midnight()->setHours(24); $this->assertSame('00:00:00.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setHours(-1); $this->assertSame('23:00:00.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setMinutes(60); $this->assertSame('01:00:00.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setMinutes(-1); $this->assertSame('23:59:00.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setSeconds(60); $this->assertSame('00:01:00.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setSeconds(-1); $this->assertSame('23:59:59.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setMicroseconds(1_000_000); $this->assertSame('00:00:01.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setMicroseconds(-1); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setHours(25)->setMinutes(120)->setSeconds(120)->setMicroseconds(2_000_001); $this->assertSame('03:02:02.000001', $t->format('H:i:s.u')); } public function testGetters(): void { $t = ChronosTime::midnight()->setTime(-1, -1, -1, -1); $this->assertSame(22, $t->getHours()); $this->assertSame(58, $t->getMinutes()); $this->assertSame(58, $t->getSeconds()); $this->assertSame(999_999, $t->getMicroseconds()); } public function testSetTime(): void { $t = new ChronosTime(); $new = $t->setTime(); $this->assertNotSame($new, $t); $this->assertSame('00:00:00.000000', $new->format('H:i:s.u')); $t = ChronosTime::midnight()->setTime(24, 120, 120, 1_000_000); $this->assertSame('02:02:01.000000', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setTime(-1, -1, -1, -1); $this->assertSame('22:58:58.999999', $t->format('H:i:s.u')); $t = ChronosTime::midnight()->setTime(-1, 120, -1, 1_000_001); $this->assertSame('01:00:00.000001', $t->format('H:i:s.u')); } public function testStartOfHour(): void { $t = ChronosTime::parse('12:30:45.123456'); $start = $t->startOfHour(); $this->assertNotSame($t, $start); $this->assertSame('12:00:00.000000', $start->format('H:i:s.u')); $t = ChronosTime::parse('00:59:59.999999'); $this->assertSame('00:00:00.000000', $t->startOfHour()->format('H:i:s.u')); $t = ChronosTime::parse('23:01:01'); $this->assertSame('23:00:00.000000', $t->startOfHour()->format('H:i:s.u')); } public function testEndOfHour(): void { $t = ChronosTime::parse('12:30:45.123456'); $end = $t->endOfHour(); $this->assertNotSame($t, $end); $this->assertSame('12:59:59.999999', $end->format('H:i:s.u')); $t = ChronosTime::parse('00:00:00'); $this->assertSame('00:59:59.999999', $t->endOfHour()->format('H:i:s.u')); $t = ChronosTime::parse('23:30:00'); $this->assertSame('23:59:59.999999', $t->endOfHour()->format('H:i:s.u')); } public function testFormat(): void { $t = new ChronosTime('23:59:59.999999'); $this->assertSame('23:59:59.999999', $t->format('H:i:s.u')); } public function testComparisons(): void { $t1 = ChronosTime::parse('00:00:00'); $t2 = ChronosTime::parse('00:00:00'); $this->assertTrue($t1->equals($t2)); $this->assertTrue($t1->greaterThanOrEquals($t2)); $this->assertTrue($t1->lessThanOrEquals($t2)); $this->assertFalse($t1->greaterThan($t2)); $this->assertFalse($t1->lessThan($t2)); $t1 = ChronosTime::parse('00:00:00'); $t2 = ChronosTime::parse('00:00:00')->setHours(24); $this->assertTrue($t1->equals($t2)); $this->assertTrue($t1->greaterThanOrEquals($t2)); $this->assertTrue($t1->lessThanOrEquals($t2)); $this->assertFalse($t1->greaterThan($t2)); $this->assertFalse($t1->lessThan($t2)); $t1 = ChronosTime::parse('00:00:00'); $t2 = ChronosTime::parse('00:00:00.000001'); $this->assertTrue($t1->lessThan($t2)); $this->assertTrue($t1->lessThanOrEquals($t2)); $this->assertFalse($t1->equals($t2)); $this->assertFalse($t1->greaterThan($t2)); $this->assertFalse($t1->greaterThanOrEquals($t2)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00'); $this->assertTrue($t1->greaterThan($t2)); $this->assertTrue($t1->greaterThanOrEquals($t2)); $this->assertFalse($t1->equals($t2)); $this->assertFalse($t1->lessThan($t2)); $this->assertFalse($t1->lessThanOrEquals($t2)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertTrue($t2->between($t1, $t3)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertTrue($t2->between($t1, $t3, false)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertTrue($t1->between($t1, $t3, true)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertFalse($t1->between($t1, $t3, false)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertTrue($t2->between($t3, $t1, false)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertFalse($t1->between($t2, $t3)); $t1 = ChronosTime::parse('00:00:00.000001'); $t2 = ChronosTime::parse('00:00:00.000002'); $t3 = ChronosTime::parse('00:00:00.000003'); $this->assertFalse($t3->between($t1, $t2)); } public function testIsStartOfDay(): void { $this->assertTrue(ChronosTime::parse('00:00:00')->isStartOfDay()); $this->assertTrue(ChronosTime::midnight()->isStartOfDay()); $this->assertFalse(ChronosTime::parse('00:00:00.000001')->isStartOfDay()); $this->assertFalse(ChronosTime::parse('00:00:01')->isStartOfDay()); $this->assertFalse(ChronosTime::noon()->isStartOfDay()); } public function testIsEndOfDay(): void { $this->assertTrue(ChronosTime::parse('23:59:59')->isEndOfDay()); $this->assertTrue(ChronosTime::endOfDay()->isEndOfDay()); $this->assertTrue(ChronosTime::parse('23:59:59.999999')->isEndOfDay()); $this->assertFalse(ChronosTime::parse('23:59:58')->isEndOfDay()); $this->assertFalse(ChronosTime::midnight()->isEndOfDay()); $this->assertFalse(ChronosTime::noon()->isEndOfDay()); } public function testIsMidnight(): void { $this->assertTrue(ChronosTime::midnight()->isMidnight()); $this->assertTrue(ChronosTime::parse('00:00:00')->isMidnight()); $this->assertFalse(ChronosTime::parse('00:00:00.000001')->isMidnight()); $this->assertFalse(ChronosTime::noon()->isMidnight()); } public function testIsMidday(): void { $this->assertTrue(ChronosTime::noon()->isMidday()); $this->assertTrue(ChronosTime::parse('12:00:00')->isMidday()); $this->assertFalse(ChronosTime::parse('12:00:00.000001')->isMidday()); $this->assertFalse(ChronosTime::parse('12:00:01')->isMidday()); $this->assertFalse(ChronosTime::midnight()->isMidday()); } public function testToDateTimeImmutable(): void { $time = ChronosTime::parse('23:59:59.999999'); $native = $time->toDateTimeImmutable(); $this->assertSame('23:59:59.999999', $native->format('H:i:s.u')); $native = $time->toNative(); $this->assertSame('23:59:59.999999', $native->format('H:i:s.u')); $native = $time->toDateTimeImmutable('Asia/Tokyo'); $this->assertSame('23:59:59.999999', $native->format('H:i:s.u')); $this->assertSame('Asia/Tokyo', $native->getTimezone()->getName()); $native = $time->toNative('Asia/Tokyo'); $this->assertSame('23:59:59.999999', $native->format('H:i:s.u')); $this->assertSame('Asia/Tokyo', $native->getTimezone()->getName()); } public function testToString(): void { $t = new ChronosTime('12:13:14.123456'); $this->assertSame('12:13:14', (string)$t); ChronosTime::setToStringFormat('H:i:s.u'); $this->assertSame('12:13:14.123456', (string)$t); ChronosTime::resetToStringFormat(); $this->assertSame('12:13:14', (string)$t); } public function testToArray(): void { $t = new ChronosTime('12:30:45.123456'); $array = $t->toArray(); $this->assertSame(12, $array['hour']); $this->assertSame(30, $array['minute']); $this->assertSame(45, $array['second']); $this->assertSame(123456, $array['microsecond']); $this->assertCount(4, $array); } }