사용자 로케일에 맞춰 날짜 형식 지정하는 방법
JavaScript를 사용하여 각 사용자의 지역 규칙에 따라 날짜 표시하기
소개
날짜는 전 세계적으로 다르게 표시됩니다. 미국인들은 2025년 3월 15일을 3/15/2025로 작성하는 반면, 유럽인들은 같은 날짜를 15/03/2025로 작성하고, 일본 사용자들은 2025/3/15를 기대합니다. 날짜 형식을 하드코딩하면 모든 사용자가 동일한 규칙을 따른다고 가정하게 됩니다.
익숙하지 않은 형식으로 날짜를 표시하면 혼란이 발생합니다. 15/03/2025를 기대하는 사용자가 3/15/2025를 보면 해당 날짜가 3월 15일을 나타내는지 아니면 불가능한 15번째 월을 나타내는지 해석하기 위해 멈춰야 합니다. 이러한 인지 부하는 애플리케이션의 모든 날짜에서 누적됩니다.
JavaScript는 날짜 형식을 자동으로 처리하기 위해 Intl.DateTimeFormat API를 제공합니다. 이 레슨에서는 날짜 형식이 문화권마다 다른 이유, API 작동 방식, 그리고 모든 로케일에 대해 날짜를 올바르게 형식화하는 방법을 설명합니다.
로케일에 따라 날짜 형식이 다른 이유
서로 다른 지역은 날짜 작성에 대한 서로 다른 규칙을 발전시켰습니다. 이러한 규칙은 역사적 관행, 교육 시스템 및 문화적 선호도를 반영합니다. 보편적인 단일 형식은 존재하지 않습니다.
미국에서는 날짜가 월-일-년 패턴을 따릅니다. 2025년 3월 15일은 3/15/2025로 표시됩니다.
영국, 독일, 프랑스, 스페인을 포함한 대부분의 유럽 국가에서는 날짜가 일-월-년 패턴을 따릅니다. 같은 날짜가 15/03/2025로 표시됩니다.
일본, 중국, 한국에서는 날짜가 년-월-일 패턴을 따릅니다. 날짜는 2025/3/15로 표시됩니다.
로케일마다 다른 구분 문자도 사용합니다. 미국인들은 슬래시를 사용하고, 독일인들은 마침표를 사용하며, 일부 로케일에서는 하이픈이나 공백을 사용합니다.
월 이름도 언어에 따라 다릅니다. 3월은 영어로 "March", 독일어로 "März", 프랑스어로 "mars", 스페인어로 "marzo", 일본어로 "3月"로 표시됩니다.
날짜를 표시할 때는 구성 요소의 순서와 특정 형식 규칙 모두에서 사용자의 기대에 부합해야 합니다.
Intl.DateTimeFormat을 사용한 날짜 형식 지정
Intl.DateTimeFormat 생성자는 로케일별 규칙을 적용하는 날짜 포맷터를 생성합니다. 첫 번째 인수로 로케일 식별자를 전달한 다음 Date 객체와 함께 format() 메서드를 호출합니다.
const formatter = new Intl.DateTimeFormat('en-US');
const date = new Date('2025-03-15');
console.log(formatter.format(date));
// Output: "3/15/2025"
이것은 슬래시와 함께 월-일-년 패턴을 사용하는 미국 영어용 포맷터를 생성합니다. format() 메서드는 Date 객체를 적절한 형식의 문자열로 변환합니다.
Date 생성자는 2025-03-15와 같은 ISO 8601 날짜 문자열을 받습니다. 이는 UTC 기준 2025년 3월 15일 자정을 나타내는 Date 객체를 생성합니다. 그런 다음 포매터가 이를 로케일별 문자열로 변환합니다.
다양한 로케일에 대해 동일한 날짜 형식 지정
생성자에 전달되는 로케일 식별자를 변경하여 다양한 로케일에 대해 동일한 날짜를 형식 지정할 수 있습니다.
const date = new Date('2025-03-15');
const usFormatter = new Intl.DateTimeFormat('en-US');
console.log(usFormatter.format(date));
// Output: "3/15/2025"
const gbFormatter = new Intl.DateTimeFormat('en-GB');
console.log(gbFormatter.format(date));
// Output: "15/03/2025"
const deFormatter = new Intl.DateTimeFormat('de-DE');
console.log(deFormatter.format(date));
// Output: "15.3.2025"
const jpFormatter = new Intl.DateTimeFormat('ja-JP');
console.log(jpFormatter.format(date));
// Output: "2025/3/15"
각 포맷터는 서로 다른 규칙을 적용합니다. 미국 포맷터는 슬래시로 구분된 월-일-년을 사용합니다. 영국 포맷터는 슬래시로 구분된 일-월-년을 사용합니다. 독일 포맷터는 마침표로 구분된 일-월-년을 사용합니다. 일본 포맷터는 슬래시로 구분된 년-월-일을 사용합니다.
각 로케일이 어떤 패턴이나 구분 기호를 사용하는지 알 필요가 없습니다. API가 로케일 식별자를 기반으로 이러한 세부 사항을 자동으로 처리합니다.
사용자의 로케일에 맞춰 날짜 형식 지정
특정 로케일을 하드코딩하는 대신 브라우저에서 사용자가 선호하는 언어를 사용할 수 있습니다. navigator.language 속성은 사용자의 최우선 언어 설정을 반환합니다.
const userLocale = navigator.language;
const formatter = new Intl.DateTimeFormat(userLocale);
const date = new Date('2025-03-15');
console.log(formatter.format(date));
// Output varies by user's locale
// For en-US: "3/15/2025"
// For en-GB: "15/03/2025"
// For de-DE: "15.3.2025"
// For ja-JP: "2025/3/15"
이 접근 방식은 사용자가 수동으로 로케일을 선택할 필요 없이 각 사용자의 기대에 따라 날짜를 표시합니다. 브라우저가 언어 기본 설정을 제공하고 Intl API가 적절한 형식 규칙을 적용합니다.
전체 선호 언어 배열을 전달하여 대체 동작을 활성화할 수도 있습니다.
const formatter = new Intl.DateTimeFormat(navigator.languages);
const date = new Date('2025-03-15');
console.log(formatter.format(date));
API는 배열에서 지원하는 첫 번째 로케일을 사용합니다. 이는 사용자의 최우선 선호 로케일을 사용할 수 없을 때 더 나은 대체 처리를 제공합니다.
API가 형식화하는 대상 이해하기
Intl.DateTimeFormat API는 JavaScript Date 객체를 포맷합니다. Date 객체는 날짜, 시간 및 시간대 정보를 포함한 특정 시점을 나타냅니다.
Date 객체를 형식화하면 API는 로케일의 규칙에 따라 문자열로 변환합니다. 기본적으로 API는 날짜 부분만 형식화하고 시간은 생략합니다.
const formatter = new Intl.DateTimeFormat('en-US');
const dateWithTime = new Date('2025-03-15T14:30:00');
console.log(formatter.format(dateWithTime));
// Output: "3/15/2025"
Date 객체에는 시간 정보가 포함되어 있지만 기본 포매터는 이를 무시합니다. 이후 레슨에서는 날짜와 시간을 함께 형식화하거나 시간만 형식화하는 방법을 다룰 예정입니다.
형식화할 날짜 생성하기
Date 객체는 여러 가지 방법으로 생성할 수 있습니다. 가장 신뢰할 수 있는 방법은 ISO 8601 날짜 문자열을 사용하는 것입니다.
const date1 = new Date('2025-03-15');
const date2 = new Date('2025-12-31');
const date3 = new Date('2025-01-01');
const formatter = new Intl.DateTimeFormat('en-US');
console.log(formatter.format(date1));
// Output: "3/15/2025"
console.log(formatter.format(date2));
// Output: "12/31/2025"
console.log(formatter.format(date3));
// Output: "1/1/2025"
ISO 8601 문자열은 YYYY-MM-DD 형식을 사용합니다. 이 형식은 명확하며 모든 로케일과 시간대에서 일관되게 작동합니다.
타임스탬프에서 날짜 형식화하기
Unix 타임스탬프에서 Date 객체를 생성할 수도 있습니다. Unix 타임스탬프는 1970년 1월 1일 UTC 이후의 밀리초 수를 나타냅니다.
const timestamp = 1710489600000; // March 15, 2025
const date = new Date(timestamp);
const formatter = new Intl.DateTimeFormat('en-US');
console.log(formatter.format(date));
// Output: "3/15/2025"
이 방법은 API, 데이터베이스 또는 날짜를 숫자로 표현하는 다른 시스템에서 타임스탬프를 받을 때 유용합니다.
Date 객체를 먼저 생성하지 않고 타임스탬프를 format() 메서드에 직접 전달할 수도 있습니다.
const formatter = new Intl.DateTimeFormat('en-US');
const timestamp = 1710489600000;
console.log(formatter.format(timestamp));
// Output: "3/15/2025"
API는 Date 객체와 타임스탬프를 모두 허용합니다. 코드에 더 적합한 방법을 사용하세요.
현재 날짜 형식화하기
현재 날짜를 포맷하려면 인수 없이 Date 객체를 생성하세요. 이렇게 하면 현재 시점을 나타내는 Date 객체가 생성됩니다.
const formatter = new Intl.DateTimeFormat('en-US');
const now = new Date();
console.log(formatter.format(now));
// Output: "10/15/2025" (or current date when run)
현재 타임스탬프를 숫자로 반환하는 Date.now()를 직접 전달할 수도 있습니다.
const formatter = new Intl.DateTimeFormat('en-US');
console.log(formatter.format(Date.now()));
// Output: "10/15/2025" (or current date when run)
두 방법 모두 동일한 결과를 생성합니다.
성능을 위한 포매터 재사용
새로운 Intl.DateTimeFormat 인스턴스를 생성하려면 로케일 데이터를 로드하고 옵션을 처리해야 합니다. 동일한 로케일과 설정으로 여러 날짜를 포맷해야 하는 경우 포매터를 한 번 생성하고 재사용하세요.
const formatter = new Intl.DateTimeFormat('en-US');
const dates = [
new Date('2025-01-01'),
new Date('2025-06-15'),
new Date('2025-12-31')
];
dates.forEach(date => {
console.log(formatter.format(date));
});
// Output:
// "1/1/2025"
// "6/15/2025"
// "12/31/2025"
이 방법은 각 날짜마다 새로운 포매터를 생성하는 것보다 효율적입니다. 수백 또는 수천 개의 날짜가 포함된 배열을 포맷할 때 성능 차이가 두드러집니다.
템플릿에서 날짜 포맷하기
사용자에게 날짜를 표시하는 모든 곳에서 Intl.DateTimeFormat를 사용할 수 있습니다. 여기에는 HTML 템플릿에 포맷된 날짜 삽입, 테이블에 날짜 표시 또는 사용자 인터페이스에 타임스탬프 표시가 포함됩니다.
const formatter = new Intl.DateTimeFormat(navigator.language);
const publishedDate = new Date('2025-03-15');
const updatedDate = new Date('2025-04-20');
document.getElementById('published').textContent = formatter.format(publishedDate);
document.getElementById('updated').textContent = formatter.format(updatedDate);
포맷된 문자열은 다른 문자열 값과 동일하게 작동합니다. 텍스트 콘텐츠, 속성 또는 사용자에게 정보를 표시하는 다른 컨텍스트에 삽입할 수 있습니다.