Skip to content

Commit

Permalink
Improve timezone handling CFM-394)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benn Oshrin committed Nov 30, 2024
1 parent c8bacf7 commit f86b04d
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 9 deletions.
13 changes: 11 additions & 2 deletions app/src/Controller/AppController.php
Original file line number Diff line number Diff line change
Expand Up @@ -657,13 +657,22 @@ protected function setTZ() {
// See if we've collected it from the browser in a previous page load. Otherwise,
// use the system default. If the user set a preferred timezone, we'll catch that below.

$tz = date_default_timezone_get();
$tz = new \DateTimeZone(date_default_timezone_get());

if(!empty($_COOKIE['cm_registry_tz_auto'])) {
// We have an auto-detected timezone from a previous page render from the browser.
// Note we don't call date_default_timezone_set() because we still want to record
// times internally in UTC (at the expense of having to convert back and forth).
$tz = $_COOKIE['cm_registry_tz_auto'];

try {
// If the cookie value is invalid, this will throw an Exception, and we'll eventually
// reset the browser cookie based on the detected timezone (for the next page load)
$tz = new \DateTimeZone($_COOKIE['cm_registry_tz_auto']);
}
catch(\Exception $e) {
// We'll fall back to the default timezone, and we'll reset the cookie when the
// default layout renders (so no need to do anything here)
}
}

// XXX need to implement person-specific timezone detection (after CoPerson model and
Expand Down
2 changes: 1 addition & 1 deletion app/src/Lib/Util/StringUtilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static function columnKey($modelsName, $c, $tz=null, $useCustomClMdlLabel

if($tz) {
// If there is a timezone aware label, use that
$label = __d('field', $c.'.tz', [$tz]);
$label = __d('field', $c.'.tz', [$tz->getName()]);

if($label != $c.'.tz') {
return $label;
Expand Down
10 changes: 4 additions & 6 deletions app/src/Model/Behavior/TimezoneBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,14 @@ class TimezoneBehavior extends Behavior
*/

public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) {
if($this->tz && $this->tz != 'UTC') {
if($this->tz && $this->tz->getName() != 'UTC') {
// There's some Cake support for doing timezone conversion, but it's not really
// well documented, so we use PHP calls directly.

$localTZ = new \DateTimeZone($this->tz);

foreach($this->fields as $f) {
if(!empty($data[$f])) {
// This returns a DateTime object adjusting for localTZ
$offsetDT = new \DateTime($data[$f], $localTZ);
$offsetDT = new \DateTime($data[$f], $this->tz);

// strftime converts a timestamp according to server localtime (which should be UTC)
$data[$f] = strftime("%F %T", $offsetDT->getTimestamp());
Expand All @@ -78,10 +76,10 @@ public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $opti
* Set the current timezone.
*
* @since COmanage Registry v5.0.0
* @param string $tz Timezone, eg as determined by AppController::beforeFilter
* @param DateTimeZone $tz Timezone, eg as determined by AppController::beforeFilter
*/

public function setTimeZone(string $tz) {
public function setTimeZone(\DateTimeZone $tz) {
$this->tz = $tz;
}
}

0 comments on commit f86b04d

Please sign in to comment.