다양한 달력 체계에서 날짜를 형식화하는 방법은 무엇인가요?
JavaScript의 calendar 옵션을 사용하여 전 세계 사용자를 위해 이슬람력, 히브리력, 일본력, 중국력 및 기타 달력 체계로 날짜를 표시하세요
소개
대부분의 개발자는 날짜가 모든 곳에서 동일하게 작동한다고 가정합니다. 2025년 3월 15일에 대한 Date 객체를 생성하고, 형식을 지정한 다음 사용자에게 표시합니다. 그러나 이러한 가정은 사용자가 다른 달력 체계를 따를 때 무너집니다.
많은 문화권에서 그레고리력의 2025년 3월 15일은 완전히 다른 표현을 가집니다. 이슬람력을 따르는 사용자에게는 동일한 시점이 1447년 라마단 16일에 해당합니다. 히브리력 사용자에게는 5785년 아다르 II 14일에 해당합니다. 공식적인 맥락에서 일본 사용자에게는 레이와 7년 3월 15일로 표시됩니다.
달력 시스템은 사회가 시간을 계산하는 방법을 결정합니다. 연도가 시작되는 시점, 월이 구성되는 방식, 날짜가 번호 매겨지는 방법을 정의합니다. JavaScript의 Intl.DateTimeFormat API는 17개 이상의 다양한 달력 시스템을 지원하여 각 사용자의 문화적, 종교적 맥락에 따라 날짜를 표시할 수 있습니다.
이 레슨에서는 달력 체계가 무엇인지, 왜 존재하는지, JavaScript에서 다양한 달력 체계를 사용하여 날짜를 형식화하는 방법을 설명합니다.
달력 체계란 무엇인가
달력 체계는 시간을 구성하고 계산하는 규칙을 정의합니다. 각 체계는 연도가 시작되는 시점, 존재하는 월의 수, 날짜가 번호 매겨지는 방식, 연도 번호 매기기의 시작점 역할을 하는 기원을 설정합니다.
국제적 맥락에서 널리 사용되는 그레고리력은 예수 그리스도의 추정 탄생 시점부터 연도를 계산합니다. 28일에서 31일까지의 길이를 가진 12개월을 사용하여 4년마다 윤년이 있는 365일의 연도를 만듭니다.
다른 달력 체계는 서로 다른 구조와 시작점을 사용합니다. 이슬람력은 연간 354일 또는 355일에 해당하는 12개의 음력 월을 사용합니다. 히브리력은 음력 월과 태양년 정렬을 결합합니다. 일본 달력은 각 천황의 재위 기간마다 변경되는 연호를 사용합니다.
이러한 체계가 존재하는 이유는 서로 다른 문화권이 종교적 의미, 천문 관측, 역사적 사건을 기반으로 시간을 추적하는 고유한 방법을 개발했기 때문입니다. 많은 문화권에서는 종교 의식, 공식 문서, 문화 행사를 위해 그레고리력과 함께 전통 달력을 계속 사용하고 있습니다.
애플리케이션에서 달력 체계가 중요한 이유
다양한 문화적 배경을 가진 사용자에게 서비스를 제공하는 애플리케이션은 해당 사용자가 이해하고 기대하는 형식으로 날짜를 표시해야 합니다. 무슬림 사용자를 위한 기도 시간 앱은 이슬람력으로 날짜를 표시해야 합니다. 유대교 종교 의식을 위한 앱에는 히브리력 날짜가 필요합니다. 일본 정부 관련 애플리케이션에는 일본 연호 형식이 필요합니다.
잘못된 달력 체계를 사용하면 혼란이 발생하고 의도한 대상 사용자가 애플리케이션을 사용할 수 없게 만들 수 있습니다. 이슬람 공휴일 날짜를 그레고리력으로 표시하면 사용자가 수동으로 날짜를 변환해야 합니다. 히브리력 이벤트를 그레고리력 형식으로 표시하면 해당 날짜의 종교적 의미가 모호해집니다.
동일한 Date 객체는 달력 체계에 관계없이 동일한 시점을 나타냅니다. 변경되는 것은 표시를 위해 해당 시점을 형식화하는 방법입니다. JavaScript를 사용하면 복잡한 변환 로직 없이 지원되는 모든 달력 체계로 모든 날짜를 형식화할 수 있습니다.
calendar 옵션 사용
Intl.DateTimeFormat 생성자는 날짜 형식을 지정할 때 사용할 달력 시스템을 지정하는 calendar 옵션을 허용합니다. 달력 식별자를 문자열 값으로 전달합니다.
const date = new Date('2025-03-15');
const gregorianFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'gregory',
dateStyle: 'long'
});
const islamicFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
dateStyle: 'long'
});
console.log(gregorianFormatter.format(date));
// Output: "March 15, 2025"
console.log(islamicFormatter.format(date));
// Output: "Ramadan 16, 1447 AH"
동일한 Date 객체가 달력 시스템에 따라 서로 다른 형식의 문자열을 생성합니다. 그레고리력은 2025년 3월 15일을 표시합니다. 이슬람력은 1447 AH 라마단 16일을 표시합니다.
calendar 옵션은 로케일과 독립적으로 작동합니다. calendar 옵션을 적절한 로케일과 결합하여 영어, 아랍어, 프랑스어 또는 기타 언어로 이슬람 날짜를 형식화할 수 있습니다.
const date = new Date('2025-03-15');
const arabicFormatter = new Intl.DateTimeFormat('ar-SA', {
calendar: 'islamic',
dateStyle: 'long'
});
const englishFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
dateStyle: 'long'
});
console.log(arabicFormatter.format(date));
// Output: "١٦ رمضان ١٤٤٧ هـ"
console.log(englishFormatter.format(date));
// Output: "Ramadan 16, 1447 AH"
달력 시스템은 표시할 날짜를 결정하고, 로케일은 언어 및 형식 규칙을 결정합니다.
이슬람력으로 날짜 형식화하기
이슬람력은 29일 또는 30일로 구성된 12개월을 포함하는 음력입니다. 완전한 음력 연도는 약 354일로, 태양력인 그레고리력보다 10~11일 짧습니다. 이로 인해 이슬람 날짜는 시간이 지남에 따라 그레고리력에서 뒤로 이동합니다.
JavaScript는 여러 이슬람력 변형을 지원합니다. islamic 식별자는 알고리즘 기반 계산을 사용합니다. islamic-umalqura 식별자는 사우디아라비아에서 사용되는 움 알쿠라 달력을 사용합니다. islamic-civil 식별자는 예측 가능한 표 형식 계산을 사용합니다.
const date = new Date('2025-03-15');
const islamicFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
const umalquraFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic-umalqura',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(islamicFormatter.format(date));
// Output: "Ramadan 16, 1447 AH"
console.log(umalquraFormatter.format(date));
// Output: "Ramadan 16, 1447 AH"
무슬림 사용자를 대상으로 하는 대부분의 애플리케이션의 경우 이러한 이슬람력 변형 중 어느 것이든 올바르게 작동합니다. 이들 간의 차이는 작으며 주로 종교 의식의 정확한 날짜를 결정하는 데 중요합니다.
히브리력으로 날짜 형식화하기
히브리력은 유대교 종교 의식에 사용되는 태음태양력입니다. 특정 연도에 윤달을 추가하여 음력 월을 태양년과 동기화합니다. 이를 통해 명절이 계절과 일치하도록 유지합니다.
const date = new Date('2025-03-15');
const hebrewFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'hebrew',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(hebrewFormatter.format(date));
// Output: "14 Adar II 5785"
히브리력은 니산, 이야르, 시반, 탐무즈와 같은 히브리어 월 이름을 사용합니다. 윤년에는 달력에 아다르 I과 아다르 II가 포함됩니다. 연도 수는 유대교 전통에 따른 창조 이후의 연수를 나타냅니다.
히브리어 날짜를 히브리어로 형식화하여 원어민에게 표시할 수 있습니다.
const date = new Date('2025-03-15');
const hebrewFormatter = new Intl.DateTimeFormat('he-IL', {
calendar: 'hebrew',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(hebrewFormatter.format(date));
// Output: "י״ד באדר ב׳ ה׳תשפ״ה"
히브리어 출력은 숫자에 히브리 문자를 사용하고 월 이름에 히브리 문자를 사용합니다.
일본 달력으로 날짜 형식화
일본 달력은 재위 중인 천황을 기준으로 연호를 사용합니다. 현재 연호인 레이와는 2019년 5월 1일 나루히토 천황이 즉위하면서 시작되었습니다. 연도는 각 연호의 시작부터 계산됩니다.
const date = new Date('2025-03-15');
const japaneseFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'japanese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(japaneseFormatter.format(date));
// Output: "March 15, 7 Reiwa"
연도는 레이와 7년으로 표시되며, 이는 레이와 연호의 7번째 해를 나타냅니다. 이 형식은 일본 공식 문서, 정부 양식 및 공식적인 맥락에서 사용됩니다.
일본어로 형식화하면 전통적인 일본 날짜 형식이 생성됩니다.
const date = new Date('2025-03-15');
const japaneseFormatter = new Intl.DateTimeFormat('ja-JP', {
calendar: 'japanese',
era: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(japaneseFormatter.format(date));
// Output: "令和7年3月15日"
출력은 일본 문자를 사용하여 연호(令和), 연도(7年), 월(3月), 일(15日)을 표시합니다.
중국 달력으로 날짜 형식화
중국 달력은 춘절 및 중추절과 같은 전통 중국 명절을 결정하는 데 사용되는 태음태양력입니다. 이 달력은 음력 월과 절기를 결합합니다.
const date = new Date('2025-03-15');
const chineseFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'chinese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(chineseFormatter.format(date));
// Output: "Second Month 16, 2025(yi-si)"
중국 달력 연도는 숫자 연도와 함께 순환 이름(이 경우 을사)을 포함합니다. 월 이름은 "정월" 및 "이월"과 같은 숫자 명칭을 사용합니다.
중국어 형식화는 중국 문자를 사용하여 날짜를 표시합니다.
const date = new Date('2025-03-15');
const chineseFormatter = new Intl.DateTimeFormat('zh-CN', {
calendar: 'chinese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(chineseFormatter.format(date));
// Output: "2025乙巳年二月十六"
페르시아 달력으로 날짜 형식화
페르시아 달력은 태양 히즈라력이라고도 하며, 이란과 아프가니스탄의 공식 달력입니다. 그레고리력과 구조가 유사한 12개월의 태양년을 사용하지만 월 길이와 기원이 다릅니다.
const date = new Date('2025-03-15');
const persianFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'persian',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(persianFormatter.format(date));
// Output: "Esfand 24, 1403 AP"
페르시아력 1403년은 그레고리력 2025년에 해당합니다. AP는 Anno Persico의 약자입니다.
페르시아어 형식은 페르시아 숫자와 월 이름을 사용합니다.
const date = new Date('2025-03-15');
const persianFormatter = new Intl.DateTimeFormat('fa-IR', {
calendar: 'persian',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(persianFormatter.format(date));
// Output: "۲۴ اسفند ۱۴۰۳ ه.ش."
기타 지원되는 달력 시스템
JavaScript는 다양한 문화적 및 종교적 맥락을 위한 추가 달력 시스템을 지원합니다.
buddhist 달력은 그레고리력 연도에 543년을 더하며, 태국 및 기타 상좌부 불교 국가에서 사용됩니다.
const date = new Date('2025-03-15');
const buddhistFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'buddhist',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(buddhistFormatter.format(date));
// Output: "March 15, 2568 BE"
indian 달력은 인도의 공식 민간 달력입니다.
const date = new Date('2025-03-15');
const indianFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'indian',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(indianFormatter.format(date));
// Output: "Phalguna 24, 1946 Saka"
coptic 달력은 콥트 정교회에서 사용됩니다. ethiopic 달력은 에티오피아에서 사용됩니다.
const date = new Date('2025-03-15');
const copticFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'coptic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
const ethiopicFormatter = new Intl.DateTimeFormat('en-US', {
calendar: 'ethiopic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(copticFormatter.format(date));
// Output: "Amshir 6, 1741 ERA1"
console.log(ethiopicFormatter.format(date));
// Output: "Yekatit 6, 2017 ERA1"
지원되는 달력 검색
Intl.supportedValuesOf() 메서드는 JavaScript 구현에서 지원하는 모든 달력 식별자의 배열을 반환합니다.
const calendars = Intl.supportedValuesOf('calendar');
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", "ethioaa", "ethiopic",
// "gregory", "hebrew", "indian", "islamic", "islamic-civil",
// "islamic-tbla", "islamic-umalqura", "japanese", "persian", "roc"]
정확한 목록은 JavaScript 엔진 및 브라우저 버전에 따라 다릅니다. 이 메서드는 항상 달력을 알파벳 순서로 반환합니다.
특정 달력을 사용하기 전에 지원 여부를 확인할 수 있습니다.
const calendars = Intl.supportedValuesOf('calendar');
const supportsIslamic = calendars.includes('islamic');
if (supportsIslamic) {
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
dateStyle: 'long'
});
console.log(formatter.format(new Date()));
}
이 확인은 모든 달력 시스템을 지원하지 않을 수 있는 환경에서 오류를 방지합니다.
유니코드 확장으로 달력 지정
옵션 매개변수를 사용하는 대신 로케일 식별자에 유니코드 확장 키를 사용하여 달력 시스템을 지정할 수 있습니다. 로케일 문자열에 -u-ca- 다음에 달력 식별자를 추가합니다.
const date = new Date('2025-03-15');
const formatter = new Intl.DateTimeFormat('en-US-u-ca-islamic', {
dateStyle: 'long'
});
console.log(formatter.format(date));
// Output: "Ramadan 16, 1447 AH"
-u-ca-islamic 확장은 포매터에게 이슬람력을 사용하도록 지시합니다. 이는 옵션 객체에 calendar: 'islamic'를 전달하는 것과 동일한 결과를 생성합니다.
로케일 문자열과 옵션 객체 모두에서 달력을 지정하면 옵션 객체가 우선합니다.
const date = new Date('2025-03-15');
const formatter = new Intl.DateTimeFormat('en-US-u-ca-islamic', {
calendar: 'hebrew',
dateStyle: 'long'
});
console.log(formatter.format(date));
// Output: "14 Adar II 5785"
옵션 객체의 히브리력이 로케일 문자열의 이슬람력을 재정의합니다. 달력 시스템을 프로그래밍 방식으로 제어해야 할 때는 옵션 매개변수를 사용하세요. 사용자 기본 설정이나 구성에서 가져온 로케일 식별자로 작업할 때는 유니코드 확장을 사용하세요.
로케일이 기본 달력을 결정하는 방법
달력을 지정하지 않으면 포매터는 해당 로케일의 기본 달력을 사용합니다. 대부분의 로케일은 그레고리력을 기본값으로 사용하지만, 일부 로케일은 다른 기본값을 사용합니다.
const date = new Date('2025-03-15');
const usFormatter = new Intl.DateTimeFormat('en-US', {
dateStyle: 'long'
});
const saFormatter = new Intl.DateTimeFormat('ar-SA', {
dateStyle: 'long'
});
const ilFormatter = new Intl.DateTimeFormat('he-IL', {
dateStyle: 'long'
});
console.log(usFormatter.format(date));
// Output: "March 15, 2025"
console.log(saFormatter.format(date));
// Output: "١٦ رمضان ١٤٤٧ هـ"
console.log(ilFormatter.format(date));
// Output: "15 במרץ 2025"
미국 영어 로케일은 기본적으로 그레고리력을 사용합니다. 사우디아라비아 아랍어 로케일은 기본적으로 이슬람력을 사용합니다. 이스라엘 히브리어 로케일은 강력한 히브리력 전통이 있음에도 불구하고 기본적으로 그레고리력을 사용합니다.
resolvedOptions() 메서드를 호출하여 포매터가 사용하는 달력을 확인할 수 있습니다.
const formatter = new Intl.DateTimeFormat('ar-SA', {
dateStyle: 'long'
});
const options = formatter.resolvedOptions();
console.log(options.calendar);
// Output: "islamic-umalqura"
해석된 옵션은 ar-SA 로케일이 기본적으로 islamic-umalqura 달력 변형을 사용함을 보여줍니다.
달력을 명시적으로 설정해야 하는 경우
사용자의 기본 로케일로 일반적인 표시를 위해 날짜를 포맷할 때는 로케일이 달력 시스템을 결정하도록 합니다. 사우디아라비아 사용자는 이슬람력 날짜를 기대합니다. 일본 사용자는 공식적인 맥락에서 일본 연호 형식을 기대합니다. 로케일 기본값은 이러한 기대를 자동으로 처리합니다.
const date = new Date('2025-03-15');
const formatter = new Intl.DateTimeFormat(navigator.language, {
dateStyle: 'long'
});
console.log(formatter.format(date));
// Output varies by user's locale and default calendar
사용자의 로케일과 관계없이 특정 달력 시스템으로 날짜를 표시해야 할 때는 달력을 명시적으로 설정합니다. 기도 시간 앱은 항상 이슬람력 날짜를 표시해야 합니다. 히브리력 앱은 항상 히브리 날짜를 표시해야 합니다.
const date = new Date('2025-03-15');
const formatter = new Intl.DateTimeFormat(navigator.language, {
calendar: 'islamic',
dateStyle: 'long'
});
console.log(formatter.format(date));
// Output shows Islamic calendar date in user's language
이렇게 하면 사용자의 언어 선호도를 존중하면서도 달력 시스템이 애플리케이션의 목적과 일치하도록 보장합니다.
로케일의 기본값과 다른 달력 시스템으로 날짜를 표시할 때는 달력을 명시적으로 설정합니다. 히브리어 사용자에게 그레고리력 날짜를 표시하거나 영어 사용자에게 이슬람력 날짜를 표시할 수 있습니다.
const date = new Date('2025-03-15');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'hebrew',
dateStyle: 'long'
});
console.log(formatter.format(date));
// Output: "14 Adar II 5785"
달력과 다른 옵션 결합
calendar 옵션은 다른 모든 Intl.DateTimeFormat 옵션과 함께 작동합니다. dateStyle, timeStyle, weekday 및 month와 같은 컴포넌트 옵션, timeZone와 같은 기타 옵션과 결합할 수 있습니다.
const date = new Date('2025-03-15T14:30:00');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
dateStyle: 'full',
timeStyle: 'long',
timeZone: 'America/New_York'
});
console.log(formatter.format(date));
// Output: "Saturday, Ramadan 16, 1447 AH at 2:30:00 PM EST"
포매터는 날짜에 이슬람력을 사용하며, 전체 날짜 스타일, 긴 시간 스타일 및 지정된 시간대를 적용합니다.
개별 구성 요소 옵션과 함께 calendar 옵션을 사용할 수도 있습니다.
const date = new Date('2025-03-15');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'japanese',
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(formatter.format(date));
// Output: "Saturday, March 15, 7 Reiwa"
era 옵션은 연호를 사용하는 일본력이나 불교력과 같은 달력을 사용할 때 특히 중요합니다.
다양한 달력으로 날짜 범위 형식 지정
formatRange() 메서드는 calendar 옵션과 함께 작동하여 모든 달력 체계에서 날짜 범위를 형식화합니다.
const startDate = new Date('2025-03-15');
const endDate = new Date('2025-03-25');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(formatter.formatRange(startDate, endDate));
// Output: "Ramadan 16 – 26, 1447 AH"
포매터는 두 날짜에 이슬람력을 적용하고 범위로 형식을 지정하며, 반복되는 정보를 지능적으로 생략합니다.
성능을 위한 포매터 재사용
Intl.DateTimeFormat 인스턴스를 생성하려면 로케일 데이터와 달력 시스템 정보를 처리해야 합니다. 동일한 달력과 로케일로 여러 날짜를 형식화할 때는 포매터를 한 번 생성하고 재사용하세요.
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
dateStyle: 'long'
});
const dates = [
new Date('2025-03-15'),
new Date('2025-04-20'),
new Date('2025-06-10')
];
dates.forEach(date => {
console.log(formatter.format(date));
});
// Output:
// "Ramadan 16, 1447 AH"
// "Dhuʻl-Qiʻdah 22, 1447 AH"
// "Dhuʻl-Hijjah 15, 1447 AH"
이 접근 방식은 날짜 배열을 형식 지정하거나 애플리케이션에서 많은 타임스탬프를 표시할 때 성능을 향상시킵니다.
기억해야 할 사항
달력 체계는 문화가 시간을 구성하고 계산하는 방법을 정의합니다. JavaScript는 Intl.DateTimeFormat API를 통해 이슬람력, 히브리력, 일본력, 중국력, 페르시아력, 불교력, 콥트력을 포함한 17개 이상의 다양한 달력 체계를 지원합니다.
옵션 객체의 calendar 옵션을 사용하거나 로케일 문자열에 유니코드 확장을 추가하여 달력 시스템을 지정합니다. calendar 옵션은 날짜를 형식화하는 달력 시스템을 결정하고, 로케일은 언어 및 형식화 규칙을 결정합니다.
일반적인 용도로 날짜를 표시할 때는 로케일이 기본 달력을 결정하도록 하세요. 애플리케이션이 사용자의 로케일 기본 설정과 관계없이 특정 달력 시스템을 요구하는 경우 달력을 명시적으로 설정하세요.
캘린더 옵션은 스타일, 구성 요소 옵션, 시간대, 날짜 범위를 포함한 모든 날짜 형식 옵션과 함께 작동합니다. 성능 향상을 위해 여러 날짜를 형식화할 때 포매터 인스턴스를 재사용하세요.