0

我有一个包含大量个人/家庭记录的输入 GEDCOM 文件。目的是将他们的数据格式化成这种形式:

名称(p6,“哈利·布伊斯”)。出生(p6,日期(1927,11,17))。死亡(p6,日期(2001,08,21))。famc(p6,f3)。家族(p6,f2)。

我已经能够提取人员编号和他们的姓名并将其打印到输出文件中,但是我无法解析出生/死亡日期。我希望能够使用子字符串将birthDay、birthMonth 和BirthYear 分配为整数,以便将其打印到输出文件中。它必须是整数,所以我可以按日期排序。这是来自输入文件的一个客户数据的示例。

0 @P6@ 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 @F3@
1 FAMS @F2@

这是我到目前为止的源代码:

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() 方法中没有“birthDay”,我的输出如下所示:

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').

这是一个好的开始。

但是当我有那个 if 语句时,我得到一个这样的错误,并且没有打印:

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)

现在,我已经尝试了子字符串索引值的每种组合,但似乎没有任何效果。关于我如何解决这个问题的任何想法?

提前致谢。

4

2 回答 2

0

我建议你使用 Date 函数。日期函数的排序比年/月/日更容易。如果你真的想要,将它们存储为自纪元以来的毫秒数。

要解析日期,请使用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 指的是开始字符串的索引,所以你可以指定格式开始的索引,你很好。总的来说,我认为这更清洁。

于 2014-11-13T23:29:33.437 回答
0

从 GEDCOM 文件中解析日期很棘手。您可以将 SimpleDateFormatter 用于 dd MMM yyyy 格式的任何日期(例如 2015 年 9 月 26 日),但 GEDCOM 支持许多奇怪的变化,包括您只有月份和年份或只有年份的不精确日期。它还允许使用诸如“ABT”之类的前缀来表示在特定日期附近发生的事情,允许范围(“BET date1 AND date2”)和(“FROM date1 TO date2”),以及许多其他复杂的行为(法国共和党人或希伯来日历,有人吗?)

我建议使用 gedcom4j ( http://gedcom4j.org ),它是一个 Java 库,您可以链接到您的程序中以将数据加载到 Java 对象中,然后执行您需要的操作。该库中的 DateParser 类可以解释您的字符串值并将它们转换为 java.util.Date 值,以便您可以执行您所描述的操作。

于 2016-07-23T13:07:19.120 回答