- apis/chat 모듈(api/queries/mutations/keys/type) + useChatController(append-only send 주입) - useChatStore 재배선, list→chat session_id 라우팅 연결, mock 제거 - 마감/종료/권한 시 입력 잠금·목록 복귀, 가격범위 인라인 에러, CHAT_IN_PROGRESS 처리 - list 마감일 KST(Asia/Seoul) 고정 표시(lib/datetime formatKstDateTime) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
30 lines
1.3 KiB
TypeScript
30 lines
1.3 KiB
TypeScript
// 시각 표시 유틸. 백엔드는 모든 시각을 UTC(+00:00 오프셋 포함 ISO)로 직렬화하므로,
|
|
// 절대 시각 파싱은 브라우저 타임존과 무관하게 정확하다. 다만 "표시"는 항상 KST(Asia/Seoul)로
|
|
// 고정해야 한국 외 타임존 브라우저에서도 동일한 마감 시각을 보여줄 수 있다.
|
|
export const KST_TIME_ZONE = 'Asia/Seoul'
|
|
|
|
// hourCycle:'h23' → 자정을 24 가 아닌 00 으로(엔진별 '24:00' 방지). locale 무관 고정 포맷.
|
|
const kstFormat = new Intl.DateTimeFormat('en-CA', {
|
|
timeZone: KST_TIME_ZONE,
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
hourCycle: 'h23',
|
|
})
|
|
|
|
function toKstParts(value: string | Date): Record<string, string> | null {
|
|
const d = value instanceof Date ? value : new Date(value)
|
|
if (Number.isNaN(d.getTime())) return null
|
|
return Object.fromEntries(kstFormat.formatToParts(d).map((p) => [p.type, p.value]))
|
|
}
|
|
|
|
/** 'YYYY-MM-DD HH:mm' (KST). 빈 값 '-', 파싱 실패 시 원본 문자열. */
|
|
export function formatKstDateTime(value: string | Date): string {
|
|
if (!value) return '-'
|
|
const p = toKstParts(value)
|
|
if (!p) return typeof value === 'string' ? value : '-'
|
|
return `${p.year}-${p.month}-${p.day} ${p.hour}:${p.minute}`
|
|
}
|