From 8ca3ac257db34ddfb9a5edf684fa24efea72ccff Mon Sep 17 00:00:00 2001 From: Corey Taylor Date: Sun, 24 Sep 2023 22:35:53 -0500 Subject: [PATCH] Allow setting time zone when converting to DateTimeImmutable --- src/ChronosDate.php | 20 ++++++++++++++------ src/ChronosTime.php | 12 ++++++++---- tests/TestCase/ChronosTimeTest.php | 13 +++++++++++-- tests/TestCase/Date/StringsTest.php | 12 +++++++++--- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/ChronosDate.php b/src/ChronosDate.php index 8245df8..db84023 100644 --- a/src/ChronosDate.php +++ b/src/ChronosDate.php @@ -1578,25 +1578,33 @@ public function diffForHumans(?ChronosDate $other = null, bool $absolute = false } /** - * Returns the date as a `DateTimeImmutable` instance. + * Returns the date as a `DateTimeImmutable` instance at midnight. * + * @param \DateTimeZone|string|null $timezone Time zone the DateTimeImmutable instance will be in * @return \DateTimeImmutable */ - public function toDateTimeImmutable(): DateTimeImmutable + public function toDateTimeImmutable(DateTimeZone|string|null $timezone = null): DateTimeImmutable { - return $this->native; + if ($timezone === null) { + return $this->native; + } + + $timezone = is_string($timezone) ? new DateTimeZone($timezone) : $timezone; + + return new DateTimeImmutable($this->native->format('Y-m-d H:i:s.u'), $timezone); } /** - * Returns an `DateTimeImmutable` instance set to this clock time. + * Returns the date as a `DateTimeImmutable` instance at midnight. * * Alias of `toDateTimeImmutable()`. * + * @param \DateTimeZone|string|null $timezone Time zone the DateTimeImmutable instance will be in * @return \DateTimeImmutable */ - public function toNative(): DateTimeImmutable + public function toNative(DateTimeZone|string|null $timezone = null): DateTimeImmutable { - return $this->toDateTimeImmutable(); + return $this->toDateTimeImmutable($timezone); } /** diff --git a/src/ChronosTime.php b/src/ChronosTime.php index df84d95..7c928e6 100644 --- a/src/ChronosTime.php +++ b/src/ChronosTime.php @@ -447,11 +447,14 @@ public function between(ChronosTime $start, ChronosTime $end, bool $equals = tru /** * Returns an `DateTimeImmutable` instance set to this clock time. * + * @param \DateTimeZone|string|null $timezone Time zone the DateTimeImmutable instance will be in * @return \DateTimeImmutable */ - public function toDateTimeImmutable(): DateTimeImmutable + public function toDateTimeImmutable(DateTimeZone|string|null $timezone = null): DateTimeImmutable { - return (new DateTimeImmutable())->setTime( + $timezone = is_string($timezone) ? new DateTimeZone($timezone) : $timezone; + + return (new DateTimeImmutable(timezone: $timezone))->setTime( $this->getHours(), $this->getMinutes(), $this->getSeconds(), @@ -464,10 +467,11 @@ public function toDateTimeImmutable(): DateTimeImmutable * * Alias of `toDateTimeImmutable()`. * + * @param \DateTimeZone|string|null $timezone Time zone the DateTimeImmutable instance will be in * @return \DateTimeImmutable */ - public function toNative(): DateTimeImmutable + public function toNative(DateTimeZone|string|null $timezone = null): DateTimeImmutable { - return $this->toDateTimeImmutable(); + return $this->toDateTimeImmutable($timezone); } } diff --git a/tests/TestCase/ChronosTimeTest.php b/tests/TestCase/ChronosTimeTest.php index a5a0b1c..68f3e79 100644 --- a/tests/TestCase/ChronosTimeTest.php +++ b/tests/TestCase/ChronosTimeTest.php @@ -262,11 +262,20 @@ public function testComparisons(): void public function testToDateTimeImmutable(): void { - $native = ChronosTime::parse('23:59:59.999999')->toDateTimeImmutable(); + $time = ChronosTime::parse('23:59:59.999999'); + $native = $time->toDateTimeImmutable(); $this->assertSame('23:59:59.999999', $native->format('H:i:s.u')); - $native = ChronosTime::parse('23:59:59.999999')->toNative(); + $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 diff --git a/tests/TestCase/Date/StringsTest.php b/tests/TestCase/Date/StringsTest.php index f91312c..aede1d4 100644 --- a/tests/TestCase/Date/StringsTest.php +++ b/tests/TestCase/Date/StringsTest.php @@ -176,9 +176,15 @@ public function testToW3cString() public function testToDateTimeImmutable(): void { $d = ChronosDate::now(); - $this->assertSame($d->format('Y-m-d'), $d->toDateTimeImmutable()->format('Y-m-d')); + $this->assertSame($d->format('Y-m-d H:i:s.u'), $d->toDateTimeImmutable()->format('Y-m-d H:i:s.u')); + $this->assertSame($d->format('Y-m-d H:i:s.u'), $d->toNative()->format('Y-m-d H:i:s.u')); - $d = ChronosDate::now(); - $this->assertSame($d->format('Y-m-d'), $d->toNative()->format('Y-m-d')); + $native = $d->toDateTimeImmutable('Asia/Tokyo'); + $this->assertSame($d->format('Y-m-d H:i:s.u'), $native->format('Y-m-d H:i:s.u')); + $this->assertSame('Asia/Tokyo', $native->getTimezone()->getName()); + + $native = $d->toNative('Asia/Tokyo'); + $this->assertSame($d->format('Y-m-d H:i:s.u'), $native->format('Y-m-d H:i:s.u')); + $this->assertSame('Asia/Tokyo', $native->getTimezone()->getName()); } }