LHJ

I'm a FE developer.

15.6 날짜 데이터 전송하기

22 May 2020 » js_lj

15.6 날짜 데이터 전송하기

서버에서 브라우저로 날짜를 전송하거나, 반대로 브라우저에서 서버로 날짜를 전송할 때는 조금 복잡할 수 있습니다.
서버와 브라우저가 다른 타임존에 있더라도 사용자는 자신의 타임존을 기준으로 날짜를 보고 싶어할 겁니다.
다행히 자바스크립트의 Date 인스턴스는 날짜를 저장할 때 UTC를 기준으로 유닉스 타임스탬프를 저장하므로, Date 객체를 그냥 전송해도 일반적으로 안전합니다.

자바스크립트에서 날짜를 전송하는 가장 확실한 방법은 JSON을 사용하는 겁니다.
날짜는 JSON에서 1:1 대칭이 되게끔 파싱할 수 없으므로 JSON 명세에는 날짜에 대한 데이터 타입을 정의하지 않았습니다.

const before = { d: new Date() };
before.d instanceof Date;               // true
const json = JSON.stringify(before);
const after = JSON.parse(json);
after.d instanceof Date;                // false
typeof after.d                          // "string"

즉, JSON으로 바로 날짜를 다룰 수는 없지만, 전송된 문자열에서 날짜를 ‘복구’하는 것은 가능합니다.

after.d = new Date(after.d);
after.d instanceof Date         // true

원래 날짜가 어느 타임존에 있었든, 일단 JSON으로 인코드된 날짜는 UTC입니다.
그리고 JSON으로 인코드된 문자열을 Date 생성자에 넘겨서 얻은 날짜는 사용자의 타임존 기준으로 표시됩니다.

문자열로 인코드하지 않고 valueOf() 메서드로 얻은 숫자를 그냥 전송해도 됩니다.

const before = { d: new Date() };
before.d instanceof Date;               // true
const json = JSON.stringify(before);
const after = JSON.parse(json);
after.d instanceof Date;                // false
typeof after.d                          // "string"

///////////////////////////////////////////////////

const before = { d: new Date().valueOf() };
typeof before.d                 // "number"
const json = JSON.stringify(before);
const after = JSON.parse(json);
typeof after.d                  // "number"
const d = new Date(after.d);

CAUTION_
자바스크립트에서는 JSON으로 인코드된 날짜 문자열을 일관되게 처리하지만, 다른 언어나 운영체제에서 제공하는 JSON 라이브러리는 그렇지 않습니다.
특히 .NET JSON 직렬화기는 JSON으로 인코드된 날짜 객체를 자신만의 형식으로 감싸(wrap)버립니다.
따라서 자바스크립트가 아닌 다른 시스템과 날짜 데이터를 주고받을 때는 그 시스템에서 날짜를 어떻게 직렬화하는지 알아둬야 합니다.
이런 상황에서는 유닉스 타임스탬프를 주고받는 편이 더 안전합니다.
하지만 유닉스 타임스탬프를 주고받을 때도 한 가지 조심할 것이 있습니다.
숫자형 값을 밀리초가 아니라 초 기준으로 해석하는 라이브러리도 많습니다.