Files
scoreodonto.com/frontend/utils/appTime.ts
T
VPS 4 Builder 8ea8faa4c2 wip: inbox/agenda diversos (trabalho anterior à sessão)
Consolida WIP acumulado que não faz parte das features de hoje: melhorias do
inbox (WhatsChatDrawer, InputBar, MessageBubble, ProtocolPanel, StickerPanel,
LinkPreview, hooks, socketService, chatStore, nwClient), componentes novos
(ConversationSearch, ForwardModal, LabelManagerModal, roleMeta), AgendaPresence,
ComunicacaoInternaModal, Sidebar, GestaoEquipeView, SessionsView, appTime e o
asset chat-bg.png.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 06:08:07 +02:00

30 lines
2.0 KiB
TypeScript

// Fuso de REFERÊNCIA do armazenamento. As colunas de horário (agendamentos.start_time)
// são `timestamp` naive; o backend (container) roda em America/Sao_Paulo, então o node-pg
// serializa o wall-clock naive nesse fuso. Para exibir o horário LITERAL (o mesmo que a
// Secretária ofereceu/gravou) em qualquer navegador, formatamos SEMPRE neste fuso — e não
// no fuso local do navegador (que causaria o deslocamento de ±1h).
export const STORAGE_TZ = 'America/Sao_Paulo';
const D = (v?: string | number | Date | null) => (v === null || v === undefined || v === '' ? null : new Date(v));
export const fmtHora = (v?: string | number | Date | null): string => {
const d = D(v); return d ? d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit', timeZone: STORAGE_TZ }) : '—';
};
export const fmtDataCurta = (v?: string | number | Date | null): string => {
const d = D(v); return d ? d.toLocaleDateString('pt-BR', { weekday: 'short', day: 'numeric', month: 'short', timeZone: STORAGE_TZ }) : '—';
};
export const fmtDataHora = (v?: string | number | Date | null): string => {
const d = D(v); return d ? d.toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: STORAGE_TZ }) : '—';
};
// Converte um instante (ISO/Date) para o WALL-CLOCK naive no fuso canônico, no formato
// "YYYY-MM-DDTHH:mm:ss" (SEM offset). Uso: alimentar o FullCalendar, que — sem o plugin
// de timezone (luxon) — IGNORA o prop `timeZone` nomeado e cai no fuso do NAVEGADOR.
// Passando a string naive, o calendário exibe o horário literal em qualquer navegador
// (mesma garantia do fmtHora, mas para os eventos do grid). Retorna undefined se vazio.
export const toCalendarNaive = (v?: string | number | Date | null): string | undefined => {
const d = D(v); if (!d) return undefined;
// 'sv-SE' produz "YYYY-MM-DD HH:mm:ss" (ISO-like); trocamos o espaço por 'T'.
return d.toLocaleString('sv-SE', { timeZone: STORAGE_TZ, hour12: false }).replace(' ', 'T');
};