turin.blog
← 전체 글로 돌아가기

practical debugging note

블로그 글 목록에서 날짜 정렬이 하루씩 밀려 보인 원인

KST 기준으로 쓴 글이 UTC 저장값 때문에 목록에서 어색하게 정렬되던 문제를 표시 기준과 정렬 기준으로 나눠 고친 기록입니다.

빠른 요약

이상하게 보인 부분 밤늦게 글을 발행하면 관리자 목록에서는 오늘 글인데 공개 목록에서는 어제 글처럼 보였다.

이 글에서 확인할 것
  • 이상하게 보인 부분
  • 먼저 나눈 기준
  • 표시 함수를 따로 만들었다
  • 정렬 코드는 단순하게 유지했다
  • 확인 체크리스트

이상하게 보인 부분

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

원인은 저장값은 UTC이고 화면 표시도 브라우저 기본값에 맡겨둔 상태였기 때문이다. 내 노트에는 KST 기준으로 발행했다고 적혀 있는데, 코드에서는 기준을 명확히 쓰지 않았다.

먼저 나눈 기준

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

  • 정렬 기준: 서버에 저장된 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을 넣은 이유는 나중에 다른 시간대 표시와 섞지 않기 위해서다. 그냥 formatDate라고 두면 다시 기준이 흐려질 것 같았다.

정렬 코드는 단순하게 유지했다

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

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

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

확인 체크리스트

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

정리하며

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