Prototype를 공부하면서.. Date객체에 .toJSON은 있는데, 왜 .fromJSON은 없을까? 하는 의문이 들었다.
우선 생각난김에 만들어봤는데.. 잘못된 부분이 있을지도 모르겠다.
(우선은 잘 동작한다. 하지만 약 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시간을 계산해서 반영할 수도 있다. 하지만 난 굳이 삽질하기 싫어서 패스.
크리에이티브 커먼즈 라이센스
Creative Commons License

Posted by 장현준

2007/08/24 14:41 2007/08/24 14:41
, , ,
Response
No Trackback , a comment
RSS :
http://b4you.net/blog/rss/response/133


블로그 이미지

빗소리를 먹는 사람.

- 장현준

Notices

Archives

Authors

  1. 장현준

Recent Trackbacks

  1. 듀얼클러치의 생각 rsvin28's me2DAY 2009

Calendar

«   2012/02   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

Site Stats

Total hits:
158009
Today:
79
Yesterday:
228