우선 생각난김에 만들어봤는데.. 잘못된 부분이 있을지도 모르겠다.
(우선은 잘 동작한다. 하지만 약 1시간만에 만든거라(ISO 문서 및 Date객체에 대한 검색 시간 포함이라 -_-a).. 부족할 수도 있다. 즉, 발로 만들었으므로 약간의 검증이 필요하다고 보면 된다.)
JSON 에서 날짜는 ISO 8601 형식을 따른다고 한다.
보통,
http://www.w3.org/TR/NOTE-datetime Year: YYYY (eg 1997) Year and month: YYYY-MM (eg 1997-07) Complete date: YYYY-MM-DD (eg 1997-07-16) Complete date plus hours and minutes: YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00) Complete date plus hours, minutes and seconds: YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) Complete date plus hours, minutes, seconds and a decimal fraction of a second YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
와 같이 쓰인다고 하는데.
Prototype 1.5.1의 Date.toJSON()에서 보면, hh:mm이 붙는 시간에도 UTC 정보는 붙지 않는다.
이건.. global 한 웹 프로젝트라면 문제가 될 수 있겠다. 아마도 UTC 정보가 붙도록 곧 패치 되겠지?
(서버에서 보낸 시간을 클라이언트에서 처리 할 때, 서로 UTC 시간이 다르다면 시간이 맞지 않을 수 있다)
(주 - 물론 이건 제가 몰라서 하는 소리일 수도 있으니, 만약 UTC가 명시되어 있지 않을 경우 N(UTC+0000)이 기본값이 된다던가.. 이런게 있다면 알려주시면 감사하겠습니다.)
function getDateFromJSON(str)
{
var exp = /(\d\d\d\d)(-\d\d)?(-\d\d)?((T\d\d)(:\d\d))?((:\d\d)(\.\d\d\d?)?)?(N|[-+](\d\d):(\d\d))?/;
// tokens에서 해당 property에 속하는 값을 구하기 위한 index의 배열
var tokenIndexs = {
FullYear: [1],
Month: [2],
Date: [3],
Hours: [5, 11],
Minutes: [6, 12],
Seconds: [8],
Milliseconds: [9]
};
var tokens;
tokens = str.match(exp);
// 처리 전의 tokens (=> 변경 후)
// tokens[0]: 전체
// tokens[1]: YYYY
// tokens[2]: -MM (=> MM)
// tokens[3]: -DD (=> DD)
// tokens[4]: Thh:mm
// tokens[5]: Thh (=> hh)
// tokens[6]: :mm (=> mm)
// tokens[7]: :ss.sss
// tokens[8]: :ss (=> ss)
// tokens[9]: .sss (=> sss)
// tokens[10]: TZD (-??:??, +??:??, Z)
// tokens[11]: TZD시간 (-, +일 경우)
// tokens[12]: TZD분 (-, +일 경우)
tokens[2] = tokens[2].replace('-', '');
tokens[3] = tokens[3].replace('-', '');
tokens[5] = tokens[5].replace('T', '');
tokens[6] = tokens[6].replace(':', '');
tokens[8] = tokens[8].replace(':', '');
tokens[9] = tokens[9].replace('.', '');
// Date객체에 값을 사용하기 위해 보정한다
// month의 경우 0-based이므로 1 감소한다
tokens[2] = Math.max(parseInt(tokens[2], 10) - 1, 0);
// TZD 시간과 분은 나중에 delta 만큼 감소해야 하므로
tokens[11] = -1 * parseInt(tokens[11], 10);
tokens[12] = -1 * parseInt(tokens[12], 10);
// 반환할 객체를 생성한다
var ret = new Date(0);
// tokenIndex를 참조하여, 날짜 및 시간을 설정한다
for(var index in tokenIndexs)
{
var values;
var final_value;
values = tokenIndexs[index];
final_value = 0;
// 한개의 값을 구하기 위해 여러개의 값을 참고해야 될 경우에 모두 더한다
// 보통 UTC 시간이나 분을 보정하기 위해 사용한다
for(var valueIndex in values)
{
var token_value;
token_value = tokens[values[valueIndex]];
if(token_value)
{
final_value += parseInt(token_value, 10);
}
}
if(tokens[10])
{
// UTC 정보가 있다면
ret['setUTC' + index](final_value);
}
else
{
// UTC 정보가 없다면 local 시간으로 등록한다
ret['set' + index](final_value);
}
}
return ret;
}소스 코드가 복잡한건 없다. 그냥 파싱한담에 UTC정보 계산해서 시간을 설정해주는거다.
다만 setUTC~()와 set~()의 다른점은 setUTC~()를 호출해야 UTC+0000 시간에 맞추어 시간을 설정할 수 있다는것이다. 굳이 setUTC~()를 사용하고 싶지 않다면 local의 UTC시간을 얻어와서 그 시간과 JSON 문자열에 나타난 UTC시간을 계산해서 반영할 수도 있다. 하지만 난 굳이 삽질하기 싫어서 패스.
Posted by 장현준


