Skip to content

Commit 68c97fb

Browse files
authored
Fix browser timezone information being lost (#5357)
fixes #5209
2 parents ff04a2e + 1b36336 commit 68c97fb

File tree

3 files changed

+35
-95
lines changed

3 files changed

+35
-95
lines changed

library/Icinga/Util/TimezoneDetect.php

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
namespace Icinga\Util;
55

6+
use DateTimeZone;
7+
68
/**
79
* Retrieve timezone information from cookie
810
*/
@@ -15,13 +17,6 @@ class TimezoneDetect
1517
*/
1618
private static $success;
1719

18-
/**
19-
* Timezone offset in minutes
20-
*
21-
* @var int
22-
*/
23-
private static $offset = 0;
24-
2520
/**
2621
* @var string
2722
*/
@@ -34,13 +29,6 @@ class TimezoneDetect
3429
*/
3530
public static $cookieName = 'icingaweb2-tzo';
3631

37-
/**
38-
* Timezone name
39-
*
40-
* @var string
41-
*/
42-
private static $timezone;
43-
4432
/**
4533
* Create new object and try to identify the timezone
4634
*/
@@ -50,31 +38,14 @@ public function __construct()
5038
return;
5139
}
5240

53-
if (array_key_exists(self::$cookieName, $_COOKIE)) {
54-
$matches = array();
55-
if (preg_match('/\A(-?\d+)[\-,](\d+)\z/', $_COOKIE[self::$cookieName], $matches)) {
56-
$offset = $matches[1];
57-
$timezoneName = timezone_name_from_abbr('', (int) $offset, (int) $matches[2]);
58-
59-
self::$success = (bool) $timezoneName;
60-
if (self::$success) {
61-
self::$offset = $offset;
62-
self::$timezoneName = $timezoneName;
63-
}
64-
}
41+
if (in_array($_COOKIE[self::$cookieName] ?? null, DateTimeZone::listIdentifiers(), true)) {
42+
self::$timezoneName = $_COOKIE[self::$cookieName];
43+
self::$success = true;
44+
} else {
45+
self::$success = false;
6546
}
6647
}
6748

68-
/**
69-
* Get offset
70-
*
71-
* @return int
72-
*/
73-
public function getOffset()
74-
{
75-
return self::$offset;
76-
}
77-
7849
/**
7950
* Get timezone name
8051
*
@@ -102,6 +73,5 @@ public function reset()
10273
{
10374
self::$success = null;
10475
self::$timezoneName = null;
105-
self::$offset = 0;
10676
}
10777
}

public/js/icinga/timezone.js

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,6 @@
44

55
'use strict';
66

7-
/**
8-
* Get the maximum timezone offset
9-
*
10-
* @returns {Number}
11-
*/
12-
Date.prototype.getStdTimezoneOffset = function() {
13-
var year = new Date().getFullYear();
14-
var offsetInJanuary = new Date(year, 0, 2).getTimezoneOffset();
15-
var offsetInJune = new Date(year, 5, 2).getTimezoneOffset();
16-
17-
return Math.max(offsetInJanuary, offsetInJune);
18-
};
19-
20-
/**
21-
* Test for daylight saving time zone
22-
*
23-
* @returns {boolean}
24-
*/
25-
Date.prototype.isDst = function() {
26-
return this.getStdTimezoneOffset() !== this.getTimezoneOffset();
27-
};
28-
297
/**
308
* Write timezone information into a cookie
319
*
@@ -51,33 +29,21 @@
5129
* Write timezone information into cookie
5230
*/
5331
writeTimezone: function() {
54-
var date = new Date();
55-
var timezoneOffset = (date.getTimezoneOffset()*60) * -1;
56-
var dst = date.isDst();
57-
5832
if (this.readCookie(this.cookieName)) {
5933
return;
6034
}
6135

62-
this.writeCookie(this.cookieName, timezoneOffset + '-' + Number(dst), 1);
36+
this.writeCookie(this.cookieName, Intl.DateTimeFormat().resolvedOptions().timeZone);
6337
},
6438

6539
/**
6640
* Write cookie data
6741
*
6842
* @param {String} name
6943
* @param {String} value
70-
* @param {Number} days
7144
*/
72-
writeCookie: function(name, value, days) {
73-
var expires = '';
74-
75-
if (days) {
76-
var date = new Date();
77-
date.setTime(date.getTime()+(days*24*60*60*1000));
78-
var expires = '; expires=' + date.toGMTString();
79-
}
80-
document.cookie = name + '=' + value + expires + '; path=/';
45+
writeCookie: function(name, value) {
46+
document.cookie = name + '=' + value + '; path=/';
8147
},
8248

8349
/**

test/php/library/Icinga/Util/TimezoneDetectTest.php

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,42 @@
88

99
class TimezoneDetectTest extends BaseTestCase
1010
{
11-
public function testPositiveTimezoneOffsetSeparatedByComma()
11+
public function testInvalidTimezoneNameInCookie(): void
1212
{
13-
$this->assertTimezoneDetection('3600,0', 'Europe/Paris');
14-
}
15-
16-
public function testPositiveTimezoneOffsetSeparatedByHyphen()
17-
{
18-
$this->assertTimezoneDetection('3600-0', 'Europe/Paris');
19-
}
20-
21-
public function testNegativeTimezoneOffsetSeparatedByComma()
22-
{
23-
$this->assertTimezoneDetection('-3600,0', 'Atlantic/Azores');
24-
}
13+
$tzDetect = new TimezoneDetect();
14+
$tzDetect->reset();
15+
16+
$_COOKIE[TimezoneDetect::$cookieName] = 'ABC';
17+
$tzDetect = new TimezoneDetect();
18+
$this->assertFalse(
19+
$tzDetect->success(),
20+
false,
21+
'Failed to assert invalid timezone name is detected'
22+
);
2523

26-
public function testNegativeTimezoneOffsetSeparatedByHyphen()
27-
{
28-
$this->assertTimezoneDetection('-3600-0', 'Atlantic/Azores');
24+
$this->assertNull(
25+
$tzDetect->getTimezoneName(),
26+
'Failed to assert that the timezone name will not be set for invalid timezone'
27+
);
2928
}
3029

31-
protected function assertTimezoneDetection($cookieValue, $expectedTimezoneName)
30+
public function testValidTimezoneNameInCookie(): void
3231
{
3332
$tzDetect = new TimezoneDetect();
3433
$tzDetect->reset();
3534

36-
$_COOKIE[TimezoneDetect::$cookieName] = $cookieValue;
35+
$_COOKIE[TimezoneDetect::$cookieName] = "Europe/Berlin";
3736
$tzDetect = new TimezoneDetect();
37+
$this->assertTrue(
38+
$tzDetect->success(),
39+
true,
40+
'Failed to assert that the valid timezone name is detected'
41+
);
42+
3843
$this->assertSame(
3944
$tzDetect->getTimezoneName(),
40-
$expectedTimezoneName,
41-
'Failed asserting that the timezone "' . $expectedTimezoneName
42-
. '" is being detected from the cookie value "' . $cookieValue . '"'
45+
"Europe/Berlin",
46+
'Failed to assert that the valid timezone name was correctly set'
4347
);
4448
}
4549
}

0 commit comments

Comments
 (0)