[javascript] 자바스크립트 날짜 포맷과 변환 기초 총정리

대부분의 개발 언어가 그렇지만 기본으로 표시되는 날짜 포맷이 우리나라나 동양권의 날짜 표시 방법과는 차이가 있습니다.

자바스크립트의 많은 라이브러리들과 날짜 관련 UI 프레임워크들도 마찬가지로 날짜 포맷 표현에서 우리의 년.월.일 표현 방식과는 다른 방식으로 기본적인 날짜 표현을 합니다.

그리서 간단한 것은 날짜 포맷 함수를 직접 만들어 쓰기도 하고, 널리 알려진 날짜 포매팅 라이브러리의 도움을 받기도 합니다.

자바스크립트로 날짜 포매팅을 하는 방법은 크게 3가지로 나눌 수 있습니다.

  1. 직접 날짜 포매팅 함수를 만들기
  2. 날짜 라이브러리 사용(Moment.js)
  3. Internationalization API 사용

세 번째 국제화 API는 많이 사용되지 않다보니 다소 생소할 수 있습니다. 최신 자바스크립트 코딩을 접해보지 못했으면, 처음 보는 개발자도 있을 수 있을겁니다.

두 번째 모멘트(Moment.js)는 자바스크립트 날짜 라이브러리 중 하나로 Moment.js 또는 "모멘트"라고 합니다. 가장 많이 사용하고 또 추천하는 자바스크립트 날짜 라이브러리입니다.

다국어 지원이 잘되며, 한글 및 년.월.일 방식의 어순을 잘 지원하고, "지난주 화요일 10월 5일"과 같은 표현까지 지원합니다.

가볍고 빠른데다 다른 프레임워크와 함께 사용하는데 문제가 없어서 날짜 포매팅 함수를 직접 만들어 쓸 여력이 안되면 이 라이브러리를 사용하는 것을 추천합니다.

https://momentjs.com/

 Moment.js | HomeFormat Dates moment().format('MMMM Do YYYY, h:mm:ss a'); moment().format('dddd'); moment().format("MMM Do YY"); moment().format('YYYY [escaped] YYYY'); moment().format(); Relative Time moment("20111031", "YYYYMMDD").fromNow(); moment("20120620", "YYYYMMDD"momentjs.com

간단한 한글 날짜 표현은 Internationalization API(국제화 API)를 사용하는 것을 추천합니다.

브라우저별 호환성 문제도 없고, 브라우저 내장 API로 지원되는 ECMAScript 지원 기능이기 때문에 속도가 가장 빠릅니다. 다양한 포맷 출력을 지원하지는 못하지만 다국어 지원이 잘 되기 때문에 자바스크립트 함수와 적절히 혼용해서 사용하면 효과적인 코딩이 가능합니다.

Internationalization API 호환성

1. 날짜 포매팅 함수 만들기

날짜 객체에서 년, 월, 일, 시, 분, 초, 요일 정보를 각각 얻어서 문자열 조합으로 원하는 날짜 문자열을 만듭니다.

예를 들어 다음과 같이 원하는 날짜 포매팅 함수를 만들어서 출력할 수 있습니다.

function getYmd10() {
    //yyyy-mm-dd 포맷 날짜 생성
    var d = new Date();
    return d.getFullYear() + "-" + ((d.getMonth() + 1) > 9 ? (d.getMonth() + 1).toString() : "0" + (d.getMonth() + 1)) + "-" + (d.getDate() > 9 ? d.getDate().toString() : "0" + d.getDate().toString());
}
function getFullYmdStr(){
    //년월일시분초 문자열 생성
    var d = new Date();
    return d.getFullYear() + "년 " + (d.getMonth()+1) + "월 " + d.getDate() + "일 " + d.getHours() + "시 " + d.getMinutes() + "분 " + d.getSeconds() + "초 " +  '일월화수목금토'.charAt(d.getUTCDay())+'요일';
}
console.log(getYmd10());
console.log(getFullYmdStr());

날짜 포맷 출력 함수 외에 두 날짜 사이의 차이를 계산하는 함수 등도 만들어서 사용해야 합니다.

국제화 API 도 다국어 날짜 포매팅을 하는 메서드만 제공하기 때문에 이런 연산 기능들은 직접 제작해서 사용해야 합니다.

function calcDateDiff(type, date1, date2){
	//두 날짜 사이의 간격을 type 으로 계산해 출력
    let ret = Math.abs(date1 - date2);
    switch(type){
        case 'day':
            ret /= 24;
        case 'hour':
            ret /= 60;
        case 'min':
            ret /= 60;
        case 'sec':
            ret /= 1000;
    }
    return ret;
}

let date1 = new Date(2021, 9, 1, 9, 0), date2 = new Date(2021, 9, 30, 6, 30), current = new Date();
console.log(Math.round(calcDateDiff('day', date1, date2))+'일 차이');
console.log(Math.round(calcDateDiff('hour', current, date2))+'시간 차이');

2. Moment.js 로 날짜 포매팅

다국어 표시 및 날짜 표현을 사용하려면 기본 moment.js 가 아니라 moment-with-locales.js를 사용해야 합니다.

Moment 홈페이지에서 다운로드 받아 사용할 때 주의해야 합니다.

moment.js 는 영문 출력 및 영문 날짜 어순 표시만 지원합니다.

파일을 다운로드 받아서 링크를 걸면 바로 사용할 수 있습니다.

jsdelivr에 CDN으로 올라가 있는 버전이 있으므로 특별히 Moment를 수정할 일이 없으면 CDN 링크를 가져와 사용해도 됩니다.

버전별 종류별 CDN 링크 URL은 다음 위치에서 확인할 수 있습니다.

https://www.jsdelivr.com/package/npm/moment

 jsDelivr - A free, fast, and reliable CDN for Open SourceSupports npm, GitHub, WordPress, Deno, and more. Largest network and best performance among all CDNs. Serving more than 80 billion requests per month. Built for production use.www.jsdelivr.com

사용 방법은 상당히 직관적이고 편리합니다.

먼저 사용할 로케일을 설정합니다.

moment.locale('ko');         // en - 영어

자바스크립트 최상단에 선언하면 이후에 사용하는 moment 객체의 모든 날짜 출력은 설정한 로케일로 출력됩니다.

우리가 주로 사용할 언어는 한글 날짜 출력 포매팅일 것이므로 "ko"를 로케일 인자로 설정하면 됩니다.

출력 메서드들은 상당히 방대하고 다양합니다.

모멘트 라이브러리의 날짜 출력 메서드는 format()입니다.

인자를 사용해 직접 출력 포맷을 설정할 수도 있고, 내장된 몇몇 가지 기본 포맷을 사용할 수도 있습니다.

몇 가지 예를 들면 다음과 같이 사용할 수 있습니다.

//기본 출력 포맷
console.log(moment().format(''));

//출력 포맷 설정
console.log(moment().format('YYYY년 MMMM Do, a h:mm:ss'));
console.log(moment().format('dddd'));
console.log(moment().format("YY년 MMM Do"));
console.log(moment().format('YYYY 년 MM 월 부터'));

//내장 출력 포맷
console.log(moment().format('LT'));
console.log(moment().format('LTS'));
console.log(moment().format('L'));
console.log(moment().format('l'));
console.log(moment().format('LL'));
console.log(moment().format('ll'));
console.log(moment().format('LLL'));
console.log(moment().format('lll'));
console.log(moment().format('LLLL'));
console.log(moment().format('llll'));

참고로 내장 출력 포맷의 대소문자 구분은 영문 및 알파벳 문화권을 위한 것입니다.

한글에서는 format('LLLL')과 format('llll')이 동일하게 출력되지만, 영문 환경에서는 짧은 요일(소문자)과 긴 요일(대문자)을 구분하며, 표시 순서와 구분자, 그리고 월, 일의 자릿수를 다르게 출력합니다.

내장 출력 포맷 한글 영문
LT 오전 12:25 12:25 AM
LTS 오전 12:25:30 12:25:30 AM
L 2021.10.05 10/05/2021
l 2021.10.05 10/5/2021
LL 2021년 10월 5일 October 5, 2021
ll 2021년 10월 5일 Oct 5, 2021
LLL 2021년 10월 5일 오전 12:25 October 5, 2021 12:25 AM
lll 2021년 10월 5일 오전 12:25 Oct 5, 2021 12:25 AM
LLLL 2021년 10월 5일 화요일 오전 12:25 Tuesday, October 5, 2021 12:25 AM
llll 2021년 10월 5일 화요일 오전 12:25 Tue, Oct 5, 2021 12:25 AM

모멘트는 moment() 메서드로 현재 시각을 호출합니다.

시간을 바꾸려면 moment() 메서드의 문자열 인자로 원하는 시각을 넣어서 변경할 수 있습니다.

moment("20151003", "YYYYMMDD").format('LLLL');

모멘트는 절대 시간이 아닌 상대 시간으로 표시하는 메서드들도 다양하게 지원을 합니다.

예를 들어 fromNow() 메서드는 현재 시각을 기준으로 2015년 10월 5일 날짜를 "6 년 전"과 같이 출력할 수 있습니다.

//상대 시간 표시
console.log(moment("20151003", "YYYYMMDD").fromNow(''));
console.log(moment().startOf('day'));
console.log(moment().startOf('day').fromNow(''));
console.log(moment().endOf('day').fromNow(''));
console.log(moment().startOf('hour').fromNow(''));
console.log(moment().endOf('hour').fromNow(''));

모멘트는 앞서 자바스크립트로 직접 만들어서 구현했던 날짜 연산 함수의 기능과 같은 날짜 연산 기능을 내장 메서드로 제공합니다.

console.log(moment().subtract(100, 'days').calendar(''));
console.log(moment().subtract(6, 'days').calendar(''));
console.log(moment().subtract(1, 'months').calendar(''));
console.log(moment().add(1, 'days').calendar(''));
console.log(moment().add(6, 'days').calendar(''));
console.log(moment().add(1, 'years').calendar(''));

연산 기능으로 연산된 결과 날짜는 calendar() 메서드를 사용하면 좀 더 이해하기 쉬운 문자열로 출력할 수 있습니다.

calendar() 메서드로 출력하면 어제, 내일, 지난주 수요일과 같은 친숙한 문자열로 날짜를 출력할 수 있습니다.

참고로 7일 이상 날짜는 연월일 포맷으로 출력합니다.


3. Internationalization API로 날짜 포매팅

국제화 API는 자바스크립트 내장 객체로 지원되기 때문에 별도의 라이브러리를 포함할 필요가 없습니다.

사용 객체명은 "Intl "입니다.

Moment.js 에 비해 사용 방법이 다소 번거롭고, 다양한 출력 형태를 지원하지 못하는 단점이 있습니다. 더 유연하고 다양한 날짜 출력 포맷을 필요로 하면 Moment.js를 사용하는 것이 좋습니다.

기본적인 사용방법은 다음과 같습니다.

const today = new Date();
const formattedDateKR = new Intl.DateTimeFormat("ko-KR").format(today);
console.log(formattedDateKR);

국제화 API는 2가지 포맷 출력을 지원합니다.

하나는 년-월-일 과 같은 날짜 표기 방법에 따른 로케일을 표시하도록 하는 DateTimeFormat(로케일) 메서드이고, 

다른 하나는 며칠, 몇 시간과 같은 단순 시간 단위 표현을 위한 RelativeTimeFormat(로케일) 메서드입니다.

로케일 인자를 설정할 때 주의할 점이 있는데 DateTimeFormat() 메서드는 로케일 인자로 "KO-kr"과 같이 "언어-국가" 표시로 로케일을 선택하고, RelativeTimeFormat() 메서드는 "ko"와 같이 언어만 인자로 사용합니다.

헷갈리지 않도록 주의해야 합니다.

국제화 API는 어디까지나 Date 객체를 보조하는 수단이기 때문에 날짜 정보와 연산 기능 등은 Date 객체의 것을 사용해야 합니다. 다국어 API의 주요 기능이 표시되는 시간의 표시 순서와 표시 언어를 언어/국가별로 순서를 변경해주는 것이 주요 기능이기 때문에 이 부분만 국제화 API를 활용한다고 생각하면 됩니다.

국제화 API로 날짜 표시

출력할 날짜 문자열을 생성하는 메서드는 format() 메서드입니다.

format() 메서드는 2개의 인자를 받을 수 있습니다.

첫 번째 인자는 날짜 객체입니다.

날짜 객체에 원하는 날짜를 설정한 후 format() 메서드 인자로 넘기면 문자열로 포매팅된 날짜가 출력됩니다.

두 번째 인자는 옵션 객체입니다.

옵션 객체는 정해진 키들이 있으며, 이 키에 값을 표시해서 옵션 객체를 구성한 후 인자로 넘기게 됩니다. 옵션에 대한 것은 뒤에서 설명합니다.

//기본 사용 방법
const today = new Date();
const tIntl1 = new Intl.DateTimeFormat("en-US").format(today);
const tIntl2 = new Intl.DateTimeFormat("ko-KR").format(today);
console.log(tIntl1);
console.log(tIntl2);
//상대 시간 출력
const rtIntl1 = new Intl.RelativeTimeFormat("en").format(calcDateDiff('day', date1, date2), 'day');
const rtIntl2 = new Intl.RelativeTimeFormat("ko").format(calcDateDiff('hour', current, date2), 'hour');
console.log(rtIntl1);
console.log(rtIntl2);

옵션 설정

국제환 API 표시의 옵션 설정은 옵션 객체를 통해 합니다.

옵션 객체에 사용할 수 있는 옵션 값은 미리 정해져 있으며, 다음과 같이 옵션 객체를 만들어서 인자로 넘기게 됩니다.

// 주요 옵션
const options = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric',
    fractionalSecondDigits: 3,
    hour12: false,
    weekday: 'long',
    timeZone: 'Asia/Seoul',
    calendar: 'korean'
};

//개별 설정
options.timeZone = 'UTC';
options.timeZoneName = 'long';

// 필요한 옵션만 설정
const options2 = {
    hour: 'numeric', minute: 'numeric', second: 'numeric',
    timeZone: 'America/New_york',
    timeZoneName: 'short'
};

const date = new Date();
console.log(new Intl.DateTimeFormat("ko-KR", options).format(date));
console.log(new Intl.DateTimeFormat('en-US', options2).format(date));

사용할 수 있는 값들도 정해져 있으므로, 사용할 수 있는 값 범위 안에서만 사용해야 합니다.

사용할 수 없는 값이나, 인식하지 못하는 속성 값이 있으면 다음과 같이 자바스크립트 에러를 발생시킵니다.

속성 값을 사용할 때는 사용할 수 있는 값인지 미리 확인해야 합니다.

>> javascript Date() 현재 날짜, 오늘, 어제, 전월 말일 날짜 계산과 출력 포매팅

>> javascript Date() 전전달 말일, 다음달 말일, 다음주, 윤년, 만나이, 경과 날짜 수, 날짜 연산하기