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? ;
numDayOfMonth: NUMBER ;
num: NUMBER ;
unknownDate: UNKNOWN ;
-
+romanNum: ROMANNUMBER ;
/*
* Lexer rules
HUNDREDS: [0-9]*? '00' '\''? 's';
TENS: [0-9]*? '0' '\''? 's';
NUMBER: ([0-9,]+)*[0-9] ;
+ROMANNUMBER: [ivx]+ ;
COMMA: ',' ;
HYPHEN: '-' ;
DASH: [—–] ; /* EM DASH, EN DASH */
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.
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;
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);
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;
'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
# -------------------------------------------------------------------------------------------------------
null
'13 June 0': # year 0
- null
\ No newline at end of file
+ null
+
+ '29-XX-2018': # invalid month
+ null