Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions src/helpers/format-date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,32 @@ export const formatNullableDateRange = (
return startEnd;
};

export const dateSameAcrossTimezones = (date: Date): boolean => {
const endDayUserTZ = dayjs(date);
const endDayUTC = dayjs(date).utc(true);
return endDayUserTZ.isSame(endDayUTC);
/**
* Formats a dayjs date in UTC timezone.
* This is needed because formatDate() uses toLocaleTimeString() which always
* formats in local timezone. This function formats directly in UTC using dayjs.
*
* Only shows the date if UTC falls on a different calendar day than local
* (e.g., "Today, 8pm PST Feb 6, 4am UTC"). If same day, just shows time
* (e.g., "Today, 10am PST 6pm UTC").
*/
export const formatDateAsUTC = (date: Dayjs): string => {
const utcDate = date.utc();
const localDate = date;

// Format time: "4pm" or "4:30pm"
const timeStr =
utcDate.minute() === 0 ? utcDate.format("ha") : utcDate.format("h:mma");

// Only show date if UTC and local fall on different calendar days
const sameCalendarDay =
utcDate.date() === localDate.date() &&
utcDate.month() === localDate.month() &&
utcDate.year() === localDate.year();

if (sameCalendarDay) {
return `${timeStr} UTC`;
}

return `${utcDate.format("MMM D")}, ${timeStr} UTC`;
};
14 changes: 3 additions & 11 deletions src/helpers/units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import type { Nullable } from "../types/empty.ts";
import { dateSameAcrossTimezones, formatDate } from "./format-date.ts";
import { formatDate, formatDateAsUTC } from "./format-date.ts";

dayjs.extend(utc);
dayjs.extend(timezone);
Expand Down Expand Up @@ -158,11 +158,7 @@ export async function selectTime(
const suggestedHigherUserTZ = `${formatDate(suggestedHigher.toDate(), {
forceIncludeTime: true,
})} ${dayjs(suggestedHigher).format("z")}`;
const suggestedHigherUTC = `${formatDate(suggestedHigher.utc(true).toDate(), {
today: suggestedHigher.toDate(),
showToday: dateSameAcrossTimezones(suggestedHigher.toDate()),
forceIncludeTime: true,
})} UTC`;
const suggestedHigherUTC = formatDateAsUTC(suggestedHigher);

// If the lower boundary is in the past, suggest "NOW"
if (suggestedLower.isBefore(dayjs(new Date()))) {
Expand Down Expand Up @@ -192,11 +188,7 @@ export async function selectTime(
const suggestedLowerUserTZ = `${formatDate(suggestedLower.toDate(), {
forceIncludeTime: true,
})} ${dayjs(suggestedLower).format("z")}`;
const suggestedLowerUTC = `${formatDate(suggestedLower.utc(true).toDate(), {
today: suggestedLower.toDate(),
showToday: dateSameAcrossTimezones(suggestedLower.toDate()),
forceIncludeTime: true,
})} UTC`;
const suggestedLowerUTC = formatDateAsUTC(suggestedLower);

const maxLength = Math.max(
suggestedLowerUserTZ.length,
Expand Down