// Format: INT DATE (phrase) protected static string ParseIntDate(GDMDateInterpreted date, GEDCOMParser strTok) { strTok.SkipWhitespaces(); if (!strTok.RequireWord(GDMCustomDate.INT)) { throw new GEDCOMIntDateException(strTok.GetFullStr()); } strTok.Next(); ParseDate(date, strTok); strTok.SkipWhitespaces(); var token = strTok.CurrentToken; if (token == GEDCOMToken.Symbol && strTok.GetSymbol() == '(') { var phrase = new StringBuilder(); phrase.Append(strTok.GetWord()); do { token = strTok.Next(); phrase.Append(strTok.GetWord()); } while (token != GEDCOMToken.Symbol || strTok.GetSymbol() != ')'); date.DatePhrase = phrase.ToString(); } else { date.DatePhrase = string.Empty; } return(strTok.GetRest()); }
// Format: FROM DATE1 TO DATE2 protected static string ParsePeriodDate(GDMDatePeriod date, GEDCOMParser strTok) { strTok.SkipWhitespaces(); if (strTok.RequireWord(GDMCustomDate.FROM)) { strTok.Next(); ParseDate(date.DateFrom, strTok); strTok.SkipWhitespaces(); } if (strTok.RequireWord(GDMCustomDate.TO)) { strTok.Next(); ParseDate(date.DateTo, strTok); strTok.SkipWhitespaces(); } return(strTok.GetRest()); }
// Format: AFT DATE | BEF DATE | BET AFT_DATE AND BEF_DATE protected static string ParseRangeDate(GDMDateRange date, GEDCOMParser strTok) { strTok.SkipWhitespaces(); var token = strTok.CurrentToken; if (token != GEDCOMToken.Word) { // error! } string su = strTok.GetWord(); int dateType = Algorithms.BinarySearch(GDMCustomDate.GEDCOMDateRangeArray, su, string.CompareOrdinal); if (dateType == 0) // "AFT" { strTok.Next(); ParseDate(date.After, strTok); } else if (dateType == 1) // "BEF" { strTok.Next(); ParseDate(date.Before, strTok); } else if (dateType == 2) // "BET" { strTok.Next(); ParseDate(date.After, strTok); strTok.SkipWhitespaces(); if (!strTok.RequireWord(GDMCustomDate.GEDCOMDateRangeArray[3])) // "AND" { throw new GEDCOMRangeDateException(strTok.GetFullStr()); } strTok.Next(); strTok.SkipWhitespaces(); ParseDate(date.Before, strTok); } return(strTok.GetRest()); }
// DateValue format: INT/FROM/TO/etc..._<date> protected static string ParseDateValue(GDMDateValue dateValue, string str) { if (str == null) { return(string.Empty); } var strTok = new GEDCOMParser(str, false); strTok.SkipWhitespaces(); int idx = 0; var token = strTok.CurrentToken; if (token == GEDCOMToken.Word) { string su = strTok.GetWord(); idx = Algorithms.BinarySearch(GDMCustomDate.GEDCOMDateTypes, su, string.CompareOrdinal); } var dateType = (idx < 0) ? GEDCOMDateType.SIMP : (GEDCOMDateType)idx; string result; GDMCustomDate date; switch (dateType) { case GEDCOMDateType.AFT: case GEDCOMDateType.BEF: case GEDCOMDateType.BET: date = new GDMDateRange(); result = ParseRangeDate((GDMDateRange)date, strTok); break; case GEDCOMDateType.INT: date = new GDMDateInterpreted(); result = ParseIntDate((GDMDateInterpreted)date, strTok); break; case GEDCOMDateType.FROM: case GEDCOMDateType.TO: date = new GDMDatePeriod(); result = ParsePeriodDate((GDMDatePeriod)date, strTok); break; default: date = new GDMDate(); result = ParseDate((GDMDate)date, strTok); break; } dateValue.SetRawData(date); return(result); }
// Format: [ <YEAR>[B.C.] | <MONTH> <YEAR> | <DAY> <MONTH> <YEAR> ] (see p.45-46) protected static string ParseDate(GEDCOMParser strTok, out GDMApproximated approximated, out short year, out bool yearBC, out string yearModifier, out byte month, out byte day) { approximated = GDMApproximated.daExact; year = GDMDate.UNKNOWN_YEAR; yearBC = false; yearModifier = string.Empty; month = 0; day = 0; strTok.SkipWhitespaces(); var token = strTok.CurrentToken; // extract approximated token = strTok.CurrentToken; if (token == GEDCOMToken.Word) { string su = InvariantTextInfo.ToUpper(strTok.GetWord()); int idx = Algorithms.BinarySearch(GDMCustomDate.GEDCOMDateApproximatedArray, su, string.CompareOrdinal); if (idx >= 0) { approximated = (GDMApproximated)idx; strTok.Next(); strTok.SkipWhitespaces(); } } // extract day token = strTok.CurrentToken; int dNum; if (token == GEDCOMToken.Number && strTok.TokenLength() <= 2 && ((dNum = strTok.GetNumber()) <= 31)) { day = (byte)dNum; token = strTok.Next(); } // extract delimiter if (token == GEDCOMToken.Whitespace && strTok.GetSymbol() == ' ') { token = strTok.Next(); } // extract month if (token == GEDCOMToken.Word) { // in this case, according to performance test results, BinarySearch is more efficient // than a simple search or even a dictionary search (why?!) string su = InvariantTextInfo.ToUpper(strTok.GetWord()); int idx = BinarySearch(GDMCustomDate.GEDCOMMonthValues, su, string.CompareOrdinal); month = (byte)((idx < 0) ? 0 : idx); token = strTok.Next(); } // extract delimiter if (token == GEDCOMToken.Whitespace && strTok.GetSymbol() == ' ') { token = strTok.Next(); } // extract negative years if (token == GEDCOMToken.Symbol && strTok.GetSymbol() == '-') { yearBC = true; token = strTok.Next(); } // extract year if (token == GEDCOMToken.Number) { year = (short)strTok.GetNumber(); token = strTok.Next(); // extract year modifier if (token == GEDCOMToken.Symbol && strTok.GetSymbol() == GDMCustomDate.YearModifierSeparator) { token = strTok.Next(); if (token != GEDCOMToken.Number) { // error } else { yearModifier = strTok.GetWord(); } token = strTok.Next(); } // extract bc/ad if (token == GEDCOMToken.Word && strTok.GetWord() == "B") { token = strTok.Next(); if (token != GEDCOMToken.Symbol || strTok.GetSymbol() != '.') { // error } token = strTok.Next(); if (token != GEDCOMToken.Word || strTok.GetWord() != "C") { // error } token = strTok.Next(); if (token != GEDCOMToken.Symbol || strTok.GetSymbol() != '.') { // error } strTok.Next(); yearBC = true; } } token = strTok.CurrentToken; if (day > 0 && month == 0 && year == GDMDate.UNKNOWN_YEAR) { year = day; day = 0; } //date.SetRawData(approximated, calendar, year, yearBC, yearModifier, month, day, dateFormat); string result = strTok.GetRest(); return(result); }