diff --git a/packages/frontend-misskey-world-engine/src/envs/lobby.ts b/packages/frontend-misskey-world-engine/src/envs/lobby.ts index 724ea74e52..62ae5ab4e7 100644 --- a/packages/frontend-misskey-world-engine/src/envs/lobby.ts +++ b/packages/frontend-misskey-world-engine/src/envs/lobby.ts @@ -11,6 +11,7 @@ import { findMaterial, GRAPHICS_QUALITY, Timer } from '../utility.js'; import { WorldEnvManager } from '../env.js'; import { RecyvlingTextGrid, createPlaneUvMapper, randomRange } from '../utility.js'; import { Firework } from '../Firework.js'; +import { getTimezoneOffsetLabel, timezones } from '../timezones.js'; import type { WorldEngine } from '../engine.js'; export class LobbyEnvManager extends WorldEnvManager { @@ -25,6 +26,7 @@ export class LobbyEnvManager extends WorldEnvManager { private textBwMaterial: BABYLON.StandardMaterial | null = null; private translucentTextMaterial: BABYLON.StandardMaterial | null = null; private timer: Timer = new Timer(); + private tz = timezones.find((tz) => tz.abbrev === 'JST')!; constructor(engine: WorldEngine) { super(engine); @@ -228,11 +230,11 @@ export class LobbyEnvManager extends WorldEnvManager { }); this.timer.setInterval(() => { - const now = new Date(); + const now = this.getCurrentTime(); const hours = now.getHours().toString().padStart(2, '0'); const minutes = now.getMinutes().toString().padStart(2, '0'); const seconds = now.getSeconds().toString().padStart(2, '0'); - text.write(`${hours}:${minutes}:${seconds}`); + text.write(`${hours}:${minutes}:${seconds} ${getTimezoneOffsetLabel(this.tz.offset)}`); }, 1000); } @@ -262,11 +264,13 @@ export class LobbyEnvManager extends WorldEnvManager { }); this.timer.setInterval(() => { - const now = new Date(); + const now = this.getCurrentTime(); const years = now.getFullYear().toString(); const months = (now.getMonth() + 1).toString().padStart(2, '0'); const days = now.getDate().toString().padStart(2, '0'); - text.write(`${years}/${months}/${days}`); + const dayOfWeek = now.getDay(); + const dayOfWeekStr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][dayOfWeek]; + text.write(`${this.tz.abbrev} ${years}/${months}/${days} ${dayOfWeekStr.toUpperCase()}`); }, 1000); } @@ -436,7 +440,7 @@ export class LobbyEnvManager extends WorldEnvManager { const minuteHands = this.meshes.filter(m => m.name.includes('__CLOCK_HAND_M__')); this.timer.setInterval(() => { - const now = new Date(); + const now = this.getCurrentTime(); const hours = now.getHours() % 12; const minutes = now.getMinutes(); const hAngle = -(hours / 12) * Math.PI * 2 - (minutes / 60) * (Math.PI * 2 / 12); @@ -500,6 +504,12 @@ export class LobbyEnvManager extends WorldEnvManager { } } + private getCurrentTime() { + const now = new Date(); + now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + this.tz.offset); + return now; + } + public dispose() { this.timer.dispose(); for (const m of this.meshes) { diff --git a/packages/frontend-misskey-world-engine/src/timezones.ts b/packages/frontend-misskey-world-engine/src/timezones.ts new file mode 100644 index 0000000000..06113af1c6 --- /dev/null +++ b/packages/frontend-misskey-world-engine/src/timezones.ts @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export const timezones = [{ + name: 'UTC', + abbrev: 'UTC', + offset: 0, +}, { + name: 'Europe/Berlin', + abbrev: 'CET', + offset: 60, +}, { + name: 'Asia/Tokyo', + abbrev: 'JST', + offset: 540, +}, { + name: 'Asia/Seoul', + abbrev: 'KST', + offset: 540, +}, { + name: 'Asia/Shanghai', + abbrev: 'CST', + offset: 480, +}, { + name: 'Australia/Sydney', + abbrev: 'AEST', + offset: 600, +}, { + name: 'Australia/Darwin', + abbrev: 'ACST', + offset: 570, +}, { + name: 'Australia/Perth', + abbrev: 'AWST', + offset: 480, +}, { + name: 'America/New_York', + abbrev: 'EST', + offset: -300, +}, { + name: 'America/Mexico_City', + abbrev: 'CST', + offset: -360, +}, { + name: 'America/Phoenix', + abbrev: 'MST', + offset: -420, +}, { + name: 'America/Los_Angeles', + abbrev: 'PST', + offset: -480, +}]; + +export function getTimezoneAbbrev(timezone: string | null): string { + if (timezone === null) { + return timezones.find((tz) => tz.name.toLowerCase() === Intl.DateTimeFormat().resolvedOptions().timeZone.toLowerCase())?.abbrev ?? '?'; + } else { + return timezones.find((tz) => tz.name.toLowerCase() === timezone.toLowerCase())?.abbrev ?? '?'; + } +} + +export function getTimezoneOffset(timezone: string | null): number { + if (timezone === null) { + return 0 - new Date().getTimezoneOffset(); + } else { + return timezones.find((tz) => tz.name.toLowerCase() === timezone.toLowerCase())?.offset ?? 0; + } +} + +export function getTimezoneOffsetLabel(tzOffset: number): string { + return (tzOffset >= 0 ? '+' : '-') + Math.floor(tzOffset / 60).toString().padStart(2, '0') + ':' + (tzOffset % 60).toString().padStart(2, '0'); +} diff --git a/packages/frontend/assets/world/envs/lobby/lobby.blend b/packages/frontend/assets/world/envs/lobby/lobby.blend index ae21726b77..201f8ca6f4 100644 Binary files a/packages/frontend/assets/world/envs/lobby/lobby.blend and b/packages/frontend/assets/world/envs/lobby/lobby.blend differ diff --git a/packages/frontend/assets/world/envs/lobby/lobby.glb b/packages/frontend/assets/world/envs/lobby/lobby.glb index ea9d3e3bcd..6c32d4557e 100644 Binary files a/packages/frontend/assets/world/envs/lobby/lobby.glb and b/packages/frontend/assets/world/envs/lobby/lobby.glb differ