fix: refresh same-day OHLCV bars
This commit is contained in:
@@ -64,10 +64,43 @@ function timeAgo(iso: string): string {
|
||||
return `${days}d ago`;
|
||||
}
|
||||
|
||||
function marketDate(date = new Date()): string {
|
||||
const parts = new Intl.DateTimeFormat('en-US', {
|
||||
timeZone: 'America/New_York',
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).formatToParts(date);
|
||||
const value = (type: Intl.DateTimeFormatPartTypes) =>
|
||||
parts.find((part) => part.type === type)?.value ?? '';
|
||||
return value('year') + '-' + value('month') + '-' + value('day');
|
||||
}
|
||||
|
||||
function formatSessionDate(isoDate: string): string {
|
||||
if (isoDate === marketDate()) return 'Today';
|
||||
|
||||
// Parse date-only market sessions explicitly. Parsing YYYY-MM-DD directly as
|
||||
// a Date means midnight UTC and makes today's bar look many hours old.
|
||||
const [year, month, day] = isoDate.split('-').map(Number);
|
||||
if (!year || !month || !day) return isoDate;
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: year === new Date().getFullYear() ? undefined : 'numeric',
|
||||
timeZone: 'UTC',
|
||||
}).format(new Date(Date.UTC(year, month - 1, day)));
|
||||
}
|
||||
|
||||
function formatOHLCVFreshness(sessionDate: string, updatedAt?: string | null): string {
|
||||
const session = formatSessionDate(sessionDate);
|
||||
return updatedAt ? session + ' · updated ' + timeAgo(updatedAt) : session;
|
||||
}
|
||||
|
||||
interface DataStatusItem {
|
||||
label: string;
|
||||
available: boolean;
|
||||
timestamp?: string | null;
|
||||
timestampLabel?: string | null;
|
||||
selector: FetchSelector; // what a refresh of this row fetches
|
||||
paid?: boolean; // provider call that may cost money/quota
|
||||
}
|
||||
@@ -100,7 +133,7 @@ function DataFreshnessBar({
|
||||
}`} />
|
||||
<span className="text-xs text-gray-400">{item.label}</span>
|
||||
{item.available && item.timestamp ? (
|
||||
<span className="text-[10px] text-gray-500">{timeAgo(item.timestamp)}</span>
|
||||
<span className="text-[10px] text-gray-500">{item.timestampLabel ?? timeAgo(item.timestamp)}</span>
|
||||
) : !item.available ? (
|
||||
<span className="text-[10px] text-gray-600">no data</span>
|
||||
) : null}
|
||||
@@ -171,10 +204,16 @@ export default function TickerDetailPage() {
|
||||
const dataStatus: DataStatusItem[] = useMemo(() => [
|
||||
{
|
||||
label: 'OHLCV',
|
||||
// Market age of the latest bar (session date), not DB insert time —
|
||||
// created_at stays frozen when the provider returns no new sessions.
|
||||
// Keep the market session date distinct from the last successful bar
|
||||
// write; treating YYYY-MM-DD as an instant makes today's session look old.
|
||||
available: !!ohlcv.data && ohlcv.data.length > 0,
|
||||
timestamp: ohlcv.data?.[ohlcv.data.length - 1]?.date,
|
||||
timestampLabel: ohlcv.data?.length
|
||||
? formatOHLCVFreshness(
|
||||
ohlcv.data[ohlcv.data.length - 1].date,
|
||||
ohlcv.data[ohlcv.data.length - 1].created_at,
|
||||
)
|
||||
: null,
|
||||
selector: ['ohlcv'] as FetchSelector,
|
||||
paid: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user