JavaScript 달력의 날짜와 시각 분리 — Codex 도구 개발 기록
안녕하세요. 무료 독립 프로젝트 Codex Reset Calendar를 유지관리하는 kiki입니다. Codex의 도움을 받아 개발하고 문안을 다듬는 과정에서 정리한 날짜·시각 처리 경험을 공유합니다. OpenAI와 무관한 비공식 프로젝트이며, 이 글은 특정 강의를 수강한 후기가 아닙니다.
1. “달력의 날짜”와 “어떤 순간”은 다른 자료형처럼 다루기
같은 날짜 문자열이라도 역할을 먼저 정해야 했습니다. 달력의 칸 이름인 2026-10-20과, 실제 사건이 발생한 시각인 2026-10-20T00:30:00Z는 의미가 다릅니다. 전자는 날짜 자체를 유지해야 하고, 후자는 읽는 사람의 시간대에 따라 날짜까지 달라질 수 있습니다.
현재 구현에서는 달력 날짜를 표시하는 함수와 실제 시각을 표시하는 함수를 나눴습니다. 날짜 표시는 YYYY-MM-DD에 UTC 자정을 붙이고 UTC 기준으로 서식을 적용합니다. 실제 사건 시각은 브라우저의 시간대를 명시해 표시합니다. 언어 선택은 별도이며, 한국어를 선택했다고 시간대를 Asia/Seoul로 고정하지 않습니다.
핵심을 줄인 JavaScript 예시입니다. 아래는 설명용 코드이며 전체 앱 소스는 아닙니다.
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
const dateLabel = new Intl.DateTimeFormat("ko-KR", { timeZone: "UTC", dateStyle: "medium" }).format(new Date("2026-10-20T00:00:00Z"));
const instantLabel = new Intl.DateTimeFormat("ko-KR", { timeZone: zone, dateStyle: "medium", timeStyle: "short" }).format(new Date("2026-10-20T00:30:00Z"));
dateLabel은 달력의 날짜를 보존하고, instantLabel은 같은 순간을 이용자의 시간대로 표현합니다. 이 구분 없이 모든 값을 같은 Date 포맷터에 넣으면, 시간대에 따라 전날로 보이는 현상을 의도한 것인지 오류인지 판단하기 어려워집니다.
2. 시간 계산이 맞아도 데이터 의미가 틀리면 오해가 생깁니다
이 프로젝트에서는 공개된 전체 리셋 기록과 개인 사용량 타이머도 분리했습니다. 공개 기록은 Tibo의 X 원문과 연결하고, 개인 타이머는 사용자가 입력한 시간으로만 계산합니다. 사이트가 OpenAI 계정의 잔여량이나 실제 개인 리셋 시각을 읽는 것은 아닙니다.
따라서 두 기능을 같은 화면에서 보여주더라도 “확인된 공개 사건”, “아직 유효한 예고”, “사용자가 입력한 개인 타이머”라는 서로 다른 상태임을 문구로 구분해야 했습니다. 시간대 변환만 검증해서는 이 의미 차이를 검증할 수 없습니다.
3. 추정치는 시각 정보보다 먼저 출처와 한계를 표시하기
유효한 예고가 없을 때의 향후 24/48/72시간 확률은 최근 최대 90일의 확인된 기록에서 계산한 역사적 추정입니다. AI가 미래를 예측한 값도, 공식 일정도 아닙니다. 표본과 방법을 함께 표시하고 표본이 부족하면 이유를 안내합니다. 개인 계정의 리셋을 보장하지 않습니다.
개발하면서는 숫자 계산뿐 아니라 “이 숫자를 사용자가 무엇으로 받아들이는가”도 확인해야 한다고 정리했습니다. 과거 기록에서 계산한 확률에 확정 일정과 같은 표현을 붙이지 않는 것이 그 예입니다.
4. 동기화 실패는 마지막 정상 데이터와 함께 설명하기
마지막 정상 스냅샷을 보존하면 일시적 실패 때도 화면을 제공할 수 있습니다. 다만 보존된 값이라는 사실과 오래된 상태임을 표시해야 합니다. 화면이 비어 있지 않다는 것과 최신 데이터라는 것은 별개의 조건이기 때문입니다.
검토할 때는 날짜 전용 값이 다른 시간대에서도 같은 날짜로 보이는지, 실제 시각은 브라우저 시간대로 표시되는지, 언어 변경이 시간대를 덮어쓰지 않는지, 오래된 스냅샷이 최신 상태처럼 보이지 않는지를 각각 나눠 확인하는 편이 명확했습니다.
관련 구현은 JavaScript와 Cloudflare Workers/KV를 사용합니다. 제가 유지관리하는 실제 적용 사례는 https://codex-resets-tracker.com/ko/ 에서 설치나 가입 없이 볼 수 있습니다.
비슷한 달력이나 카운트다운을 만드신 분들은 날짜 전용 값과 실제 시각을 데이터 모델에서 어떻게 구분하시는지 궁금합니다.
답변 0





