From 8a875b119f45b1af69f360be61a3315dc9ca9588 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Fri, 17 Nov 2023 18:50:33 -0800 Subject: [PATCH] people: Remove final use of date-fns-tz. date-fns-tz does not handle daylight saving time correctly, and can be replaced with modern browser APIs. Signed-off-by: Anders Kaseorg --- package.json | 1 - pnpm-lock.yaml | 11 ----------- version.py | 2 +- web/src/people.ts | 29 ++++++++++------------------- web/src/settings_data.ts | 18 ------------------ web/src/timerender.ts | 2 +- web/tests/people.test.js | 20 +++----------------- 7 files changed, 15 insertions(+), 68 deletions(-) diff --git a/package.json b/package.json index 96b9d1bcb2..423608cd11 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "css-loader": "^6.2.0", "css-minimizer-webpack-plugin": "^5.0.0", "date-fns": "^2.16.1", - "date-fns-tz": "^2.0.0", "email-addresses": "^5.0.0", "emoji-datasource-google": "^15.0.1", "emoji-datasource-google-blob": "npm:emoji-datasource-google@^3.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1558d4e072..66f79814fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,9 +97,6 @@ dependencies: date-fns: specifier: ^2.16.1 version: 2.30.0 - date-fns-tz: - specifier: ^2.0.0 - version: 2.0.0(date-fns@2.30.0) email-addresses: specifier: ^5.0.0 version: 5.0.0 @@ -5082,14 +5079,6 @@ packages: whatwg-url: 12.0.1 dev: true - /date-fns-tz@2.0.0(date-fns@2.30.0): - resolution: {integrity: sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==} - peerDependencies: - date-fns: '>=2.0.0' - dependencies: - date-fns: 2.30.0 - dev: false - /date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} diff --git a/version.py b/version.py index 2b0148d9e4..2224024eec 100644 --- a/version.py +++ b/version.py @@ -48,4 +48,4 @@ API_FEATURE_LEVEL = 227 # historical commits sharing the same major version, in which case a # minor version bump suffices. -PROVISION_VERSION = (253, 1) +PROVISION_VERSION = (254, 0) diff --git a/web/src/people.ts b/web/src/people.ts index db6570f112..d353dff530 100644 --- a/web/src/people.ts +++ b/web/src/people.ts @@ -1,5 +1,4 @@ import md5 from "blueimp-md5"; -import {format, utcToZonedTime} from "date-fns-tz"; import assert from "minimalistic-assert"; import * as typeahead from "../shared/src/typeahead"; @@ -12,8 +11,9 @@ import * as muted_users from "./muted_users"; import {page_params} from "./page_params"; import * as reload_state from "./reload_state"; import * as settings_config from "./settings_config"; -import * as settings_data from "./settings_data"; +import * as timerender from "./timerender"; import type {DisplayRecipientUser, Message, MessageWithBooleans} from "./types"; +import {user_settings} from "./user_settings"; import * as util from "./util"; export type ProfileData = { @@ -364,26 +364,17 @@ export function emails_to_full_names_string(emails: string[]): string { .join(", "); } -export function get_user_time_preferences( - user_id: number, -): settings_data.TimePreferences | undefined { +export function get_user_time(user_id: number): string | undefined { const user_timezone = get_by_user_id(user_id)!.timezone; if (user_timezone) { - return settings_data.get_time_preferences(user_timezone); - } - return undefined; -} - -export function get_user_time(user_id: number): string | undefined { - const user_pref = get_user_time_preferences(user_id); - if (user_pref) { - const current_date = utcToZonedTime(new Date(), user_pref.timezone); - // This could happen if the timezone is invalid. - if (Number.isNaN(current_date.getTime())) { - blueslip.error("Got invalid date for timezone", {timezone: user_pref.timezone}); - return undefined; + try { + return new Date().toLocaleTimeString(user_settings.default_language, { + ...timerender.get_format_options_for_type("time"), + timeZone: user_timezone, + }); + } catch (error) { + blueslip.error(`Error formatting time in ${user_timezone}`, undefined, error); } - return format(current_date, user_pref.format, {timeZone: user_pref.timezone}); } return undefined; } diff --git a/web/src/settings_data.ts b/web/src/settings_data.ts index 9084ea5602..33a9cc4efd 100644 --- a/web/src/settings_data.ts +++ b/web/src/settings_data.ts @@ -19,24 +19,6 @@ export function initialize(current_user_join_date: Date): void { about page_params and settings_config details. */ -export type TimePreferences = { - timezone: string; - format: string; -}; - -export function get_time_preferences(user_timezone: string): TimePreferences { - if (user_settings.twenty_four_hour_time) { - return { - timezone: user_timezone, - format: "H:mm", - }; - } - return { - timezone: user_timezone, - format: "h:mm a", - }; -} - export function user_can_change_name(): boolean { if (page_params.is_admin) { return true; diff --git a/web/src/timerender.ts b/web/src/timerender.ts index 6faeb69dbb..7ec5a9a526 100644 --- a/web/src/timerender.ts +++ b/web/src/timerender.ts @@ -43,7 +43,7 @@ type DateOrTimeFormat = DateFormat | TimeFormat | DateWithTimeFormat; // for any formats that display the name for a month/weekday, but // possibly in more subtle ways for languages with different // punctuation schemes for date and times. -function get_format_options_for_type(type: DateOrTimeFormat): Intl.DateTimeFormatOptions { +export function get_format_options_for_type(type: DateOrTimeFormat): Intl.DateTimeFormatOptions { const is_twenty_four_hour_time = user_settings.twenty_four_hour_time; const time_format_options: Intl.DateTimeFormatOptions = is_twenty_four_hour_time diff --git a/web/tests/people.test.js b/web/tests/people.test.js index 333bbbeae8..67fc3d56d4 100644 --- a/web/tests/people.test.js +++ b/web/tests/people.test.js @@ -586,25 +586,11 @@ test_people("bot_custom_profile_data", () => { test_people("user_timezone", () => { MockDate.set(parseISO("20130208T080910").getTime()); - const expected_pref = { - timezone: "America/Los_Angeles", - format: "H:mm", - }; - user_settings.twenty_four_hour_time = true; - assert.deepEqual(people.get_user_time_preferences(me.user_id), expected_pref); - - expected_pref.format = "h:mm a"; - user_settings.twenty_four_hour_time = false; - assert.deepEqual(people.get_user_time_preferences(me.user_id), expected_pref); - - user_settings.twenty_four_hour_time = true; - assert.equal(people.get_user_time(me.user_id), "0:09"); + assert.equal(people.get_user_time(me.user_id), "00:09"); user_settings.twenty_four_hour_time = false; assert.equal(people.get_user_time(me.user_id), "12:09 AM"); - - assert.deepEqual(people.get_user_time_preferences(unknown_user.user_id), undefined); }); test_people("utcToZonedTime", ({override}) => { @@ -612,10 +598,10 @@ test_people("utcToZonedTime", ({override}) => { user_settings.twenty_four_hour_time = true; assert.deepEqual(people.get_user_time(unknown_user.user_id), undefined); - assert.equal(people.get_user_time(me.user_id), "0:09"); + assert.equal(people.get_user_time(me.user_id), "00:09"); override(people.get_by_user_id(me.user_id), "timezone", "Eriador/Rivendell"); - blueslip.expect("error", "Got invalid date for timezone"); + blueslip.expect("error", "Error formatting time in Eriador/Rivendell"); people.get_user_time(me.user_id); });