1. Serial Number란?
Excel에서 날짜는 우리가 흔히 생각하는 "YYYY-MM-DD" 형태가 아니라, 숫자(Serial Number) 로 저장된다. 이 숫자는 특정 기준일로부터 며칠이 지났는지를 나타내며, 소수점 아래는 시간 비율을 의미한다.
- 기준일
기준일은 1899-12-30 을 기준(0일)으로 하는 날짜 형식이다.
즉, `45809.36366`를 예로 든다면 `45809`은 1899년 12월 30일로부터 지난 일 수(45809일 지남), `.36366`는 하루 24시간 중 흘러간 비율(36.366% 지남 약 08:43:40)을 의미한다.
45809.36366 = 2025-10-24T08:43:40
왜 변환이 필요할까?
Excel에서 받은 날짜는 Serial Number(숫자)이고,
API나 데이터베이스(DB)에서는 일반적으로 ISO 8601 형식(2025-10-23T14:30:00Z) 등으로 저장된다.
즉, 엑셀에서 받아온 날짜 데이터와 현재 날짜 혹은 api 등에서 받아온 날짜를 비교하기 위해선 수학적으로 계산된 날짜로 변환이 필요하다.
예를 들어 Excel에서 추출한 날짜 데이터(Serial Number)와 DB에 저장되어있는 날짜 데이터를 비교하려면 밀리초로 변환하여 숫자 비교를 거쳐야한다.
Serial Number To Millisecond
function excelDateToMillis(serialNumber: number): number {
const millisPerDay = 24 * 60 * 60 * 1000; // 하루 24시간의 밀리초 단위
const excelEpochMillis = Date.UTC(1899, 11, 30);
return excelEpochMillis + serialNumber * millisPerDay;
}
먼저 Serial Number를 엑셀 기준 날짜와 더해 밀리초 단위로 반환한다.
Date() 객체를 활용해 `1899-11-30`을 밀리초로 반환한다.
여기서 알아야할 점은
- Date() 객체에 날짜 형식(YYYY-MM-DDThh:mm:ssZ)을 넣으면 밀리초 단위로 반환되고, 밀리초 단위를 넣으면 날짜 형식으로 반환된다.
- JavaScript에서 월(month)는 0-based 방식을 사용하기 때문에, 12월은 11로 표현된다.
DB Date(ISO) To Millisecond
const dbMillis = new Date(dbIso).getTime();
서버로부터 전달받은 날짜 데이터를 `dbIso`라고 하겠다.
`YYYY-MM-DDThh:mm:ss.sssZ`와 같은 형태이기 때문에 Date() 객체를 이용해 밀리초로 변환한다.
참고로 `new Date(dbIso)`를 하게되면 밀리초로 변환된 데이터를 가진 객체가 반환되고, getTime() 이용해 사용할 수 있는 숫자의 형태로 반환하는 것이다.
const excelMillis = excelDateToMillis(serialNumber);
if (dbMillis > excelMillis) ...
이렇게 두 날짜를 통일된 데이터 형식으로 변환한뒤 비교 등의 계산을 시행할 수 있다
다시 정리해보자면,
엑셀 serial number와 DB의 ISO 데이터의 비교는
serial number => 엑셀 기준 시각(1899-12-30) + serial number
ISO => Date().getTime() 객체를 이용해 밀리초 변환
이때 두 값은 UTC(1970-01-01)을 기준으로 한다.
ISO 8601
ISO 8601은 날짜와 시간을 연속적인 문자열로 표현하며 가장 널리 쓰이는 데이터 표준 형식이다.
표현 방식은
`YYYY-MM-DDTHH:mm:ss.sssZ`와 같이 표현되며,
순서대로 연도-월-일-구분문자(T)-시-분-초.밀리초+UTC(Z) 를 의미한다.
번외로, 종종 DB에 저장되거나 API로 전달받는 ISO 데이터가 로컬 타임을 기준으로 할 때도 있다.
이럴 때는 UTC를 기준으로 현재 로컬 시간과의 차이를 의미하는 .getTimezoneOffset() 메서드를 활용한다.
const dbMillis = new Date(dbIso).getTime() - new Date(dbIso).getTimezoneOffset() * 60 * 1000;'WEB > JavaScript' 카테고리의 다른 글
| [JS] Fuse.js (0) | 2024.12.12 |
|---|---|
| [JS] Promise (2) | 2024.11.19 |
| [JS] 옵셔널 체이닝: "?." (0) | 2024.11.14 |