mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 13:33:24 +00:00
bug fix: Check offsets when browser doesn't canonicalize.
This is more of a workaround than a bug fix. Some JS implementations are less "aggressive" about canonicalizing things like America/Montreal to America/Toronto. We instead use offset checks.
This commit is contained in:
@@ -555,18 +555,44 @@ export function should_display_profile_incomplete_alert(timestamp: number): bool
|
||||
return false;
|
||||
}
|
||||
|
||||
export function browser_canonicalize_timezone(uncanonicalized_timezone: string): string {
|
||||
export function get_time_in_timezone(date: Date, timezone: string): number {
|
||||
return Date.parse(date.toLocaleString("en-US", {timeZone: timezone}));
|
||||
}
|
||||
|
||||
export function get_offset_difference_at_date(
|
||||
timezone1: string,
|
||||
timezone2: string,
|
||||
reference_date: Date,
|
||||
): number {
|
||||
const date1 = get_time_in_timezone(reference_date, timezone1);
|
||||
const date2 = get_time_in_timezone(reference_date, timezone2);
|
||||
return date1 - date2;
|
||||
}
|
||||
|
||||
export function are_timezones_on_same_clock_now(timezone1: string, timezone2: string): boolean {
|
||||
// America/Los_Angeles is clearly the same as America/Los_Angeles:
|
||||
if (timezone1 === timezone2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We still want this function to return true if the timezones are
|
||||
// on the same clock for now, even though they may eventually diverge
|
||||
// during Daylight Savings. This avoids nagging the user. The only
|
||||
// tradeoff is if the user stays logged on while the clocks change,
|
||||
// but that should be rare.
|
||||
const now = new Date();
|
||||
|
||||
try {
|
||||
// we use the runtime's default locale, to match _browser_time_zone_.
|
||||
const canonicalized_timezone = new Intl.DateTimeFormat(undefined, {
|
||||
timeZone: uncanonicalized_timezone,
|
||||
}).resolvedOptions().timeZone;
|
||||
return canonicalized_timezone;
|
||||
return get_offset_difference_at_date(timezone1, timezone2, now) === 0;
|
||||
} catch {
|
||||
return "";
|
||||
// This should only happen during testing, but we just catch any error
|
||||
// related to invalid time zones.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function is_browser_timezone_same_as(uncanonicalized_target_timezone: string): boolean {
|
||||
return browser_time_zone() === browser_canonicalize_timezone(uncanonicalized_target_timezone);
|
||||
export function is_browser_timezone_same_as(zulip_time_zone: string): boolean {
|
||||
// We delegate most of this check to facilitate testing.
|
||||
// We don't want to mock browser_time_zone.
|
||||
return are_timezones_on_same_clock_now(browser_time_zone(), zulip_time_zone);
|
||||
}
|
||||
|
||||
@@ -654,6 +654,40 @@ run_test("should_display_profile_incomplete_alert", () => {
|
||||
assert.equal(timerender.should_display_profile_incomplete_alert(realm_date_created_secs), true);
|
||||
});
|
||||
|
||||
run_test("are_timezones_on_same_clock_now", () => {
|
||||
assert.ok(
|
||||
timerender.are_timezones_on_same_clock_now("America/Los_Angeles", "America/Los_Angeles"),
|
||||
);
|
||||
assert.ok(timerender.are_timezones_on_same_clock_now("America/New_York", "America/New_York"));
|
||||
|
||||
// Montreal and Toronto are equivalent year-round.
|
||||
assert.ok(timerender.are_timezones_on_same_clock_now("America/Montreal", "America/Toronto"));
|
||||
|
||||
assert.ok(
|
||||
!timerender.are_timezones_on_same_clock_now("Invalid/Timezone", "America/Los_Angeles"),
|
||||
);
|
||||
assert.ok(
|
||||
!timerender.are_timezones_on_same_clock_now("America/New_York", "America/Los_Angeles"),
|
||||
);
|
||||
});
|
||||
|
||||
run_test("are_timezones_on_same_clock_now (Phoenix)", () => {
|
||||
/*
|
||||
If you live in Phoenix and make the short flight to Los Angeles during
|
||||
Daylight Savings time, you don't need to reset your watch.
|
||||
|
||||
Likewise, during the winter, if you go to Denver, you don't need to
|
||||
reset your watch.
|
||||
|
||||
We err on the side of not nagging Phoenix folks to change their
|
||||
"Zulip clock" for these short trips.
|
||||
*/
|
||||
assert.ok(
|
||||
timerender.are_timezones_on_same_clock_now("America/Phoenix", "America/Los_Angeles") ||
|
||||
timerender.are_timezones_on_same_clock_now("America/Phoenix", "America/Denver"),
|
||||
);
|
||||
});
|
||||
|
||||
run_test("is_browser_timezone_same_as", () => {
|
||||
assert.equal(timerender.is_browser_timezone_same_as(timerender.browser_time_zone()), true);
|
||||
|
||||
@@ -661,19 +695,13 @@ run_test("is_browser_timezone_same_as", () => {
|
||||
assert.equal(timerender.is_browser_timezone_same_as("Invalid/Timezone"), false);
|
||||
});
|
||||
|
||||
run_test("test time zone math", () => {
|
||||
// This test doesn't seem to test any Zulip code, but it seems
|
||||
// useful to keep around anyway, since the offset logic
|
||||
// here is useful to understand.
|
||||
|
||||
run_test("time zone helpers", () => {
|
||||
function get_time_in_timezone(date, timezone) {
|
||||
return Date.parse(date.toLocaleString("en-US", {timeZone: timezone}));
|
||||
return timerender.get_time_in_timezone(date, timezone);
|
||||
}
|
||||
|
||||
function get_offset_difference_at_date(tz1, tz2, reference_date) {
|
||||
const date1 = get_time_in_timezone(reference_date, tz1);
|
||||
const date2 = get_time_in_timezone(reference_date, tz2);
|
||||
return date1 - date2;
|
||||
return timerender.get_offset_difference_at_date(tz1, tz2, reference_date);
|
||||
}
|
||||
|
||||
// The current time in America/Phoenix does equal the current time
|
||||
|
||||
Reference in New Issue
Block a user