AM/PM 또는 로케일별 시간대 표시 방법
JavaScript를 사용하여 각 문화권의 하루 구분 방식에 맞는 시간대 표시하기
소개
4:00과 같은 시간을 표시할 때 사용자는 그것이 오전인지 오후인지 알기 위해 맥락이 필요합니다. 영어에서는 명확히 하기 위해 AM 또는 PM을 추가합니다. 4:00 AM은 일출 전에 발생하고, 4:00 PM은 오후에 발생합니다.
다른 언어들은 단순히 AM과 PM을 번역하지 않습니다. 많은 문화권에서는 하루를 두 개 이상의 시간대로 나누며, 이른 아침, 늦은 아침, 오후, 저녁, 밤에 대한 특정 용어를 사용합니다. 스페인어에는 자정 이후이지만 새벽 전의 시간을 나타내는 "madrugada"가 있습니다. 독일어는 하루를 두 개가 아닌 여섯 개의 구별되는 시간대로 나눕니다. 일부 언어에서는 오전 1시를 "아침 1시"가 아닌 "밤 1시"라고 부릅니다.
JavaScript의 Intl.DateTimeFormat는 dayPeriod 옵션을 제공하여 이러한 문화권별 시간 구분을 자동으로 표시합니다. 이 레슨에서는 문화권에 따라 시간대가 어떻게 작동하는지, 국제 애플리케이션에서 왜 중요한지, 그리고 적절한 시간대 레이블로 시간을 형식화하는 방법을 설명합니다.
문화권에 따라 시간대가 다른 이유
서로 다른 문화권에서는 24시간을 명명된 시간대로 나누는 서로 다른 방식을 발전시켰습니다. 이러한 구분은 각 문화권의 사람들이 시간에 대해 생각하고 이야기하는 방식을 반영합니다.
영어 사용자들은 하루를 네 개의 시간대로 나눕니다. 아침은 자정부터 정오까지, 오후는 정오부터 저녁까지, 저녁은 늦은 오후부터 어두워질 때까지, 밤은 어두워진 후부터 자정까지입니다. 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는 전체 단어나 구문을 생성합니다.
많은 로케일의 경우 이 세 가지 값은 동일한 출력을 생성합니다. Unicode 로케일 데이터는 로케일과 형식 길이의 모든 조합에 대해 구별되는 형식을 정의하지 않습니다. 구별되는 형식이 존재하지 않는 경우 포매터는 지정한 값에 관계없이 동일한 출력을 사용합니다.
시간대를 사용한 시간 형식 지정
시간대를 표시하려면 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));
// Output: "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"
영어는 아침, 오후, 저녁 및 밤을 구분합니다. 각 시간은 시간에 따라 적절한 문구를 받습니다. 어떤 시간대가 적용되는지 결정할 필요가 없습니다. 포매터는 Unicode 로케일 데이터를 기반으로 자동으로 처리합니다.
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));
// Output: "4 in the morning"
const enGB = new Intl.DateTimeFormat('en-GB', options);
console.log(enGB.format(date));
// Output: "4 at night"
const deDK = new Intl.DateTimeFormat('de-DE', options);
console.log(deDK.format(date));
// Output: "4 morgens"
const fr = new Intl.DateTimeFormat('fr-FR', options);
console.log(fr.format(date));
// Output: "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));
// Output: "4 in the morning"
const with24Hour = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h23',
dayPeriod: 'long'
});
console.log(with24Hour.format(date));
// Output: "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));
// Output: "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));
// Output: "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));
// Output varies by user's locale
// For en-US: "4:30 in the morning"
// For en-GB: "4:30 at night"
// For de-DE: "4:30 morgens"
// For fr-FR: "4:30 du matin"
이 접근 방식은 각 사용자가 자연스럽게 시간을 표현하는 방식과 일치하는 시간대로 시간을 표시합니다. 브라우저가 언어 기본 설정을 제공하고 Intl API가 적절한 시간대 용어와 경계를 적용합니다.
시간대를 사용해야 하는 경우
시간대는 단순한 오전/오후 표시보다 더 많은 맥락을 제공하고자 할 때 효과적입니다. 시간을 더 대화체로 만들고 한눈에 해석하기 쉽게 만듭니다.
설명 텍스트와 함께 시간이 표시되는 사용자 인터페이스에서 시간대를 사용하세요. "새벽 4시 30분"을 표시하는 캘린더는 "오전 4시 30분"보다 명확합니다. 이 표현이 본문에서 더 자연스럽게 들리기 때문입니다.
대화체 언어가 가독성을 향상시키는 알림 및 메시지에서 시간대를 사용하세요. "회의가 저녁 8시 30분에 시작합니다"는 "회의가 오후 8시 30분에 시작합니다"보다 더 자연스럽게 읽힙니다.
공간이 제한된 컴팩트한 디스플레이에서는 시간대를 피하세요. 표, 차트 및 밀집된 레이아웃은 표준 오전/오후 표시 또는 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"으로 처리합니다.