풀지 못 한 문제(실시간 시계)

현재 시간을 실시간으로 사용해야 하는데 문제가 생겼다.

setInterval을 사용해서 1초마다 시간을 뽑아낸 후 recoil에 보냈는데... 보낸 시간을 불러와 뽑아보면 오늘 날짜보다 하루 늦은 날짜로 나온다. 

new Date()로 바로 찍은 시간(위), 상태관리에 보낸 후 다시 받아온 시간(아래)

recoil에 보낸 후 다시 불러오는 동안 아무런 가공도 거치지 않았다. 그저 recoil에 set 한 후 다시 import 해서 찍었을 뿐인데... 하루는 어디에 잡아먹힌 것인가. 

 

  // component.js
  useEffect(() => {
    const id = setInterval(() => {
      const now = new Date();
      const todayInKorea = new Intl.DateTimeFormat("en-US", {
        timeZone: "Asia/Seoul",
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
      }).format(now);

      setToday(new Date(todayInKorea));
    }, 1000);
    return () => clearInterval(id);
  }, []);
  
  // recoil.js
  export const TodayAtom = atom({
  key: "TodayAtom",
  default: new Date(
    new Date().toLocaleString("en-US", { timeZone: "Asia/Seoul" })
  ),

 

타임존이 문제인가 싶어 컴포넌트와 recoil 초기값의 타임존을 명확하게 명시해보기도 했지만 전혀 소용이 없다. 

 

 

html에 그려보면 이런 아름다운 에러도 받을 수 있다.

서버측 시간은 19일인데 클라이언트측 시간은 20일이란다. 오늘은 20일이니 서버쪽 시간이 이상한 것 같다.

 

chat gpt한테 물어봤는데 서버에서 날짜를 생성할 때 시간대를 명시적으로 설정하라고 한다. 하지만 나는 지금 서버에서 날짜를 생성해 쓰는 코드가 없다. 

 

현재 recoil에서 atom으로 받은 시간을 selector로 가공해서 사용하고 있는데, selector에서 new Date()로 시간을 새로 뽑아버리거나 today를 new Date()로 감싸니 현재 날짜를 받아올 수 있어서 일단 코드는 원하는대로 작동하게끔 만들었다. 하지만 today atom이 왜 하루 전으로 들어오는지는 여전히 모르겠다.

 

시간이 없어 일단은 그냥 넘어가지만 나중에 조금 더 자세히 알아봐야지 싶어서 글로 남겨둔다. 

 

 

+추가

일반적으로 new Date()는 사용자의 컴퓨터 시간대를 기준으로 생성되고, 서버 시간과 차이가 있다면 .env 파일에 TZ를 추가하거나, 서버 시간을 받아와서 한국 시간으로 변환해 사용하는 방법이 주로 사용되는 듯 하다. 하지만 시간을 recoil에 저장했다가 출력하는것과 서버와의 관련은 아직 정확하게 이해하지 못 했다.