2013-05-13 2 views
1

문자열에서 의미있는 날짜와 시간을 구문 분석하는 프로그램을 만들려고합니다. 나는 날짜/시간 객체를 입력 다음과 같은 종류의 정보를 제공하고, 만들 수 있도록하려면 :문자열에서 날짜/시간을 파싱 하시겠습니까?

5 o'clock 
5 p.m. 
5 a.m. 
5 
530 
530 a.m. 
530 p.m. 
Tuesday at [insert any above string here] 
the 30th at [same as above] 
May 12th at [same as above] 
today at [same as above] 
tomorrow at [same as above] 

오늘날 것으로 가정 할 수있는 일/날짜를 포함하지 않는 모든 문자열, 언제든지 그 오후 9 시부 터 오후 8시 59 분 사이에 AM/PM 지정이없는 것으로 가정 할 수 있습니다.

private void createEvent(String phrase) { 
    int hour; 
    int day = 0; 
    String dayOfWeek = ""; 

    if (phrase.contains("o'clock")) { 
     hour = Integer.parseInt(phrase.substring(phrase.indexOf("o'clock")-3, phrase.indexOf("o'clock")-1).trim()); 
     out.write(""+hour); 
    } 

    if (phrase.contains("tomorrow")) 
     day = (Calendar.DAY_OF_WEEK % 7)+1; 

    if (phrase.contains("sunday") || day == 1) { 
     dayOfWeek = "Sunday"; day = 1; } 
    else if (phrase.contains("monday") || day == 2) { 
     dayOfWeek = "Monday"; day = 2; } 
    else if (phrase.contains("tuesday") || day == 3) { 
     dayOfWeek = "Tuesday"; day = 3; } 
    else if (phrase.contains("wednesday") || day == 4) { 
     dayOfWeek = "Wednesday"; day = 4; } 
    else if (phrase.contains("thursday") || day == 5) { 
     dayOfWeek = "Thursday"; day = 5; } 
    else if (phrase.contains("friday") || day == 6) { 
     dayOfWeek = "Friday"; day = 6; } 
    else if (phrase.contains("saturday") || day == 7) { 
     dayOfWeek = "Saturday"; day = 7; } 
    else { 
     dayOfWeek = "Today"; day = 0; }  
} 

사람이 어떤 방향을 제공 할 수 있습니다 : 나는 빨리이 코드의이 부분을 작성 후지고 있었는지 엉망 실현?

+1

나는 각 경우에 seperatly에 집중할 것이고, 아마도 기본 목적을 위해 간단한 'Formatter'를 만들 것이다. 그것들을 모두 중앙의'FormatFactory'에 추가하십시오. 이렇게하면 필요할 때 포매터를 늘릴 수 있습니다 (또는 필요한 경우 일부 제외). – MadProgrammer

+0

문자열에있을 가능성이있는 것은 무엇입니까? 전체 문자열은 시간과 관련이 있거나 일부 정보에 다른 정보가 포함될 수 있습니까? 예 : "5시에 역에서 만나자" – GHC

답변

3

당신은 다음 구문 분석 날짜를 비교, 어쩌면 당신은 사전에 몇 가지 형식을 만들 수 DateFormat의

String now = new Date().toString(); 
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); 
Date date = format.parse(now); 

사용할 수 있습니다. 여기

체크 튜토리얼 : http://www.xyzws.com/Javafaq/how-to-use-simpledateformat-class-formating-parsing-date-and-time/142

+0

"a.m."을 구문 분석하지 않습니다. 또는 "p.m." 그리고 "내일"은 어떨까요? – MadProgrammer

+0

문자열 형식에 제한이없는 경우 모든 상황을 처리하는 코드를 작성하는 것은 불가능합니다. 사용자가 입력 한 모든 것을 파싱하고 싶다면 자연어 처리에 문제가 될 것입니다 ... – ltebean

+0

다음으로 많이 말하십시오. – MadProgrammer

2
가 관리 덩어리로 아래로 문제를 휴식

... 난 당신이 필요로하는 새로운 포매터를 추가 할 수있는 수단을 제공함으로써 시작할 것

.

기존 코드를 재사용 할 수도 있습니다. 시간은 문제에 대해 꽤 일관된 측면입니다.

이것은 (쉽게 관리 할) 어떤 종류의 중앙 형식 공장을 제공하는 개념으로 나를 인도하지만, 작은 관리 덩어리

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.List; 

public class CustomDateFormatter { 

    public static void main(String[] args) { 
     new CustomDateFormatter(); 
    } 

    public CustomDateFormatter() { 

     String values[] = new String[]{ 
      "5 o'clock", 
      "5 p.m.", 
      "5 a.m.", 
      "5", 
      "530", 
      "530 a.m.", 
      "530 p.m.",}; 

     for (String value : values) { 
      System.out.println(value + " = " + CustomFormatFactory.format(value)); 
     } 
    } 

    public static class CustomFormatFactory { 

     private static List<CustomFormat> formatters = new ArrayList<>(); 

     public static Date format(String value) { 
      Date date = null; 
      for (CustomFormat format : formatters) { 
       if (format.canFormat(value)) { 
        date = format.format(value); 
        if (date != null) { 
         break; 
        } 
       } 
      } 
      return date; 
     } 

     protected static boolean formatTime(String value, Calendar cal) { 
      boolean formatted = false; 
      if (Character.isDigit(value.charAt(0))) { 
       formatted = true; 
       StringBuilder timePart = new StringBuilder(4); 
       int index = 0; 
       while (index < value.length() && Character.isDigit(value.charAt(index))) { 
        timePart.append(value.charAt(index)); 
        index++; 
       } 

       int hour = 0; 
       int min = 0; 
       if (timePart.length() < 3) { 
        hour = Integer.parseInt(timePart.toString()); 
       } else { 
        hour = Integer.parseInt(timePart.substring(0, timePart.length() - 2)); 
        min = Integer.parseInt(timePart.substring(timePart.length() - 2, 3)); 
       } 

       cal.set(Calendar.HOUR_OF_DAY, hour); 
       cal.set(Calendar.MINUTE, min); 
       cal.set(Calendar.MILLISECOND, 0); 

       String sufix = value.substring(timePart.length()).trim(); 
       if ("p.m.".equalsIgnoreCase(sufix) || "pm".equalsIgnoreCase(sufix)) { 
        cal.add(Calendar.HOUR, 12); 
       } 
      } 
      return formatted; 
     } 

     static { 
      formatters.add(new SimpleTimeFormat()); 
     } 
    } 

    public static interface CustomFormat { 

     public boolean canFormat(String value); 

     public Date format(String value); 
    } 

    public static class SimpleTimeFormat implements CustomFormat { 

     @Override 
     public boolean canFormat(String value) { 
      return format(value) != null; 
     } 

     @Override 
     public Date format(String value) { 
      Date date = null; 
      Calendar cal = Calendar.getInstance(); 
      if (CustomFormatFactory.formatTime(value, cal)) { 
       date = cal.getTime(); 
      } 
      return date; 
     } 
    } 
} 
확장 된 날짜 형식에 대한

로 개별 요구 사항을 무너 뜨리는 것 나는 날짜 부분을 추출하고 날짜를 기반으로 Calendar을 빌드하고 별도의 String으로 시간 파티션을 추출하고 시간을 포맷하기 위해 CustomFormatFactory.formatTime 메소드를 사용하므로 매번 다시 코딩해야하는 번거 로움을 덜어줍니다.

동등하게, 날짜 포맷터는 시간 형식화 프로그램의 인스턴스를 내부적으로 가질 수도 있고 여러 시간 형식을 사용하고 사용 가능한 시간 포맷터를 반복하는 여러 형식 메소드를 갖도록 팩토리를 설정할 수 있습니다.)

관련 문제