2014-11-13 6 views
0

개인/가족 기록이 많은 입력 GEDCOM 파일이 있습니다. 그 목적은 데이터를 다음 형식으로 포맷하는 것입니다 :GEDCOM 파일 읽기 : 입력 파일에서 출력 파일로 정수 변수로 해당 생일, 월, 일을 부분 문자열로 변환하는 방법

이름 (p6, 'Harry Buis'). 출생 (p6, 날짜 (1927,11,17)). 사망 (p6, 날짜 (2001,08,21)). famc (p6, f3). fams (p6, f2).

나는 사람 번호와 이름을 꺼내 출력 파일에 인쇄 할 수 있지만 출생/사망일을 파싱하는 데 문제가 있습니다. 하위 문자열을 사용하여 birthDay, birthMonth 및 BirthYear를 정수로 할당하여 출력 파일에 인쇄 할 수 있기를 원합니다. 날짜별로 정렬 할 수 있도록 정수 여야합니다. 다음은 입력 파일의 한 클라이언트 데이터 샘플입니다.

0 @[email protected] INDI 
1 BIRT 
2 DATE 17 Nov 1924 
1 NAME Harry /Buis/ 
1 DEAT Age: 76 
2 DATE 21 Aug 2001 
1 SEX M 
1 FAMC @[email protected] 
1 FAMS @[email protected] 

그리고 여기가 내가 지금까지 무엇을 내 소스 코드 :

public class Main { 

static Scanner scan; 
static BufferedWriter outFile; 
static int birthYear = 0; 
static int birthMonth = 0; 
static String birthDay = ""; 
static int deathYear = 0; 
static int deathMonth = 0; 
static int deathDay = 0; 
static String name = ""; 
static String person = ""; 
static String sex = ""; 
static String famC = ""; 
static String famS = ""; 
static String man = ""; 
static String woman = ""; 
static String child = ""; 

public static void parse() throws IOException { 
    scan = new Scanner(new FileReader("pbuis.ged")); 
    outFile = new BufferedWriter(new FileWriter("output.txt")); 
    String reader = scan.nextLine(); 
    int count = 0; 

    while (scan.hasNextLine()) { 

     if (reader.contains("NAME") && count < 1) { 
      reader = reader.substring(1).replace("/", ""); 
      count++; 
      System.out.println(reader); 
      name = reader.replace("NAME", ""); 
     } 

     if (reader.startsWith("0")) { 
      person = reader.trim().substring(2, 7).replace("@", "") 
        .replace("I", "").trim().toLowerCase(); 
      System.out.print(person); 
      count = 0; 
     } 

     if (reader.contains("BIRT")) { 
      scan.nextLine(); 
      birthDay = Integerreader.substring(6, 9).trim(); 
     } 

     if (reader.equalsIgnoreCase("") || reader.equalsIgnoreCase(" ")) { 
      outFile.write("name(" + person + ", " + "'" + name.trim() + "'" 
        + ")." + "\n" + birthDay); 

     } 

     reader = scan.nextLine(); 
    } 
} 

public static void main(String[] args) throws IOException { 
    parse(); 

} 

}

은 if 문없이, 그리고 "생일"("BIRT"를 포함)하지의 outFile.write() 메소드를 사용하면 출력 결과는 다음과 같습니다.

name(p1, 'Paul Edward Buis'). 
name(p2, 'Thomas Edward Buis'). 
name(p3, 'Jennifer Joy Buis'). 
name(p4, 'Daniel Paul Buis'). 
name(p5, 'Barbara Joy VanderWall'). 
name(p6, 'Harry Buis'). 

좋은 시작입니다.

하지만 문 경우, 나는이 같은 오류가 발생하는 것을 가지고 있고, 아무 것도 인쇄 할 때 : 이제

p1Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 9 
    at java.lang.String.substring(Unknown Source) 
    at Main.parse(Main.java:50) 
    at Main.main(Main.java:64) 

, 나는 인덱스 값을 substringing의 모든 조합을 시도하고, 아무것도 작동하는 것 같다 없습니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

미리 감사드립니다.

답변

0

날짜 기능을 사용하는 것이 좋습니다. 날짜 기능은 년/월/일보다 쉽게 ​​정렬 할 수 있습니다. 정말로 원한다면, 그 시대로부터의 밀리 세컨드 단위로 저장하십시오.

날짜를 구문 분석하려면 SimpleDateFormatter을 사용하십시오. 나는 이런 식으로 뭔가가 작동합니다 생각 :

SimpleDateFormatter dateFormat=new SimpleDateFormat("dd mmm yyyy") 
Date birth=date.parse("17 jul 1984",0); 

하나는 당신이 날짜 형식으로 그것을 얻을, 당신은 다음과 같은 깔끔한 많은 것들을 할 수 있습니다

Date date1, date2; 
date1.after(date2); 
date1.compareTo(date2) 

심지어 분을 얻을 수 또는 초,하지만 나는 그것을 권장하지 않습니다. 0은 문자열을 시작하는 색인을 참조하므로 형식이 시작되는 색인 만 지정하면됩니다. 전반적으로, 나는 이것이 훨씬 깨끗하다고 ​​생각한다.

+0

와우 나는 그 존재를 전혀 몰랐다. 감사! 나는 그것을 시도 할 것이다. –

0

GEDCOM 파일의 날짜 구문 분석은 까다 롭습니다. SimpleDateFormatter는 dd MMM yyyy 형식 (예 : 2014 년 9 월 20 일)으로 사용할 수 있지만 GEDCOM은 월 및 연도 또는 연도 만있는 부정확 한 날짜를 비롯한 많은 이상한 변형을 지원합니다. 또한 "ABT"와 같은 접두사를 사용하여 특정 날짜 주변에 무언가가 발생했음을 나타낼 수 있으며 범위 ("BET 날짜 1 및 날짜 2") 및 ("FROM date1 TO date2") 및 기타 복잡한 동작 (프랑스 공화당 또는 히브리어 달력, 누구?)

Java 라이브러리에있는 gedcom4j (http://gedcom4j.org)를 사용하여 데이터를 Java 객체에로드 한 다음 필요한 것을 수행 할 수있는 프로그램에 연결할 수 있습니다. 해당 라이브러리의 DateParser 클래스는 문자열 값을 해석하고 java.util.Date 값으로 변환하여 설명하는 것을 수행 할 수 있습니다.