in Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java [72:286]
public DateTimeParseResult parse(ExtractResult er, LocalDateTime reference) {
DateTimeParseResult pr = null;
String originText = er.getText();
if (this.config.getOptions().match(DateTimeOptions.EnablePreview)) {
String newText = MatchingUtil.preProcessTextRemoveSuperfluousWords(er.getText(), config.getSuperfluousWordMatcher()).getText();
int newLength = er.getLength() + newText.length() - originText.length();
er = new ExtractResult(er.getStart(), newLength, newText, er.getType(), er.getData(), er.getMetadata());
}
// Push, save the MOD string
boolean hasBefore = false;
boolean hasAfter = false;
boolean hasSince = false;
boolean hasAround = false;
boolean hasYearAfter = false;
// "InclusiveModifier" means MOD should include the start/end time
// For example, cases like "on or later than", "earlier than or in" have inclusive modifier
boolean hasInclusiveModifier = false;
String modStr = "";
if (er.getMetadata() != null && er.getMetadata().getHasMod()) {
ConditionalMatch beforeMatch = RegexExtension.matchBegin(config.getBeforeRegex(), er.getText(), true);
ConditionalMatch afterMatch = RegexExtension.matchBegin(config.getAfterRegex(), er.getText(), true);
ConditionalMatch sinceMatch = RegexExtension.matchBegin(config.getSinceRegex(), er.getText(), true);
ConditionalMatch aroundMatch = RegexExtension.matchBegin(config.getAroundRegex(), er.getText(), true);
if (beforeMatch.getSuccess()) {
hasBefore = true;
er.setStart(er.getStart() + beforeMatch.getMatch().get().length);
er.setLength(er.getLength() - beforeMatch.getMatch().get().length);
er.setText(er.getText().substring(beforeMatch.getMatch().get().length));
modStr = beforeMatch.getMatch().get().value;
if (!StringUtility.isNullOrEmpty(beforeMatch.getMatch().get().getGroup("include").value)) {
hasInclusiveModifier = true;
}
} else if (afterMatch.getSuccess()) {
hasAfter = true;
er.setStart(er.getStart() + afterMatch.getMatch().get().length);
er.setLength(er.getLength() - afterMatch.getMatch().get().length);
er.setText(er.getText().substring(afterMatch.getMatch().get().length));
modStr = afterMatch.getMatch().get().value;
if (!StringUtility.isNullOrEmpty(afterMatch.getMatch().get().getGroup("include").value)) {
hasInclusiveModifier = true;
}
} else if (sinceMatch.getSuccess()) {
hasSince = true;
er.setStart(er.getStart() + sinceMatch.getMatch().get().length);
er.setLength(er.getLength() - sinceMatch.getMatch().get().length);
er.setText(er.getText().substring(sinceMatch.getMatch().get().length));
modStr = sinceMatch.getMatch().get().value;
} else if (aroundMatch.getSuccess()) {
hasAround = true;
er.setStart(er.getStart() + aroundMatch.getMatch().get().length);
er.setLength(er.getLength() - aroundMatch.getMatch().get().length);
er.setText(er.getText().substring(aroundMatch.getMatch().get().length));
modStr = aroundMatch.getMatch().get().value;
} else if ((er.getType().equals(Constants.SYS_DATETIME_DATEPERIOD) &&
Arrays.stream(RegExpUtility.getMatches(config.getYearRegex(), er.getText())).findFirst().isPresent()) ||
(er.getType().equals(Constants.SYS_DATETIME_DATE)) || (er.getType().equals(Constants.SYS_DATETIME_TIME))) {
// This has to be put at the end of the if, or cases like "before 2012" and "after 2012" would fall into this
// 2012 or after/above, 3 pm or later
ConditionalMatch match = RegexExtension.matchEnd(config.getSuffixAfterRegex(), er.getText(), true);
if (match.getSuccess()) {
hasYearAfter = true;
er.setLength(er.getLength() - match.getMatch().get().length);
er.setText(er.getLength() > 0 ? er.getText().substring(0, er.getLength()) : "");
modStr = match.getMatch().get().value;
}
}
}
if (er.getType().equals(Constants.SYS_DATETIME_DATE)) {
if (er.getMetadata() != null && er.getMetadata().getIsHoliday()) {
pr = config.getHolidayParser().parse(er, reference);
} else {
pr = this.config.getDateParser().parse(er, reference);
}
} else if (er.getType().equals(Constants.SYS_DATETIME_TIME)) {
pr = this.config.getTimeParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_DATETIME)) {
pr = this.config.getDateTimeParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_DATEPERIOD)) {
pr = this.config.getDatePeriodParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_TIMEPERIOD)) {
pr = this.config.getTimePeriodParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_DATETIMEPERIOD)) {
pr = this.config.getDateTimePeriodParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_DURATION)) {
pr = this.config.getDurationParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_SET)) {
pr = this.config.getGetParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_DATETIMEALT)) {
pr = this.config.getDateTimeAltParser().parse(er, reference);
} else if (er.getType().equals(Constants.SYS_DATETIME_TIMEZONE)) {
if (config.getOptions().match(DateTimeOptions.EnablePreview)) {
pr = this.config.getTimeZoneParser().parse(er, reference);
}
} else {
return null;
}
if (pr == null) {
return null;
}
// Pop, restore the MOD string
if (hasBefore && pr != null && pr.getValue() != null) {
pr.setStart(pr.getStart() - modStr.length());
pr.setText(modStr + pr.getText());
pr.setLength(pr.getLength() + modStr.length());
DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
if (!hasInclusiveModifier) {
val.setMod(combineMod(val.getMod(), Constants.BEFORE_MOD));
} else {
val.setMod(combineMod(val.getMod(), Constants.UNTIL_MOD));
}
pr.setValue(val);
}
if (hasAfter && pr != null && pr.getValue() != null) {
pr.setStart(pr.getStart() - modStr.length());
pr.setText(modStr + pr.getText());
pr.setLength(pr.getLength() + modStr.length());
DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
if (!hasInclusiveModifier) {
val.setMod(combineMod(val.getMod(), Constants.AFTER_MOD));
} else {
val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
}
pr.setValue(val);
}
if (hasSince && pr != null && pr.getValue() != null) {
pr.setStart(pr.getStart() - modStr.length());
pr.setText(modStr + pr.getText());
pr.setLength(pr.getLength() + modStr.length());
DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
pr.setValue(val);
}
if (hasAround && pr != null && pr.getValue() != null) {
pr.setStart(pr.getStart() - modStr.length());
pr.setText(modStr + pr.getText());
pr.setLength(pr.getLength() + modStr.length());
DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
val.setMod(combineMod(val.getMod(), Constants.APPROX_MOD));
pr.setValue(val);
}
if (hasYearAfter && pr != null && pr.getValue() != null) {
pr.setText(pr.getText() + modStr);
pr.setLength(pr.getLength() + modStr.length());
DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
pr.setValue(val);
hasSince = true;
}
// For cases like "3 pm or later on Monday"
if (pr != null && pr.getValue() != null && pr.getType().equals(Constants.SYS_DATETIME_DATETIME)) {
Optional<Match> match = Arrays.stream(RegExpUtility.getMatches(config.getSuffixAfterRegex(), pr.getText())).findFirst();
if (match.isPresent() && match.get().index != 0) {
DateTimeResolutionResult val = (DateTimeResolutionResult)pr.getValue();
val.setMod(combineMod(val.getMod(), Constants.SINCE_MOD));
pr.setValue(val);
hasSince = true;
}
}
if (config.getOptions().match(DateTimeOptions.SplitDateAndTime) && pr != null && pr.getValue() != null &&
((DateTimeResolutionResult)pr.getValue()).getSubDateTimeEntities() != null) {
pr.setValue(dateTimeResolutionForSplit(pr));
} else {
boolean hasModifier = hasBefore || hasAfter || hasSince;
if (pr.getValue() != null) {
((DateTimeResolutionResult)pr.getValue()).setHasRangeChangingMod(hasModifier);
}
pr = setParseResult(pr, hasModifier);
}
// In this version, ExperimentalMode only cope with the "IncludePeriodEnd" case
if (this.config.getOptions().match(DateTimeOptions.ExperimentalMode)) {
if (pr.getMetadata() != null && pr.getMetadata().getIsPossiblyIncludePeriodEnd()) {
pr = setInclusivePeriodEnd(pr);
}
}
if (this.config.getOptions().match(DateTimeOptions.EnablePreview)) {
int prLength = pr.getLength() + originText.length() - pr.getText().length();
pr = new DateTimeParseResult(pr.getStart(), prLength, originText, pr.getType(), pr.getData(), pr.getValue(), pr.getResolutionStr(), pr.getTimexStr());
}
return pr;
}