12시간제와 24시간제 시간 형식 간 전환 방법

사용자 선호도에 따라 JavaScript를 사용하여 AM/PM 또는 24시간 형식으로 시간 표시하기

소개

시간은 전 세계적으로 다르게 표시됩니다. 미국인들은 일반적으로 오후 2:30을 보는 반면, 독일인들은 14:30을 보며, 둘 다 같은 순간을 나타냅니다. 하나의 형식으로만 시간을 표시하면 모든 사용자가 동일한 관례를 따른다고 가정하는 것입니다.

익숙하지 않은 형식으로 시간을 표시하면 마찰이 발생합니다. 14:30을 기대하는 사용자가 오후 2:30을 보면 시간을 머릿속으로 변환해야 합니다. 오후 2:30을 기대하는 사용자가 14:30을 보면 같은 문제에 직면합니다. 이러한 인지적 부담은 애플리케이션에 표시되는 모든 시간마다 반복됩니다.

JavaScript는 시간 형식을 자동으로 처리하기 위해 Intl.DateTimeFormat API를 제공합니다. 이 레슨에서는 시간 형식이 왜 다른지, API가 12시간제와 24시간제 표시를 어떻게 제어하는지, 그리고 언제 로케일 기본값을 재정의해야 하는지 설명합니다.

로케일에 따라 시간 형식이 다른 이유

서로 다른 지역은 시간 표시에 대한 서로 다른 관례를 발전시켰습니다. 이러한 관례는 문화적 관행, 교육 시스템 및 역사적 선례를 반영합니다. 보편적인 단일 형식은 없습니다.

미국, 캐나다, 호주 및 필리핀에서는 AM/PM 표시가 있는 12시간제가 표준입니다. 오후 시간은 오후 2:30으로 표시됩니다.

유럽, 라틴 아메리카 및 아시아 대부분 지역에서는 24시간제가 표준입니다. 같은 시간이 AM/PM 표시 없이 14:30으로 표시됩니다.

일부 지역에서는 상황에 따라 두 형식을 모두 사용합니다. 영국은 교통 일정에는 24시간제를 사용하지만 일상 대화에는 12시간제를 사용합니다.

시간을 표시할 때는 사용자의 지역 및 상황에 대한 기대에 맞춰야 합니다.

12시간 형식과 24시간 형식의 의미

12시간 형식은 하루를 두 개의 12시간 주기로 나눕니다. 시간은 12부터 11까지 진행된 후 다시 시작됩니다. 시스템은 자정부터 정오까지는 AM(ante meridiem)을, 정오부터 자정까지는 PM(post meridiem)을 사용합니다. 자정은 12:00 AM에 시작하고 정오는 12:00 PM에 발생합니다.

12:00 AM → midnight
1:00 AM → 1 hour after midnight
11:59 AM → 1 minute before noon
12:00 PM → noon
1:00 PM → 1 hour after noon
11:59 PM → 1 minute before midnight

24시간 형식은 0부터 23까지 시간을 연속적으로 계산합니다. 자정은 00:00에 시작하고 하루는 23:59에 끝납니다. 각 시간이 고유한 번호를 가지므로 AM/PM 표시가 필요하지 않습니다.

00:00 → midnight
01:00 → 1 hour after midnight
11:59 → 1 minute before noon
12:00 → noon
13:00 → 1 hour after noon
23:59 → 1 minute before midnight

로케일마다 기본적으로 다른 형식을 사용합니다. Intl.DateTimeFormat API는 이러한 기본값을 존중하지만 필요할 때 재정의할 수 있습니다.

hour12 옵션을 사용하여 시간 형식 제어하기

hour12 옵션은 12시간 형식 사용 여부를 제어합니다. AM/PM이 있는 12시간 형식의 경우 true로 설정하고, 24시간 형식의 경우 false로 설정하세요.

const date = new Date('2025-03-15T14:30:00');

const format12 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hour12: true
});

const format24 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hour12: false
});

console.log(format12.format(date));
// Output: "2:30 PM"

console.log(format24.format(date));
// Output: "14:30"

hour12 옵션은 로케일의 기본 동작을 재정의합니다. 미국 영어가 일반적으로 12시간 형식을 사용하더라도 hour12: false로 설정하면 24시간 형식이 강제됩니다.

hour12 옵션이 적용되려면 옵션에 hour를 포함하거나 timeStyle를 사용해야 합니다. 출력에 시간 구성 요소가 없으면 이 옵션은 영향을 미치지 않습니다.

hourCycle 옵션을 사용하여 세밀하게 제어하기

hourCycle 옵션은 시간을 계산하는 방법을 정확하게 지정하여 hour12보다 더 많은 제어를 제공합니다. 네 가지 값을 허용합니다: "h11", "h12", "h23", "h24".

const date = new Date('2025-03-15T00:30:00'); // 12:30 AM

const h11 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h11'
});

const h12 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h12'
});

const h23 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h23'
});

const h24 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h24'
});

console.log(h11.format(date));
// Output: "0:30 AM"

console.log(h12.format(date));
// Output: "12:30 AM"

console.log(h23.format(date));
// Output: "00:30"

console.log(h24.format(date));
// Output: "24:30"

각 시간 주기 값은 동일한 시간에 대해 서로 다른 출력을 생성합니다. 차이점은 자정과 정오에서 가장 명확하게 나타납니다.

네 가지 hourCycle 값 이해하기

네 가지 hourCycle 값은 각 기간 내에서 시간이 번호 매겨지는 방식을 정의합니다.

"h12" 값은 1부터 12까지의 시간을 사용하는 12시간 형식을 사용합니다. 자정은 12:00 AM으로 표시되고 정오는 12:00 PM으로 표시됩니다. 이것은 미국에서 사용되는 표준 12시간 형식입니다.

"h11" 값은 0부터 11까지의 시간을 사용하는 12시간 형식을 사용합니다. 자정은 0:00 AM으로 표시되고 정오는 0:00 PM으로 표시됩니다. 이 형식은 덜 일반적이지만 일부 맥락에서 나타납니다.

"h23" 값은 0부터 23까지의 시간을 사용하는 24시간 형식을 사용합니다. 자정은 00:00으로 표시되고 하루는 23:59에 끝납니다. 이것은 유럽과 아시아 대부분에서 사용되는 표준 24시간 형식입니다.

"h24" 값은 1부터 24까지의 시간을 사용하는 24시간 형식을 사용합니다. 자정은 전날의 관점에서 24:00으로 표시됩니다. 이 형식은 드물지만 일부 기술적 맥락에서 나타납니다.

대부분의 애플리케이션은 12시간 형식의 경우 "h12"를 사용하거나 24시간 형식의 경우 "h23"를 사용합니다.

시간 주기별 자정 시간 비교

자정은 시간 주기 값 간의 차이를 가장 명확하게 보여줍니다.

const midnight = new Date('2025-03-15T00:00:00');

const cycles = ['h11', 'h12', 'h23', 'h24'];

cycles.forEach(cycle => {
  const formatter = new Intl.DateTimeFormat('en-US', {
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric',
    hourCycle: cycle
  });

  console.log(`${cycle}: ${formatter.format(midnight)}`);
});

// Output:
// h11: 0:00:00 AM
// h12: 12:00:00 AM
// h23: 00:00:00
// h24: 24:00:00

h12h23 값은 각각의 형식에 대해 가장 익숙한 표현을 생성합니다.

시간 주기별 정오 시간 비교

정오 또한 시간 주기가 어떻게 다른지 보여줍니다.

const noon = new Date('2025-03-15T12:00:00');

const cycles = ['h11', 'h12', 'h23', 'h24'];

cycles.forEach(cycle => {
  const formatter = new Intl.DateTimeFormat('en-US', {
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric',
    hourCycle: cycle
  });

  console.log(`${cycle}: ${formatter.format(noon)}`);
});

// Output:
// h11: 0:00:00 PM
// h12: 12:00:00 PM
// h23: 12:00:00
// h24: 12:00:00

다시 말하지만, h12h23는 표준 표현을 생성하는 반면 h11는 정오 시간에 0을 사용합니다.

hour12와 hourCycle의 상호 작용 방식

hour12hourCycle를 모두 지정하면 hour12 옵션이 우선하며 hourCycle 옵션은 무시됩니다.

const date = new Date('2025-03-15T14:30:00');

const formatter = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hour12: true,
  hourCycle: 'h23'  // This is ignored
});

console.log(formatter.format(date));
// Output: "2:30 PM" (12-hour format from hour12: true)

hour12: true 설정은 12시간 형식을 강제하여 일반적으로 24시간 형식을 생성하는 hourCycle: 'h23' 설정을 재정의합니다.

실제로는 간단한 제어를 위해 hour12를 사용하거나 정밀한 제어를 위해 hourCycle를 사용하되, 둘을 함께 사용하지 마세요.

로케일 기본값 준수

hour12hourCycle를 모두 생략하면 포매터는 로케일의 기본 시간 형식을 사용합니다.

const date = new Date('2025-03-15T14:30:00');

const usFormatter = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric'
});

const deFormatter = new Intl.DateTimeFormat('de-DE', {
  hour: 'numeric',
  minute: 'numeric'
});

const jpFormatter = new Intl.DateTimeFormat('ja-JP', {
  hour: 'numeric',
  minute: 'numeric'
});

console.log(usFormatter.format(date));
// Output: "2:30 PM" (US default: 12-hour)

console.log(deFormatter.format(date));
// Output: "14:30" (German default: 24-hour)

console.log(jpFormatter.format(date));
// Output: "14:30" (Japanese default: 24-hour)

미국 로케일은 기본적으로 12시간 형식을 사용하는 반면 독일어 및 일본어 로케일은 기본적으로 24시간 형식을 사용합니다. 이러한 기본값을 준수하면 각 지역의 사용자에게 가장 익숙한 경험을 제공합니다.

로케일 기본값 재정의

hour12 또는 hourCycle를 명시적으로 설정하여 로케일의 기본 시간 형식을 재정의할 수 있습니다.

const date = new Date('2025-03-15T14:30:00');

// Force German locale to use 12-hour format
const de12 = new Intl.DateTimeFormat('de-DE', {
  hour: 'numeric',
  minute: 'numeric',
  hour12: true
});

// Force US locale to use 24-hour format
const us24 = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hour12: false
});

console.log(de12.format(date));
// Output: "2:30 PM"

console.log(us24.format(date));
// Output: "14:30"

이 접근 방식은 사용자의 로케일에 관계없이 특정 시간 형식을 적용해야 할 때 유용합니다.

로케일 기본값을 준수해야 하는 경우

대부분의 애플리케이션은 로케일 기본값을 준수해야 합니다. 각 지역의 사용자는 자신에게 익숙한 형식으로 시간이 표시되기를 기대합니다. 이러한 기본값을 재정의하면 혼란이 발생합니다.

사용자에게 자신의 지역에서 시간을 표시할 때 포매터가 로케일의 기본 시간 형식을 사용하도록 하세요.

const formatter = new Intl.DateTimeFormat(navigator.language, {
  hour: 'numeric',
  minute: 'numeric'
});

const time = new Date('2025-03-15T14:30:00');
console.log(formatter.format(time));
// Output varies by user's locale
// For en-US: "2:30 PM"
// For de-DE: "14:30"
// For ja-JP: "14:30"

이 접근 방식은 구성 없이도 각 사용자의 기대에 자동으로 적응합니다.

로케일 기본값을 재정의해야 하는 경우

애플리케이션이 모든 사용자에게 일관성을 요구하는 경우 로케일 기본값을 재정의합니다. 교통 시스템, 군사 애플리케이션 및 기술 도구는 로케일에 관계없이 24시간 형식이 필요한 경우가 많습니다.

// Always use 24-hour format for flight times
const formatter = new Intl.DateTimeFormat(navigator.language, {
  hour: 'numeric',
  minute: 'numeric',
  hour12: false
});

const departureTime = new Date('2025-03-15T14:30:00');
console.log(`Departure: ${formatter.format(departureTime)}`);
// Output: "Departure: 14:30" (for all locales)

이렇게 하면 일정, 로그 또는 타임스탬프와 같이 사용자가 정확하게 참조해야 하는 시간을 표시할 때 일관성을 보장합니다.

사용자가 명시적으로 기본 설정을 선택한 경우에도 기본값을 재정의할 수 있습니다. 애플리케이션이 12시간 형식과 24시간 형식 중 선택할 수 있는 설정을 제공하는 경우 로케일 기본값 대신 해당 기본 설정을 사용합니다.

function formatTime(date, userPrefers24Hour) {
  const formatter = new Intl.DateTimeFormat(navigator.language, {
    hour: 'numeric',
    minute: 'numeric',
    hour12: !userPrefers24Hour
  });

  return formatter.format(date);
}

const time = new Date('2025-03-15T14:30:00');

console.log(formatTime(time, false));
// Output: "2:30 PM"

console.log(formatTime(time, true));
// Output: "14:30"

이 패턴은 구분 문자 및 텍스트 방향과 같은 시간 표시의 다른 측면을 현지화하면서 사용자 선택을 존중합니다.

timeStyle과 함께 hour12 사용하기

hour12 옵션은 timeStyle 프리셋 스타일과 함께 작동합니다. 이를 통해 편리한 프리셋 스타일을 사용하면서 시간 형식을 제어할 수 있습니다.

const date = new Date('2025-03-15T14:30:45');

const short12 = new Intl.DateTimeFormat('en-US', {
  timeStyle: 'short',
  hour12: true
});

const short24 = new Intl.DateTimeFormat('en-US', {
  timeStyle: 'short',
  hour12: false
});

const medium12 = new Intl.DateTimeFormat('en-US', {
  timeStyle: 'medium',
  hour12: true
});

const medium24 = new Intl.DateTimeFormat('en-US', {
  timeStyle: 'medium',
  hour12: false
});

console.log(short12.format(date));
// Output: "2:30 PM"

console.log(short24.format(date));
// Output: "14:30"

console.log(medium12.format(date));
// Output: "2:30:45 PM"

console.log(medium24.format(date));
// Output: "14:30:45"

이 접근 방식은 프리셋 스타일과 명시적 시간 형식 제어를 결합하여 형식 지정을 단순화합니다.

여러 로케일에 대한 시간 형식 지정

애플리케이션이 여러 지역의 사용자에게 서비스를 제공하는 경우 각 로케일의 규칙에 따라 시간 형식을 지정합니다.

const date = new Date('2025-03-15T14:30:00');

const locales = [
  { code: 'en-US', name: 'United States' },
  { code: 'en-GB', name: 'United Kingdom' },
  { code: 'de-DE', name: 'Germany' },
  { code: 'ja-JP', name: 'Japan' }
];

locales.forEach(locale => {
  const formatter = new Intl.DateTimeFormat(locale.code, {
    hour: 'numeric',
    minute: 'numeric'
  });

  console.log(`${locale.name}: ${formatter.format(date)}`);
});

// Output:
// United States: 2:30 PM
// United Kingdom: 14:30
// Germany: 14:30
// Japan: 14:30

각 로케일은 자동으로 선호하는 형식을 사용합니다. 어떤 지역이 어떤 형식을 사용하는지 알 필요가 없습니다.

확인된 시간 주기 확인하기

resolvedOptions()를 호출하여 포매터가 실제로 사용하는 시간 주기를 확인할 수 있습니다.

const formatter = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric'
});

const options = formatter.resolvedOptions();
console.log(options.hourCycle);
// Output: "h12"

console.log(options.hour12);
// Output: true

이 메서드는 모든 로케일 기본값과 명시적 옵션을 확인한 후 포매터가 사용하는 실제 설정을 반환합니다. 반환된 객체에는 시간 구성 요소가 있는 경우 hourCyclehour12 속성이 모두 포함됩니다.

템플릿에서 시간 형식 지정

사용자에게 시간 정보를 표시하는 모든 곳에서 형식이 지정된 시간을 사용할 수 있습니다. 여기에는 HTML에 시간 삽입, 로그에 타임스탬프 표시 또는 일정 표시가 포함됩니다.

const formatter = new Intl.DateTimeFormat(navigator.language, {
  hour: 'numeric',
  minute: 'numeric'
});

const meetingTime = new Date('2025-03-15T14:30:00');
const deadlineTime = new Date('2025-03-15T17:00:00');

document.getElementById('meeting').textContent = formatter.format(meetingTime);
document.getElementById('deadline').textContent = formatter.format(deadlineTime);

형식이 지정된 문자열은 다른 문자열 값과 동일하게 작동합니다. 텍스트 콘텐츠, 속성 또는 사용자에게 정보를 표시하는 모든 컨텍스트에 삽입할 수 있습니다.

기억해야 할 사항

hour12 옵션을 사용하여 12시간 형식과 24시간 형식 간에 전환합니다. AM/PM이 포함된 12시간 형식의 경우 true로 설정하거나 24시간 형식의 경우 false로 설정합니다.

시간 번호 매기기를 정밀하게 제어하려면 hourCycle 옵션을 사용합니다. "h12" 값은 표준 12시간 형식을 제공하고 "h23"는 표준 24시간 형식을 제공합니다.

대부분의 애플리케이션에서 로케일 기본값을 존중합니다. 사용자는 해당 지역의 익숙한 형식으로 시간이 표시되기를 기대합니다. 모든 사용자에 대한 일관성이 지역 규칙 존중보다 더 중요한 경우에만 기본값을 재정의합니다.

hour12timeStyle 프리셋과 결합하여 다른 시간 구성 요소에 편리한 프리셋 스타일을 사용하면서 시간 형식을 제어합니다.