Rev. 2.73

날짜 또는 시간을 한글로 입력해 보세요

추천 단어: 오늘, 내일, 작년, 내년, 저번 달, 다음 달, 2008년 8월 12일, 10월 1일, 2009.8.15, 다음주 목요일, 저번주 수요일, 36시간 후, 5시간 전, 30분 후, 그끄저께, 그글피, 100일 후, 열흘 전, 닷세 후, 보름 전, 스무여드레, 삼십일일, 오후 5시, 16시 30분, 모레 오후 3시, 내일밤 11시, 5월 9일 밤 10시

위 예제는 일전에 소개했던 Datejs 자바스크립트 라이브러리의 한글입력 부분을 확장한 것입니다. Datejs는 영어로 입력할 때와는 달리 한글로 날짜 및 시간을 입력할 때에 나타나는 특징들이 고려되지 않는 점과 더욱 다양한 키워드를 인식하도록 보강하기 위해 이와같은 작업을 시도하게 되었습니다. 현재 진행중인 프로젝트에 위 UI를 적용시키기위한 사전작업의 일부분이기도 합니다. 원본 Datejs 라이브러리를 왜곡하지 않고 확장하는 모습으로 한글입력을 지원하기 위해 클래스를 추가하고 ko-KR.js파일을 교정하였습니다. 아래의 예제를 봅시다.

/**
 * Korean date/time format parser 
 *   for Datejs <http://www.datejs.com/>
 * 
 * @version   0.1.2a
 * @license   MIT Style
 * @author    firejune <to [at] firejune [dot] com>
 * @url       http://www.firejune.com/1343
 *
 * @usage:    Date.parseHangul(value); 
 *
 */

new (Class.create({
  initialize: function() {
    this.datePatterns = {
      '-3':/^그끄제|그끄저께/i,'-2':/^그제|그저께/i,'+2':/^모레/i,'+3':/^글피/i,'+4':/^그글피/i,
      '1':/^하루|일일/i,'2':/^이틀|이일/i,'3':/^사흘|삼일/i,'4':/^나흘|사일/i,'5':/^닷세|오일/i,
      '6':/^엿세|육일/i,'7':/^이레|칠일/i,'8':/^여드레|팔일/i,'9':/^아흐레|구일/i,
      '10':/^열흘|십일/i,'11':/^열하루|열하레|십일일/i,'12':/^열이틀|십이일/i,
      '13':/^열사흘|열산날|십삼일/i,'14':/^열나흘|열낫날|십사일/i,'15':/^보름|열닷세|십오일/i,
      '16':/^열엿세|십육일/i,'17':/^열이레|십칠일/i,'18':/^열여드레|십팔일/i,
      '19':/^열아흐레|십구일/i,'20':/^스무날|이십일/i,'21':/^스무하루|스무하레|이십일일/i,
      '22':/^스무이틀|이십이일/i,'23':/^스무사흘|이십삼일/i,'24':/^스무나흘|스무낫날|이십사일/i,
      '25':/^스무닷세|이십오일/i,'26':/^스무엿세|이십육일/i,'27':/^스무이레|이십칠일/i,
      '28':/^스무여드레|이십팔일/i,'29':/^스무아흐레|이십구일/i,'30':/^설흔날|서른날|삼십일/i,
      '31':/^서른하루|삼십일일/i
    };

    this.regex = {
      time: /[0-9]+시|[0-9]+분|[0-9]+초|오후|저녁|밤/g,
      date: /[0-9]+년|[0-9]+월|[0-9]+일/g,
      years: /[0-9]+년/i,
      months: /[0-9]+월/i,
      days: /[0-9]+일/i,
      second: /^[0-9]+초/i,
      minute: /^[0-9]+분/i,
      hour: /^[0-9]+시(간)?/i,
      pm: /^오후|저녁|밤/i,
      am: /^오전|아침/i,
      after: /(이|\s)?후/i,
      befroe: /(이|\s)?전/i
    };

    Date.parseHangul = this.analyze.bind(this);
  },
  analyze: function(value) {
    value = value.strip();
    if (!value) return null;

    var time = this.searchTime(value);
    var date = this.searchDate(value);

    if (time) {
      if (!date) {
        date = new Date();
        date = new Date(date.getFullYear(), date.getMonth() + 1, date.getDate());
      }
      date = new Date(date.getTime() + time);
    }

    return isNaN(date) ? null : date;
  },
  searchTime: function(str) {
    var pattern = str.match(this.regex.time), times = 0;
    if (pattern && pattern.length > 1 || 
      (str.match(this.regex.am) || str.match(this.regex.pm)) && str.match(this.regex.time)) {
      for (var i = 0; i < pattern.length; i++) {
        if (pattern[i].match(this.regex.pm)) times += 43200000;
        if (pattern[i].match(this.regex.hour)) times += parseInt(pattern[i]) * 3600000;
        if (pattern[i].match(this.regex.minute)) times += parseInt(pattern[i]) * 60000;
        if (pattern[i].match(this.regex.second)) times += parseInt(pattern[i]) * 1000;
      }

      return times || null;
    } else return null;
  },
  searchDate: function(str) {
    var pattern = str.match(this.regex.date);
    if (pattern && pattern.length == 3)
      for (var i = 0; i < pattern.length; i++)
        pattern[i] = parseInt(pattern[i]);
    else {
      pattern = [];
      var years = str.match(this.regex.years),
      months = str.match(this.regex.months),
      days = str.match(this.regex.days);
      
      pattern.push(years ? parseInt(years[0]) : new Date().getFullYear());
      pattern.push(months ? parseInt(months[0]) : new Date().getMonth() + 1);
      days = days ? parseInt(days[0]) : null;

      if (!days)
        for (var regex in this.datePatterns)
          if (str.match(this.datePatterns[regex])) days = regex;

      if (!days) return null;
      else if (str.match(this.regex.befroe) || str.match(this.regex.after)) {
        if (str.match(this.regex.befroe)) days = - days;
        pattern.push(new Date().getDate() + days  * 1);
      } else {
        if (typeof days == 'string' && days.match(/\+|\-/))
          days = new Date().getDate() + days * 1;
        pattern.push(days);
      }
    }

    return new Date(pattern[0], pattern[1] - 1, pattern[2]);
  }
}))();

Examples:

var input = $('input'), result = $('result');
var parsed = Date.parseHangul(input.value) || Date.parse(input.value);
result.innerHTML = parsed.toString(Date.CultureInfo.formatPatterns.fullDateTime);

Downloads:

* original - date.js (31.06kb)
* minified - date.js (30.00kb)

Updates:

* 모레, 글피, 그글피 키워드의 날짜 계산 오류를 수정하였습니다.
* "오후 5시"와 같은 시간 값을 사용할 수 있습니다.

Comments

Got something to add? You can just leave a comment.

  • 예전에 봐뒀던 좋은 스크립트인데 한글지원이 아쉬웠는데 멋집니다. =_=b
    스토리엔에 적용되는거군요. +_+

    reply edit

  • 네, 충분한 테스트를 거쳐 적용시킬 예정입니다.

    reply edit

  • 한글로 구현되는 것은 처음 봤습니다..+_+

    reply edit

  • 구글 캘린더 외 기타 캘린더 웹서비스에서 일부 구현되어 있기도 합니다. 구글 캘린더에서 "오후 5시에 누구와 저녁식사"라는 일정을 생성하면 오후 5시를 시간값으로 인식하는 것이죠. 요것이 의외로 편리합니다.

    reply edit

  • datajs 라길래 또다른 라이브러리인줄 알았습니다 ㅎㅎ 제목에 오타가 있네요 ;) datajs -> datejs

    reply edit

  • 헉!

    reply edit

  • Shrek Shrek

    오후5 -->2008년 11월 22일 토요일 오후 12:00:00
    오후5시 --> 2008년 11월 22일 토요일 오후 5:00:00
    오후15시 --> 2008년 11월 23일 일요일 오전 3:00:00

    아놔 ㅋㅋ 기획자 같아 , 날짜 수정하셔야 할 듯 한데요

    reply edit

  • ㅎㅎ 고맙습니다. 오류 구분 규칙 만드는 것이 귀찮아서요;; 시간나면 추가해 보도록 하겠습니다.

    reply edit

  • 오늘 오전 4시 -> 안되요~ㅎㅎ

    reply edit

  • oneman oneman

    안녕하세요. 파이어준님... 다름아니라 예전에 우연히 이곳을 알게 되었고.. 가끔 둘러보는데요..

    둘러볼때마다 느끼는데... 블로그 많이 보았지만 여기만큼 잘 만들어 진곳은 못보았습니다..

    뭐라고 해야할까... 다른 블로그가 32bit 싱글이라면 여긴 64bit 듀얼 이랄까요 ??

    그정도로 마치.. 다른 차원의 세계를 보는거 같아요...


    저도 블로그를 하나 만들어서 파이어준님처럼 여러 용도로 사용하려는데요...

    이곳과 똑같이 꾸미려면 얼마나 걸릴까요 ?? 소스를 다 여기저기에서 공개된 것을 구하셔서

    만드신건지.. 아니면 직접 개발하신건지... 여러가지 유용한 기능이 너무 많네요...

    블로그를 이곳과 똑같이 만들고 싶은데.. 혹시 도와주시거나 조언해 주실게 있다면 감사하겠습니다..

    텍스트큐브로 꾸미려는데.. 잘될런지 모르겠네요...


    방명록에 남기려고 했는데.. 닫혀있더군요.. 그래서 가장 최근글에 답글로 남깁니다..

    읽어주셔서 감사합니다~

    reply edit

  • 글쎄요.. 블로그를 오픈한지 4년차 이지만 지금까지도 커스토마이징을 지속적으로 해오고 있어서 섣불리 말씀드리기가 모호하네요. 블로깅 도구로 볼때 전체적인 완성도를 객관적으로 평가하라면 약 30%정도 되는것 같습니다.

    reply edit

Your Reaction Time!

captcha

avatar