AM/PM 또는 로케일별 일 주기 표시 방법
각 문화권의 하루 구분 방식에 맞는 시간대를 표시하기 위해 JavaScript 사용하기
소개
4:00와 같은 시간을 표시할 때, 사용자는 그것이 오전인지 오후인지 알기 위한 맥락이 필요합니다. 영어에서는 AM 또는 PM을 추가하여 명확히 합니다. 4:00 AM은 일출 전에 발생하고, 4:00 PM은 오후에 발생합니다.
다른 언어들은 단순히 AM과 PM을 번역하지 않습니다. 많은 문화권에서는 하루를 두 개 이상의 시간대로 나누어 이른 아침, 늦은 아침, 오후, 저녁, 밤에 대한 특정 용어를 사용합니다. 스페인어에는 자정 이후부터 새벽 전까지의 시간을 의미하는 "madrugada"가 있습니다. 독일어는 하루를 두 개가 아닌 여섯 개의 뚜렷한 시간대로 나눕니다. 일부 언어에서는 오전 1시를 "아침 1시"가 아닌 "밤 1시"라고 부릅니다.
JavaScript의 Intl.DateTimeFormat은 dayPeriod 옵션을 제공하여 이러한 문화별 시간 구분을 자동으로 표시합니다. 이 강의에서는 문화권 전반에 걸친 일일 시간대의 작동 방식, 국제 애플리케이션에서 중요한 이유, 그리고 적절한 일일 시간대 레이블로 시간을 포맷하는 방법을 설명합니다.
일일 시간대가 문화별로 다른 이유
서로 다른 문화권에서는 24시간을 명명된 시간대로 나누는 다양한 방법을 개발했습니다. 이러한 구분은 각 문화권의 사람들이 시간에 대해 어떻게 생각하고 이야기하는지를 반영합니다.
영어 사용자들은 하루를 네 개의 시간대로 나눕니다. 아침(Morning)은 자정부터 정오까지, 오후(afternoon)는 정오부터 저녁까지, 저녁(evening)은 늦은 오후부터 어두워질 때까지, 밤(night)은 어두워진 시간부터 자정까지입니다. AM과 PM 용어는 12시간제 시계에 대한 더 간단한 두 시간대 시스템을 제공합니다.
스페인어 사용자들은 자정 이후부터 사람들이 일반적으로 깨어나기 전까지의 시간을 포함하는 뚜렷한 시간대로 "madrugada"를 인식합니다. 이는 늦은 밤 시간과 이른 아침 시간을 구분하는 다섯 개의 시간대 시스템을 만듭니다.
러시아어 사용자들은 사람들이 일반적으로 자고 있는 시간을 가리키는 "ночь"(밤)를 사용합니다. 오전 1시는 사람들이 보통 그 시간에 자고 있기 때문에 "아침 1시"가 아닌 "밤 1시"입니다.
독일어는 하루를 여섯 개의 시간대로 나눕니다. "Morgen"(아침), "Vormittag"(오전), "Mittag"(정오), "Nachmittag"(오후), "Abend"(저녁), 그리고 "Nacht"(밤)는 각각 특정 시간 범위를 포함합니다.
인도네시아어는 "pagi"(새벽부터 오전 10시까지), "siang"(오전 10시부터 오후 2시까지), "sore"(오후 2시부터 일몰까지), 그리고 "malam"(밤)을 사용하여 태양의 위치에 따라 하루를 네 개의 시간대로 나눕니다.
벵골어는 하루를 여섯 개의 시간대로 나눕니다. "ভোর"(새벽), "সকাল"(아침), "দুপুর"(이른 오후), "বিকাল"(늦은 오후), "সন্ধ্যা"(저녁), 그리고 "রাত"(밤)는 각각 특정 시간 범위를 가집니다.
국제 애플리케이션에서 시간을 표시할 때, 각 문화권의 사용자들이 자연스럽게 시간에 대해 이야기하는 방식과 일치하는 용어를 사용해야 합니다. 모든 사용자에게 "4 AM"을 보여주는 것은 다른 언어가 그 시간을 어떻게 설명하는지 무시하는 것입니다.
dayPeriod 옵션 이해하기
Intl.DateTimeFormat의 dayPeriod` 옵션은 시간을 포맷팅할 때 로케일별 일중 시간대를 포함하도록 포맷터에 지시합니다. 단순히 시간과 분만 표시하는 대신, 포맷터는 대상 언어에서 해당 시간대에 적합한 용어를 추가합니다.
이 옵션은 12시간 형식에서만 작동합니다. 24시간 형식에서는 시간 숫자 자체가 충분한 컨텍스트를 제공합니다. 04:00은 명확히 아침이고 16:00은 명확히 오후임을 추가 라벨 없이도 알 수 있습니다. 일중 시간대는 12시간 형식에서 반복되는 시간을 구분하기 위해 존재합니다.
dayPeriod 옵션은 세 가지 값을 허용합니다. narrow는 가장 짧은 형태를 생성하며, 종종 한 글자나 약어로 표시됩니다. short는 약어 형태를 생성합니다. long은 전체 단어나 구문을 생성합니다.
많은 로케일에서 이 세 가지 값은 동일한 출력을 생성합니다. 유니코드 로케일 데이터는 모든 로케일과 형식 길이의 조합에 대해 구별되는 형태를 정의하지 않습니다. 구별되는 형태가 존재하지 않을 경우, 포맷터는 지정한 값에 관계없이 동일한 출력을 사용합니다.
일중 시간대로 시간 포맷팅하기
일중 시간대를 표시하려면 dayPeriod 옵션을 narrow, short 또는 long으로 설정하여 Intl.DateTimeFormat 인스턴스를 생성하세요. 또한 hour와 같은 시간 구성 요소 옵션을 포함하고 hourCycle을 사용하여 12시간 형식을 지정해야 합니다.
const date = new Date('2025-01-15T04:30:00');
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(formatter.format(date));
// 출력: "4:30 in the morning"
이는 시간, 분, 일중 시간대를 표시하는 포맷터를 생성합니다. hourCycle: 'h12' 옵션은 일중 시간대가 나타나기 위해 필요한 12시간 형식을 지정합니다. dayPeriod: 'long' 옵션은 전체 일중 시간대 구문을 요청합니다.
dayPeriod 옵션이 없으면 포맷터는 대신 "4:30 AM"을 표시할 것입니다. 일중 시간대 옵션은 단순한 AM/PM 표시기를 더 설명적인 구문으로 대체합니다.
다양한 시간대에 걸쳐 일중 시간대 표시하기
일중 시간대는 포맷팅되는 시간에 따라 변경됩니다. 포맷터는 로케일 규칙에 따라 각 시간에 적합한 시간대를 자동으로 선택합니다.
const options = {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
};
const formatter = new Intl.DateTimeFormat('en-US', options);
const morning = new Date('2025-01-15T04:30:00');
console.log(formatter.format(morning));
// Output: "4:30 in the morning"
const afternoon = new Date('2025-01-15T14:30:00');
console.log(formatter.format(afternoon));
// Output: "2:30 in the afternoon"
const evening = new Date('2025-01-15T20:30:00');
console.log(formatter.format(evening));
// Output: "8:30 in the evening"
const night = new Date('2025-01-15T23:30:00');
console.log(formatter.format(night));
// Output: "11:30 at night"
영어는 아침(morning), 오후(afternoon), 저녁(evening), 밤(night)을 구분합니다. 각 시간은 시간에 따라 적절한 표현을 받습니다. 어떤 시간대가 적용되는지 직접 결정할 필요가 없습니다. 포맷터는 유니코드 로케일 데이터를 기반으로 이를 자동으로 처리합니다.
좁은(narrow), 짧은(short), 긴(long) 포맷 비교하기
세 가지 포맷 길이는 일부 로케일에서 다른 출력을 생성합니다. 차이점은 언어에 따라 다르며 미묘하거나 존재하지 않을 수 있습니다.
const date = new Date('2025-01-15T04:30:00');
const narrow = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'narrow'
});
console.log(narrow.format(date));
// Output: "4 in the morning"
const short = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'short'
});
console.log(short.format(date));
// Output: "4 in the morning"
const long = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(long.format(date));
// Output: "4 in the morning"
미국 영어의 경우, 세 가지 길이 모두 동일한 출력을 생성합니다. 로케일 데이터는 이 언어와 시간의 조합에 대해 다른 형식을 정의하지 않습니다.
일부 로케일은 길이를 구분합니다. 프랑스어는 좁은 형식과 긴 형식에 대해 다른 출력을 생성합니다.
const date = new Date('2025-01-15T04:30:00');
const frNarrow = new Intl.DateTimeFormat('fr-FR', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'narrow'
});
console.log(frNarrow.format(date));
// Output: "4 mat."
const frLong = new Intl.DateTimeFormat('fr-FR', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(frLong.format(date));
// Output: "4 du matin"
프랑스어는 "mat."를 약어 형식으로, "du matin"을 긴 형식으로 사용합니다. 둘 다 아침을 의미하지만, 긴 형식이 더 명시적입니다.
가능한 한 짧은 출력이 필요한 특정 공간 제약이 없는 한, 명확성을 위해 long을 사용하세요. 긴 형식은 사용자가 이해하기 쉽고, 많은 로케일에서 더 짧은 대안을 제공하지 않습니다.
로케일에 따른 일중 시간대 작동 방식
다양한 로케일은 서로 다른 일중 시간대 용어를 사용하고 하루를 다른 경계로 나눕니다. 포맷터는 각 로케일에 맞는 규칙을 자동으로 적용합니다.
const date = new Date('2025-01-15T04:30:00');
const options = {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
};
const enUS = new Intl.DateTimeFormat('en-US', options);
console.log(enUS.format(date));
// 출력: "4 in the morning"
const enGB = new Intl.DateTimeFormat('en-GB', options);
console.log(enGB.format(date));
// 출력: "4 at night"
const deDK = new Intl.DateTimeFormat('de-DE', options);
console.log(deDK.format(date));
// 출력: "4 morgens"
const fr = new Intl.DateTimeFormat('fr-FR', options);
console.log(fr.format(date));
// 출력: "4 du matin"
영국 영어에서는 오전 4시 30분을 "in the morning"이 아닌 "at night"로 간주하는데, 이는 일중 시간대에 대한 문화적 경계가 다르기 때문입니다. 독일어는 아침 시간대에 "morgens"를 사용합니다. 프랑스어는 같은 시간대에 "du matin"을 사용합니다.
이러한 차이는 오류나 불일치가 아닙니다. 이는 사람들이 시간을 개념화하고 표현하는 방식의 진정한 문화적 차이를 반영합니다. 포맷터는 로케일에 따라 이러한 차이를 자동으로 존중합니다.
일중 시간대는 12시간 형식이 필요합니다
'dayPeriod' 옵션은 'hourCycle: 'h12'' 또는 'hourCycle: 'h11''을 사용하여 12시간 형식을 지정할 때만 작동합니다. 12시간 형식 없이는 일중 시간대가 표시되지 않습니다.
const date = new Date('2025-01-15T04:30:00');
const with12Hour = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(with12Hour.format(date));
// 출력: "4 in the morning"
const with24Hour = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h23',
dayPeriod: 'long'
});
console.log(with24Hour.format(date));
// 출력: "04"
24시간 형식은 옵션이 지정되어 있어도 일중 시간대를 표시하지 않습니다. 24시간 형식에서는 시간 숫자가 추가 레이블 없이도 충분한 컨텍스트를 제공합니다.
'h12'와 'h11'의 차이는 자정과 정오가 어떻게 번호가 매겨지는지와 관련이 있습니다. 시간이 1부터 12까지인 표준 12시간 시계에는 'h12'를 사용하세요. 0부터 11까지의 시간 시스템에는 'h11'을 사용하세요. 두 가지 모두 일중 시간대와 함께 작동합니다.
시간대 구분과 분, 초 결합하기
시간대 구분과 함께 분과 초를 포함할 수 있습니다. 포맷터는 로케일 규칙에 따라 시간대 구분을 적절하게 배치합니다.
const date = new Date('2025-01-15T04:30:45');
const withMinutes = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(withMinutes.format(date));
// 출력: "4:30 in the morning"
const withSeconds = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(withSeconds.format(date));
// 출력: "4:30:45 in the morning"
시간대 구분은 시간 구성 요소 뒤에 나타납니다. 시간대 구분을 수동으로 배치하거나 형식을 지정할 필요가 없습니다. 포맷터가 로케일 규칙에 따라 레이아웃을 처리합니다.
사용자 로케일에 맞는 시간대 구분 포맷팅
특정 로케일을 하드코딩하는 대신 브라우저에서 사용자가 선호하는 언어를 사용하세요. navigator.language 속성은 사용자의 최상위 언어 선호도를 반환합니다.
const date = new Date('2025-01-15T04:30:00');
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(formatter.format(date));
// 출력은 사용자의 로케일에 따라 다름
// en-US의 경우: "4:30 in the morning"
// en-GB의 경우: "4:30 at night"
// de-DE의 경우: "4:30 morgens"
// fr-FR의 경우: "4:30 du matin"
이 접근 방식은 각 사용자가 자연스럽게 시간에 대해 이야기하는 방식과 일치하는 시간대 구분으로 시간을 표시합니다. 브라우저가 언어 선호도를 제공하고 Intl API가 적절한 시간대 구분 용어와 경계를 적용합니다.
시간대 구분을 사용해야 하는 경우
시간대 구분은 단순한 AM/PM 표시보다 더 많은 컨텍스트를 제공하고자 할 때 효과적입니다. 이는 시간을 더 대화체로 만들고 한눈에 이해하기 쉽게 합니다.
설명 텍스트와 함께 시간이 표시되는 사용자 인터페이스에서 시간대 구분을 사용하세요. "오전 4시 30분"과 같이 표시하는 캘린더는 "4:30 AM"보다 더 명확합니다. 이는 문장 내에서 더 자연스럽게 들리기 때문입니다.
대화체 언어가 가독성을 향상시키는 알림 및 메시지에서 시간대 구분을 사용하세요. "회의가 저녁 8시 30분에 시작됩니다"는 "회의가 8:30 PM에 시작됩니다"보다 더 자연스럽게 읽힙니다.
공간이 제한된 컴팩트한 디스플레이에서는 시간대 구분을 피하세요. 표, 차트 및 밀집된 레이아웃은 표준 AM/PM 표시 또는 24시간 형식이 더 적합합니다.
24시간 형식으로 시간을 표시할 때는 시간대 구분을 피하세요. 시간 숫자 자체가 이미 하루 중 시간을 나타내므로 시간대 구분은 유용한 정보를 추가하지 않습니다.
요약
Intl.DateTimeFormat의 dayPeriod 옵션은 문화별 특정 시간대 용어를 표시합니다. 다양한 문화권에서는 하루를 다르게 구분하며, 단순히 AM과 PM 대신 스페인어의 "madrugada"나 독일어의 6개 구분된 시간대와 같은 용어를 사용합니다.
이 옵션은 세 가지 값을 허용합니다. narrow는 가장 짧은 형태를, short는 약어 형태를, long은 전체 구문을 생성합니다. 많은 로케일에서는 세 값 모두 동일한 출력을 생성합니다.
일 주기는 hourCycle: 'h12' 또는 hourCycle: 'h11'로 지정된 12시간 형식을 사용할 때만 나타납니다. 24시간 형식에서는 시간 숫자가 충분한 컨텍스트를 제공하기 때문에 나타나지 않습니다.
다양한 로케일은 서로 다른 일 주기 용어를 사용하고 다른 시간에 경계를 설정합니다. 포맷터는 로케일 식별자에 따라 이러한 규칙을 자동으로 적용합니다. 영국 영어에서는 오전 4시 30분을 "at night"로 취급하는 반면, 미국 영어에서는 "in the morning"으로 취급합니다.