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