← 전체 글로 돌아가기

웹 개발

블로그 글 목록이 KST 기준으로 하루씩 밀려 보이던 시간대 문제

UTC 저장값과 KST 표시를 섞지 않고 정렬은 타임스탐프로, 화면은 별도 함수로 통일하면서 혼란이 줄었다.

증상

밤늦게 글을 발행하면 관리자 목록에서는 오늘 글인데 공개 목록에서는 어제 글처럼 보였다. 정렬 자체가 완전히 틀린 건 아니었지만, 날짜 표시가 하루씩 밀려 보여서 최근 글을 확인할 때 계속 신경 쓰였다.

원인은 저장값은 UTC이고 화면 표시도 브라우저 기본값에 맡겨둔 상태였기 때문이다.

먼저 기준을 분리했다

날짜 문제를 고칠 때는 두 가지를 섞지 않기로 했다.

  • 정렬 기준: 서버에 저장된 publishedAt 원본 시간
  • 표시 기준: 독자에게 보여줄 KST 날짜 문자열

정렬은 UTC 타임스탬프로 그대로 하고, 화면 표시만 Asia/Seoul로 고정했다.

표시 함수를 별도로 만들었다

컴포넌트마다 toLocaleDateString()을 직접 쓰지 않도록 작은 함수를 뺐다.

export function formatKoreanDate(value: string | Date) {
  return new Intl.DateTimeFormat("ko-KR", {
    timeZone: "Asia/Seoul",
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
  }).format(new Date(value));
}

이 함수 이름에 Korean을 넣은 이유는 나중에 다른 시간대 표시와 섞지 않기 위해서다.

정렬은 단순하게 유지했다

문자열로 만든 날짜를 정렬에 쓰지 않고, 날짜 값으로 비교했다.

posts.sort((a, b) => {
  return new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime();
});

표시용 문자열은 마지막 렌더링 단계에서만 만들었다.

확인 체크리스트

  • KST 00시 근처에 만든 테스트 데이터가 자연스럽게 보이는가?
  • RSS의 pubDate와 화면 날짜가 의도한 차이를 갖는가?
  • 관리자 목록과 공개 목록이 같은 표시 함수를 쓰는가?
  • 정렬에 YYYY.MM.DD 같은 표시 문자열을 쓰지 않는가?

정리

시간대 문제는 한 번에 크게 터지기보다 계속 작은 어색함으로 남았다. 그래서 저장, 정렬, 표시 기준을 분리해서 이름으로 드러내는 게 가장 효과적이었다. 특히 초보일 때는 날짜 문자열이 보기 좋다고 바로 정렬에 쓰기 쉬운데, 그 순간부터 원인 찾기가 어려워진다.