Skip to content

Commit

Permalink
Augment dates using display_timezone config
Browse files Browse the repository at this point in the history
  • Loading branch information
duncanmcclean committed Jan 31, 2025
1 parent d320852 commit a133e51
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
15 changes: 15 additions & 0 deletions config/system.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@

'date_format' => 'F jS, Y',

/*
|--------------------------------------------------------------------------
| Display Timezone
|--------------------------------------------------------------------------
|
| Dates and times are stored in UTC. This setting allows you to determine which
| timezone dates and times are displayed in. For a full list of supported timezones,
| please see the PHP documentation.
|
| https://www.php.net/manual/en/timezones.php
|
*/

'display_timezone' => 'UTC',

/*
|--------------------------------------------------------------------------
| Default Character Set
Expand Down
7 changes: 4 additions & 3 deletions src/Fieldtypes/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ public function augment($value)
}

if ($value instanceof Carbon) {
return $value;
return $value->setTimezone(config('statamic.system.display_timezone'));
}

if ($this->config('mode') === 'range') {
Expand All @@ -321,7 +321,8 @@ public function augment($value)
];
}

$date = $this->parseSaved($value);
$date = $this->parseSaved($value)
->setTimezone(config('statamic.system.display_timezone'));

if (! $this->config('time_enabled')) {
$date->startOfDay();
Expand Down Expand Up @@ -349,7 +350,7 @@ public function toQueryableValue($value)
private function parseSaved($value)
{
try {
return Carbon::createFromFormat($this->saveFormat(), $value);
return Carbon::createFromFormat($this->saveFormat(), $value, 'UTC');
} catch (InvalidFormatException|InvalidArgumentException $e) {
return Carbon::parse($value);
}
Expand Down
38 changes: 36 additions & 2 deletions tests/Fieldtypes/DateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ public function setUp(): void

#[Test]
#[DataProvider('augmentProvider')]
public function it_augments($config, $value, $expected)
public function it_augments(string $displayTimezone, array $config, string $value, string $expected)
{
config()->set('statamic.system.display_timezone', $displayTimezone);

$augmented = $this->fieldtype($config)->augment($value);

$this->assertInstanceOf(Carbon::class, $augmented);
Expand All @@ -38,35 +40,52 @@ public static function augmentProvider()
{
return [
'date' => [
'UTC',
[],
'2012-01-04',
'2012 Jan 04 00:00:00',
],
'date with custom format' => [
'UTC',
['format' => 'Y--m--d'],
'2012--01--04',
'2012 Jan 04 00:00:00',
],
'date with display timezone' => [
'America/New_York',
[],
'2012-01-04',
'2012 Jan 04 00:00:00',
],

// The time and seconds configs are important, otherwise
// when when parsing dates without times, the time would inherit from "now".
// when parsing dates without times, the time would inherit from "now".
// We need to rely on the configs to know when or when not to reset the time.

'date with time' => [
'UTC',
['time_enabled' => true],
'2012-01-04 15:32',
'2012 Jan 04 15:32:00',
],
'date with time but seconds disabled' => [
'UTC',
['time_enabled' => true],
'2012-01-04 15:32:54',
'2012 Jan 04 15:32:00',
],
'date with time and seconds' => [
'UTC',
['time_enabled' => true, 'time_seconds_enabled' => true],
'2012-01-04 15:32:54',
'2012 Jan 04 15:32:54',
],
'date with time and display timezone' => [
'America/New_York',
['time_enabled' => true],
'2012-01-04 15:32',
'2012 Jan 04 10:32:00', // -5 hours
],
];
}

Expand All @@ -89,6 +108,21 @@ public function it_augments_a_carbon_instance()
$this->assertSame($instance, $augmented);
}

#[Test]
public function it_augments_a_carbon_instance_using_display_timezone_config()
{
// Could happen if you are using the date fieldtype to augment a manually provided value.

config()->set('statamic.system.display_timezone', 'America/New_York'); // -5 hours

$instance = new Carbon('2025-01-01 12:00:00');
$augmented = $this->fieldtype()->augment($instance);

$this->assertInstanceOf(Carbon::class, $augmented);
$this->assertEquals('America/New_York', $augmented->getTimezone()->getName());
$this->assertEquals(7, $instance->hour); // 12pm in UTC is 7am in New York
}

#[Test]
public function it_augments_a_range()
{
Expand Down

0 comments on commit a133e51

Please sign in to comment.