Skip to content

Commit 77aadc4

Browse files
committed
PHPORM-143 Ensure date are read using local timezone
1 parent 2829bbc commit 77aadc4

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## [4.1.3] - unreleased
5+
6+
* Fix timezone of `Date` fields read from the database by @GromNaN in [#2739](https://github.com/mongodb/laravel-mongodb/pull/2739)
7+
48
## [4.1.2] - 2024-02-22
59

610
* Fix support for subqueries using the query builder by @GromNaN in [#2717](https://github.com/mongodb/laravel-mongodb/pull/2717)

src/Eloquent/Model.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Carbon\CarbonInterface;
88
use DateTimeInterface;
9+
use DateTimeZone;
910
use Illuminate\Contracts\Queue\QueueableCollection;
1011
use Illuminate\Contracts\Queue\QueueableEntity;
1112
use Illuminate\Contracts\Support\Arrayable;
@@ -30,6 +31,7 @@
3031
use function array_values;
3132
use function class_basename;
3233
use function count;
34+
use function date_default_timezone_get;
3335
use function explode;
3436
use function func_get_args;
3537
use function in_array;
@@ -137,7 +139,8 @@ protected function asDateTime($value)
137139
{
138140
// Convert UTCDateTime instances to Carbon.
139141
if ($value instanceof UTCDateTime) {
140-
return Date::instance($value->toDateTime());
142+
return Date::instance($value->toDateTime())
143+
->setTimezone(new DateTimeZone(date_default_timezone_get()));
141144
}
142145

143146
return parent::asDateTime($value);

tests/ModelTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@
3131
use function abs;
3232
use function array_keys;
3333
use function array_merge;
34+
use function date_default_timezone_set;
3435
use function get_debug_type;
3536
use function hex2bin;
3637
use function sleep;
3738
use function sort;
3839
use function strlen;
3940
use function time;
4041

42+
use const DATE_ATOM;
43+
4144
class ModelTest extends TestCase
4245
{
4346
public function tearDown(): void
@@ -670,6 +673,33 @@ public function testUnsetDotAttributesAndSet(): void
670673
$this->assertSame(['note2' => 'DEF', 'note1' => 'ABC'], $user->notes);
671674
}
672675

676+
public function testDateUseLocalTimeZone(): void
677+
{
678+
// The default timezone is reset to UTC before every test in OrchestraTestCase
679+
$tz = 'Australia/Sydney';
680+
date_default_timezone_set($tz);
681+
682+
$date = new DateTime('1965/03/02 15:30:10');
683+
$user = User::create(['birthday' => $date]);
684+
$this->assertInstanceOf(Carbon::class, $user->birthday);
685+
$this->assertEquals($tz, $user->birthday->getTimezone()->getName());
686+
$user->save();
687+
688+
$user = User::find($user->_id);
689+
$this->assertEquals($date, $user->birthday);
690+
$this->assertEquals($tz, $user->birthday->getTimezone()->getName());
691+
$this->assertSame('1965-03-02T15:30:10+10:00', $user->birthday->format(DATE_ATOM));
692+
693+
$tz = 'America/New_York';
694+
date_default_timezone_set($tz);
695+
$user = User::find($user->_id);
696+
$this->assertEquals($date, $user->birthday);
697+
$this->assertEquals($tz, $user->birthday->getTimezone()->getName());
698+
$this->assertSame('1965-03-02T00:30:10-05:00', $user->birthday->format(DATE_ATOM));
699+
700+
date_default_timezone_set('UTC');
701+
}
702+
673703
public function testDates(): void
674704
{
675705
$user = User::create(['name' => 'John Doe', 'birthday' => new DateTime('1965/1/1')]);

0 commit comments

Comments
 (0)