From: cesarvh Date: Thu, 29 Nov 2018 21:57:32 +0000 (-0800) Subject: UJ-47: Added roman numeral months X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=89595839b482c20f3e76d97487d6245b7a0f307e;p=tmp%2Fjakarta-migration.git UJ-47: Added roman numeral months --- diff --git a/services/structureddate/structureddate/src/main/antlr4/org/collectionspace/services/structureddate/antlr/StructuredDate.g4 b/services/structureddate/structureddate/src/main/antlr4/org/collectionspace/services/structureddate/antlr/StructuredDate.g4 index fca4433b6..e3b608f80 100644 --- a/services/structureddate/structureddate/src/main/antlr4/org/collectionspace/services/structureddate/antlr/StructuredDate.g4 +++ b/services/structureddate/structureddate/src/main/antlr4/org/collectionspace/services/structureddate/antlr/StructuredDate.g4 @@ -108,8 +108,8 @@ monthInYearRange: strMonth ( HYPHEN | DASH ) strMonth COMMA? numYear era? ; nthQuarterInYearRange: nthQuarter ( HYPHEN | DASH ) nthQuarter COMMA? numYear era? ; strSeasonInYearRange: strSeason ( HYPHEN | DASH ) strSeason COMMA? numYear era? ; numDayInMonthRange: numMonth SLASH num ( HYPHEN | DASH ) num SLASH numYear era? ; -numDate: num SLASH num SLASH num era? -| num HYPHEN num HYPHEN num era? ; +numDate: num SLASH ( num | romanNum ) SLASH num era? +| num HYPHEN ( num | romanNum ) HYPHEN num era? ; monthYear: strMonth COMMA? numYear era? ; invMonthYear: era? numYear COMMA? strMonth ; seasonYear: strSeason COMMA? numYear era? ; @@ -132,7 +132,7 @@ numMonth: NUMBER ; numDayOfMonth: NUMBER ; num: NUMBER ; unknownDate: UNKNOWN ; - +romanNum: ROMANNUMBER ; /* * Lexer rules @@ -167,6 +167,7 @@ NTHSTR: [0-9]*? ([0456789] 'th' | '1st' | '2nd' | '3rd' | '11th' | '12th HUNDREDS: [0-9]*? '00' '\''? 's'; TENS: [0-9]*? '0' '\''? 's'; NUMBER: ([0-9,]+)*[0-9] ; +ROMANNUMBER: [ivx]+ ; COMMA: ',' ; HYPHEN: '-' ; DASH: [—–] ; /* EM DASH, EN DASH */ diff --git a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java index e3b6687a8..a6883d72d 100644 --- a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java +++ b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java @@ -1332,6 +1332,42 @@ public class DateUtils { return isValid; } + + /** + * Converts Roman numeral to integer. Currently only supports 1-12. + * @param romanNum The Roman number string that needs to be transformed into decimal + * @return decimal representation of Roman number + * Credit: https://www.geeksforgeeks.org/converting-roman-numerals-decimal-lying-1-3999/ + */ + public static int romanToDecimal(String romanNum) { + int length = romanNum.length(); + int sum = 0; + int pre = 0; + + for (int i = length - 1; i >= 0; i--) { + int cur = getRomanValue(romanNum.charAt(i)); + + if (i == length - 1) { + sum = sum + cur; + } else { + if (cur < pre) { + sum = sum - cur; + } else { + sum = sum + cur; + } + } + pre = cur; + } + + return sum; + } + + private static int getRomanValue(char c) { + if (c == 'i') return 1; + else if (c == 'v') return 5; + else if (c == 'x') return 10; + return -1; + } /** * Converts a Date to a joda-time DateTime. diff --git a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/antlr/ANTLRStructuredDateEvaluator.java b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/antlr/ANTLRStructuredDateEvaluator.java index 8fe852efc..14e51f350 100644 --- a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/antlr/ANTLRStructuredDateEvaluator.java +++ b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/antlr/ANTLRStructuredDateEvaluator.java @@ -80,6 +80,7 @@ import org.collectionspace.services.structureddate.antlr.StructuredDateParser.Pa import org.collectionspace.services.structureddate.antlr.StructuredDateParser.QuarterCenturyContext; import org.collectionspace.services.structureddate.antlr.StructuredDateParser.QuarterInYearRangeContext; import org.collectionspace.services.structureddate.antlr.StructuredDateParser.QuarterYearContext; +import org.collectionspace.services.structureddate.antlr.StructuredDateParser.RomanNumContext; import org.collectionspace.services.structureddate.antlr.StructuredDateParser.SeasonYearContext; import org.collectionspace.services.structureddate.antlr.StructuredDateParser.StrCenturyContext; import org.collectionspace.services.structureddate.antlr.StructuredDateParser.StrDateContext; @@ -482,6 +483,11 @@ public class ANTLRStructuredDateEvaluator extends StructuredDateBaseListener imp numMonth = num2; dayOfMonth = num3; } + else if (DateUtils.isValidDate(num3, num2, num1, era)) { + // The date was of format day-month-year + numMonth = num2; + dayOfMonth = num1; + } stack.push(year); stack.push(numMonth); @@ -1206,6 +1212,18 @@ public class ANTLRStructuredDateEvaluator extends StructuredDateBaseListener imp stack.push(num); } + @Override + public void exitRomanNum(RomanNumContext ctx) { + + int num = DateUtils.romanToDecimal(ctx.ROMANNUMBER().getText()); + + if (num < 1 || num > 12) { + throw new StructuredDateFormatException("unexpected month '" + Integer.toString(num) + "'"); + } + + stack.push(num); + } + @Override public void exitUnknownDate(UnknownDateContext ctx) { if (ctx.exception != null) return; diff --git a/services/structureddate/structureddate/src/test/resources/test-dates.yaml b/services/structureddate/structureddate/src/test/resources/test-dates.yaml index a746dbd75..95950313e 100644 --- a/services/structureddate/structureddate/src/test/resources/test-dates.yaml +++ b/services/structureddate/structureddate/src/test/resources/test-dates.yaml @@ -1253,6 +1253,22 @@ '5/13/54,962 BC-4/5/2,019': # hyphenatedRange, date with comma'd numbers earliestSingleDate: [54962, 5, 13, BCE] latestDate: [2019, 4, 5, CE] + + '17-X-13': # Day-Month-Year with roman numeral as month, makes sure ambiguities resolved as they were before + earliestSingleDate: [17, 10, 13, CE] + + '01-I-2017 BCE': # Day-Month-Year with roman numeral as month + earliestSingleDate: [2017, 1, 1, BCE] + + '19-XI-2018': # Day-Month-Year with roman numeral as month + earliestSingleDate: [2018, 11, 19, CE] + + '27-III-1843 BCE': # Day-Month-Year with roman numeral as month + earliestSingleDate: [1843, 3, 27, BCE] + + '29-IV-2018': # Day-Month-Year with roman numeral as month + earliestSingleDate: [2018, 4, 29, CE] + # ------------------------------------------------------------------------------------------------------- # Invalid dates # ------------------------------------------------------------------------------------------------------- @@ -1300,4 +1316,7 @@ null '13 June 0': # year 0 - null \ No newline at end of file + null + + '29-XX-2018': # invalid month + null