mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 00:12:39 +00:00
Merge pull request #1262 from balabommablock-cpu/fix/relative-ago-calendar-days
fix: count calendar days in the time zone for the relative date
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { describe, it, expect, afterEach } from 'vitest';
|
||||
import { formatRelativeAgo } from '../utils';
|
||||
import { AUTO_TIME_ZONE } from '../timezone';
|
||||
import { useSettingsStore } from '@/stores/settings-store';
|
||||
|
||||
describe('formatRelativeAgo', () => {
|
||||
const now = new Date('2026-07-01T12:00:00Z');
|
||||
|
||||
afterEach(() => {
|
||||
useSettingsStore.setState({ timeZone: AUTO_TIME_ZONE });
|
||||
});
|
||||
|
||||
it('says how long ago in the largest whole unit', () => {
|
||||
expect(formatRelativeAgo(new Date('2026-07-01T11:57:00Z'), now)).toBe('3 minutes ago');
|
||||
expect(formatRelativeAgo(new Date('2026-07-01T08:00:00Z'), now)).toBe('4 hours ago');
|
||||
@@ -14,4 +20,16 @@ describe('formatRelativeAgo', () => {
|
||||
expect(formatRelativeAgo(new Date('2026-05-01T12:00:00Z'), now)).toBe('');
|
||||
expect(formatRelativeAgo('not a date', now)).toBe('');
|
||||
});
|
||||
|
||||
it('counts calendar days in the effective time zone (#1259)', () => {
|
||||
useSettingsStore.setState({ timeZone: 'America/Denver' });
|
||||
// 16 Oct, 10:00 in Denver.
|
||||
const denverNow = new Date('2026-10-16T16:00:00Z');
|
||||
// 14 Oct, 20:51 in Denver: only 37 hours ago, but two days back.
|
||||
expect(formatRelativeAgo(new Date('2026-10-15T02:51:30Z'), denverNow)).toBe('2 days ago');
|
||||
// 15 Oct, 08:00 in Denver: 26 hours ago, and yesterday.
|
||||
expect(formatRelativeAgo(new Date('2026-10-15T14:00:00Z'), denverNow)).toBe('yesterday');
|
||||
// Under a day still reads in hours, even across midnight.
|
||||
expect(formatRelativeAgo(new Date('2026-10-15T23:00:00Z'), denverNow)).toBe('17 hours ago');
|
||||
});
|
||||
});
|
||||
|
||||
+10
-1
@@ -258,6 +258,10 @@ export function formatDateTime(
|
||||
* How long ago `date` was, in words ("3 minutes ago", "2 days ago"), for the
|
||||
* parenthesis Gmail puts after a message's time. Empty once it is a month
|
||||
* old, where the date alone says enough.
|
||||
*
|
||||
* Days are calendar days in the user's effective time zone, so a mail from
|
||||
* the day before yesterday is never called "yesterday" just because fewer
|
||||
* than 48 hours have passed. (#1259)
|
||||
*/
|
||||
export function formatRelativeAgo(date: Date | string, now: Date = new Date()): string {
|
||||
const d = typeof date === 'string' ? new Date(date) : date;
|
||||
@@ -265,7 +269,12 @@ export function formatRelativeAgo(date: Date | string, now: Date = new Date()):
|
||||
const diff = Math.max(0, now.getTime() - d.getTime());
|
||||
const minutes = Math.floor(diff / 60000);
|
||||
const hours = Math.floor(diff / 3600000);
|
||||
const days = Math.floor(diff / 86400000);
|
||||
const timeZone = getEffectiveTimeZone();
|
||||
const dayNumber = (x: Date) => {
|
||||
const w = getWallClock(x, timeZone);
|
||||
return Date.UTC(w.year, w.month - 1, w.day) / 86400000;
|
||||
};
|
||||
const days = Math.max(1, dayNumber(now) - dayNumber(d));
|
||||
if (days >= 30) return '';
|
||||
const locale = getEffectiveLocale();
|
||||
const rtf = new Intl.RelativeTimeFormat(locale === 'en' ? 'en-US' : locale, { numeric: 'auto' });
|
||||
|
||||
Reference in New Issue
Block a user