60.1 날짜는 왜 나라마다 다르게 써요?
날짜 하나로 사고가 나는 걸 저는 여러 번 봤어요. 화면에 03/09가 찍히면 미국 사람은 3월 9일로, 유럽 사람은 9월 3일로 읽어요. 예약이나 마감일이 엇갈리면 큰일이죠. 그래서 날짜는 지역 규칙대로 보여줘야 해요.
여기서도 구원자는 Intl.DateTimeFormat이에요. 같은 시각을 지역별로 어떻게 찍는지 직접 돌려봤어요.
상황: 같은 시각을 나라별 형식으로 찍어요.
const d = new Date("2026-03-09T18:30:00Z");
new Intl.DateTimeFormat("en-US", { dateStyle: "full", timeStyle: "short" }).format(d);
new Intl.DateTimeFormat("en-GB", { dateStyle: "full", timeStyle: "short" }).format(d);
new Intl.DateTimeFormat("ko-KR", { dateStyle: "full", timeStyle: "short" }).format(d);
결과:
en-US: Tuesday, March 10, 2026 at 3:30 AM
en-GB: Tuesday, 10 March 2026 at 03:30
ko-KR: 2026년 3월 10일 화요일 AM 3:30
미국은 월이 앞, 영국은 일이 앞, 한국은 년월일 순에 요일까지 붙고, 요일 이름도 그 나라 말로 나와요. 손으로 짜 맞추면 나라 수만큼 코드가 늘지만, Intl은 지역 코드만 바꾸면 끝이에요.
60.2 날짜 형식을 손으로 만들면 왜 안 돼요?
제가 신입 때 날짜를 year + "년 " + month + "월 " 식으로 조립한 적이 있어요. 한국어만 쓸 땐 멀쩡했는데, 영어를 넣으니 "2026년 March월"이라는 괴상한 문자열이 나왔죠. 손으로 조립한 형식은 한 언어에 못 박혀 버려요.
그래서 형식은 손대지 말고 옵션으로 지시만 하는 게 정석이에요. dateStyle과 timeStyle에 full, long, medium, short를 주면 그 나라에 맞는 완성된 형식이 나오고, 세밀하게는 year, month, weekday 같은 조각별 옵션도 줄 수 있어요.
상황: 원하는 조각만 지정하면 언어에 맞게 조립돼요.
new Intl.DateTimeFormat("ko-KR", {
year: "numeric", month: "long", day: "numeric", weekday: "long"
}).format(new Date("2026-03-09T18:30:00Z"));
// "2026년 3월 10일 화요일"
내가 "년월일과 요일을 보여줘"라고 뜻만 전하면, 순서와 이름은 Intl이 언어별로 맞춰요. 형식 문자열을 직접 조립하는 습관만 버려도 국제화 버그의 절반이 사라져요.
60.3 시간대가 왜 이렇게 골치 아파요?
날짜보다 더 무서운 게 시간대(timezone, 지역별 시간 차이)예요. 같은 순간이라도 지구 반대편에선 다른 시각이고, 심지어 다른 날짜일 수 있어요. 위 예제의 시각을 지역만 바꿔 찍어봤어요.
상황: 똑같은 한 순간을 지역별 시간대로 봐요.
const d = new Date("2026-03-09T18:30:00Z"); // UTC 기준 시각
for (const tz of ["Asia/Seoul", "America/New_York", "Europe/London"]) {
new Intl.DateTimeFormat("en-US",
{ dateStyle: "medium", timeStyle: "short", timeZone: tz }).format(d);
}
결과:
Asia/Seoul: Mar 10, 2026, 3:30 AM
America/New_York: Mar 9, 2026, 2:30 PM
Europe/London: Mar 9, 2026, 6:30 PM
똑같은 한 순간인데 서울은 3월 10일 새벽, 뉴욕은 3월 9일 오후예요. 날짜가 하루 차이나죠. timeZone 옵션에 지역 이름을 주면 Intl이 그 지역 벽시계로 바꿔줘요. 사용자가 "새벽 3시에 예약했는데 왜 오후로 떠요?" 하는 민원은 대개 이 시간대를 안 챙겨서 나요.
60.4 서버엔 시간을 어떻게 저장해요?
여기 황금률이 하나 있어요. 저장은 UTC로, 표시는 지역 시간으로. 이거 하나만 지켜도 시간대 사고의 대부분을 피해요.
이유는 간단해요. 서버가 "2026-03-10 03:30"을 지역 정보 없이 저장하면, 이게 서울 시간인지 뉴욕 시간인지 아무도 몰라요. 반대로 UTC라는 세계 공통 기준으로 저장하면 딱 한 순간을 가리키는 흔들림 없는 값이라, 보여줄 때만 사용자 시간대로 바꾸면 되죠.
상황: 저장은 UTC 문자열, 화면은 사용자 시간대로 변환해요.
const saved = "2026-03-09T18:30:00Z"; // DB엔 UTC로 저장
new Intl.DateTimeFormat("ko-KR",
{ dateStyle: "long", timeStyle: "short", timeZone: "Asia/Seoul" })
.format(new Date(saved)); // 화면엔 서울 시간으로
DB엔 흔들리지 않는 한 순간을 박아두고, 화면에선 같은 데이터를 각자 자기 시계로 보게 하는 거예요. 이 분리가 안 되면 서머타임(일광절약시간)이 바뀔 때 데이터가 통째로 어긋나요.
60.5 "3분 전" 같은 표현은 어떻게 만들어요?
요즘 앱엔 "방금", "3분 전", "어제" 같은 상대 시간 표현이 흔하죠. 이것도 언어마다 다른데, 손으로 "n분 전"을 조립하면 또 그 언어에 못 박혀요. 그래서 Intl.RelativeTimeFormat이 있어요. 한국어와 영어로 돌려봤어요.
상황: 상대 시간을 언어에 맞게 만들어요.
const ko = new Intl.RelativeTimeFormat("ko", { numeric: "auto" });
const en = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
ko.format(-1, "day"); en.format(-1, "day");
ko.format(-2, "hour"); en.format(3, "day");
결과:
ko.format(-1, "day") => "어제"
en.format(-1, "day") => "yesterday"
ko.format(-2, "hour") => "2시간 전"
en.format(3, "day") => "in 3 days"
numeric: "auto" 덕분에 -1일이 "1일 전"이 아니라 자연스러운 "어제"로 나와요. 음수는 과거, 양수는 미래죠. 영어 "in 3 days"처럼 어순이 다른 표현도 알아서 만들어주니, 짜깁기할 이유가 없어요.
60.6 목록이나 요일 같은 것도 지역화가 돼요?
네, 많이요. 예를 들어 여러 항목을 나열할 때도 이음말이 언어마다 달라요. 영어는 "A, B, and C"처럼 and, 한국어는 "및"을 쓰죠. Intl.ListFormat으로 돌려봤어요.
상황: 항목 나열을 언어에 맞게 이어요.
new Intl.ListFormat("en", { type: "conjunction" }).format(["apple", "pear", "kiwi"]);
new Intl.ListFormat("ko", { type: "conjunction" }).format(["사과", "배", "감"]);
결과:
en: apple, pear, and kiwi
ko: 사과, 배 및 감
쉼표 위치와 이음말을 언어가 알아서 정해줘요. 이 밖에 숫자 정렬(Intl.Collator), 상대 시간, 통화까지 Intl 한 식구가 다 처리해요. 국제화에서 뭔가 손으로 조립하고 싶어질 때마다, "이거 Intl에 이미 있지 않나?"를 먼저 의심해보세요. 대개 있어요.
60.7 오늘 내용을 정리해볼게요
날짜와 시간의 지역화를 훑었어요.
날짜는 03/09처럼 나라마다 다르게 읽히니 손으로 조립하지 말고 Intl.DateTimeFormat에 dateStyle이나 조각 옵션으로 뜻만 전하세요. 시간대는 같은 순간도 지역마다 날짜까지 달라지니, 저장은 UTC로, 표시는 timeZone 옵션으로 사용자 시간에 맞추는 황금률을 지키세요.
"어제", "3분 전" 같은 상대 시간은 Intl.RelativeTimeFormat이, 항목 나열은 Intl.ListFormat이 언어에 맞게 만들어줘요. 날짜와 시간은 국제화에서 사고가 가장 잦은 곳이에요. 문자열을 직접 조립하는 대신 Intl에 맡기는 습관 하나가, 그 사고를 통째로 막아줘요.