EST(eastern standard time) 기준으로, 2022년 1월 24일 오후 8시에 LOVO에서 만든 NFT 민팅을 시작한다. 이를 소개하는 랜딩페이지에서 카운트 다운을 하는 UI를 작업하면서 겪었던 시간대에 대한 이슈들을 기록으로 남긴다.
해외시간대를 고려해서 UI를 개발한 건 이번이 처음이라 낯설었고, 지역마다 다 다른 시간대를 고려해서 개발하려면 어떻게 해야할까 고민을 시작했다.
어느 특정 시간대만 고려해서 코드를 작성하면 분명 local마다 다르게 작동하는 Date API때문에 버그가 발생할 것이다.
평소에 유튜브로 즐겨보던 포프님의 영상에서 여럼풋이 들었던 아래 문장이 떠올랐다.
💡 [UTC 시간을 쓰자](https://www.youtube.com/watch?v=GMQNsmEHYD4)말 그대로, UTC 시간을 사용하는 것을 첫 단추로 잡고 차근차근 접근했다. 브라우저에서는 UTC관련 api를 제공해주고 있다. 그 중에서 나는 Date.UTC()
함수를 활용했다.
EST 기준, 2022년 1월 24일 오후 8시를 위의 UTC함수를 사용해 milliseconds를 얻었다. 하지만 실제로 EST는 UTC보다 5시간이 더 빠르다. 따라서 아래의 UTC시간을 EST로 변환하게 되면 사실상 5시간이 더 빠른 2022년 1월 24일 오후 3시이다.
Date.UTC(2022, 0, 24, 20);
즉, 우리가 원하는 EST 시간대에 해당되는 UTC는 위의 시간에 5시간을 더해줘야 한다.
코드적으로는 아래와 같이 처리해주었다.
const HOUR = 1000 * 60 * 60;
const theDay = Date.UTC(2022, 0, 24, 20) + 5 * HOUR;
남은 시간을 카운트하기 위해서는 현재 시간과의 차이를 구해야했다. 현재 시간을 구하는 API는 아래와 같다. 이 API자체가 UTC를 기준으로 milliseconds를 반환해준다.
const now = Date.now();
따라서 위에서 얻은 UTC 와 현재 시간을 빼주면 남은 시간을 milliseconds로 구할 수 있었다.
const offset = theDay - now;
마지막으로 기록으로 남기고 싶은 이슈다. 디자이너 분이 요청한 UI에는 총 4가지를 그려줘야 했다.
우리는 현재 milliseconds를 가지고 있기 때문에 해당되는 단위로 나눠서 결과를 얻었다.
/*
* DAY, HOUR, MINUTE은 millisecond로 표현한 값이다.
*/
const day = Math.floor(offset / DAY)
const hour = Math.floor(offset % DAY);
const minute = Math.floor(offset % HOUR);
const second = Math.floor(offset % MINUTE)
내가 여기서 한 가지 삽질한 부분이 있는데, 결과값의 소숫점을 버리고 string으로 변환하기 위해 toFixed()
API를 사용했다.
그런데 day, hour, minute, second가 모두 1씩 크게 나오는 이슈가 있었다. 알고보니 toFixed
API는 소숫점을 버릴때, 반올림을 하는 동작이 있었고 이 부분이 의도하는 결과값이랑 달랐던 원인이었다.