in Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseDateParser.java [153:398]
private DateTimeResolutionResult parseImplicitDate(String text, LocalDateTime referenceDate) {
String trimmedText = text.trim();
DateTimeResolutionResult ret = new DateTimeResolutionResult();
// handle "on 12"
Optional<Match> match = Arrays.stream(RegExpUtility.getMatches(this.config.getOnRegex(), this.config.getDateTokenPrefix() + trimmedText)).findFirst();
if (match.isPresent() && match.get().index == 3 && match.get().length == trimmedText.length()) {
int month = referenceDate.getMonthValue();
int year = referenceDate.getYear();
String dayStr = match.get().getGroup("day").value.toLowerCase();
int day = this.config.getDayOfMonth().get(dayStr);
ret.setTimex(DateTimeFormatUtil.luisDate(-1, -1, day));
LocalDateTime futureDate;
LocalDateTime pastDate;
String tryStr = DateTimeFormatUtil.luisDate(year, month, day);
if (DateUtil.tryParse(tryStr) != null) {
futureDate = DateUtil.safeCreateFromMinValue(year, month, day);
pastDate = DateUtil.safeCreateFromMinValue(year, month, day);
if (futureDate.isBefore(referenceDate)) {
futureDate = futureDate.plusMonths(1);
}
if (pastDate.isEqual(referenceDate) || pastDate.isAfter(referenceDate)) {
pastDate = pastDate.minusMonths(1);
}
} else {
futureDate = DateUtil.safeCreateFromMinValue(year, month + 1, day);
pastDate = DateUtil.safeCreateFromMinValue(year, month - 1, day);
}
ret.setFutureValue(futureDate);
ret.setPastValue(pastDate);
ret.setSuccess(true);
return ret;
}
// handle "today", "the day before yesterday"
ConditionalMatch exactMatch = RegexExtension.matchExact(this.config.getSpecialDayRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
int swift = getSwiftDay(exactMatch.getMatch().get().value);
LocalDateTime value = referenceDate.toLocalDate().atStartOfDay().plusDays(swift);
ret.setTimex(DateTimeFormatUtil.luisDate(value));
ret.setFutureValue(value);
ret.setPastValue(value);
ret.setSuccess(true);
return ret;
}
// handle "two days from tomorrow"
exactMatch = RegexExtension.matchExact(this.config.getSpecialDayWithNumRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
int swift = getSwiftDay(exactMatch.getMatch().get().getGroup("day").value);
List<ExtractResult> numErs = this.config.getIntegerExtractor().extract(trimmedText);
Object numberParsed = this.config.getNumberParser().parse(numErs.get(0)).getValue();
int numOfDays = Math.round(((Double)numberParsed).floatValue());
LocalDateTime value = referenceDate.plusDays(numOfDays + swift);
ret.setTimex(DateTimeFormatUtil.luisDate(value));
ret.setFutureValue(value);
ret.setPastValue(value);
ret.setSuccess(true);
return ret;
}
// handle "two sundays from now"
exactMatch = RegexExtension.matchExact(this.config.getRelativeWeekDayRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
List<ExtractResult> numErs = this.config.getIntegerExtractor().extract(trimmedText);
Object numberParsed = this.config.getNumberParser().parse(numErs.get(0)).getValue();
int num = Math.round(((Double)numberParsed).floatValue());
String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
LocalDateTime value = referenceDate;
// Check whether the determined day of this week has passed.
if (value.getDayOfWeek().getValue() > this.config.getDayOfWeek().get(weekdayStr)) {
num--;
}
while (num-- > 0) {
value = DateUtil.next(value, this.config.getDayOfWeek().get(weekdayStr));
}
ret.setTimex(DateTimeFormatUtil.luisDate(value));
ret.setFutureValue(value);
ret.setPastValue(value);
ret.setSuccess(true);
return ret;
}
// handle "next Sunday"
exactMatch = RegexExtension.matchExact(this.config.getNextRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
LocalDateTime value = DateUtil.next(referenceDate, this.config.getDayOfWeek().get(weekdayStr));
ret.setTimex(DateTimeFormatUtil.luisDate(value));
ret.setFutureValue(value);
ret.setPastValue(value);
ret.setSuccess(true);
return ret;
}
// handle "this Friday"
exactMatch = RegexExtension.matchExact(this.config.getThisRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
LocalDateTime value = DateUtil.thisDate(referenceDate, this.config.getDayOfWeek().get(weekdayStr));
ret.setTimex(DateTimeFormatUtil.luisDate(value));
ret.setFutureValue(value);
ret.setPastValue(value);
ret.setSuccess(true);
return ret;
}
// handle "last Friday", "last mon"
exactMatch = RegexExtension.matchExact(this.config.getLastRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
LocalDateTime value = DateUtil.last(referenceDate, this.config.getDayOfWeek().get(weekdayStr));
ret.setTimex(DateTimeFormatUtil.luisDate(value));
ret.setFutureValue(value);
ret.setPastValue(value);
ret.setSuccess(true);
return ret;
}
// handle "Friday"
exactMatch = RegexExtension.matchExact(this.config.getWeekDayRegex(), trimmedText, true);
if (exactMatch.getSuccess()) {
String weekdayStr = exactMatch.getMatch().get().getGroup("weekday").value.toLowerCase();
int weekDay = this.config.getDayOfWeek().get(weekdayStr);
LocalDateTime value = DateUtil.thisDate(referenceDate, this.config.getDayOfWeek().get(weekdayStr));
if (weekDay == 0) {
weekDay = 7;
}
if (weekDay < referenceDate.getDayOfWeek().getValue()) {
value = DateUtil.next(referenceDate, weekDay);
}
ret.setTimex("XXXX-WXX-" + weekDay);
LocalDateTime futureDate = value;
LocalDateTime pastDate = value;
if (futureDate.isBefore(referenceDate)) {
futureDate = futureDate.plusDays(7);
}
if (pastDate.isEqual(referenceDate) || pastDate.isAfter(referenceDate)) {
pastDate = pastDate.minusDays(7);
}
ret.setFutureValue(futureDate);
ret.setPastValue(pastDate);
ret.setSuccess(true);
return ret;
}
// handle "for the 27th."
match = Arrays.stream(RegExpUtility.getMatches(this.config.getForTheRegex(), text)).findFirst();
if (match.isPresent()) {
int day;
int month = referenceDate.getMonthValue();
int year = referenceDate.getYear();
String dayStr = match.get().getGroup("DayOfMonth").value.toLowerCase();
int start = match.get().getGroup("DayOfMonth").index;
int length = match.get().getGroup("DayOfMonth").length;
// create a extract comments which content ordinal string of text
ExtractResult er = new ExtractResult(start, length, dayStr, null, null);
Object numberParsed = this.config.getNumberParser().parse(er).getValue();
day = Math.round(((Double)numberParsed).floatValue());
ret.setTimex(DateTimeFormatUtil.luisDate(-1, -1, day));
LocalDateTime futureDate;
String tryStr = DateTimeFormatUtil.luisDate(year, month, day);
if (DateUtil.tryParse(tryStr) != null) {
futureDate = DateUtil.safeCreateFromMinValue(year, month, day);
} else {
futureDate = DateUtil.safeCreateFromMinValue(year, month + 1, day);
}
ret.setFutureValue(futureDate);
ret.setPastValue(ret.getFutureValue());
ret.setSuccess(true);
return ret;
}
// handling cases like 'Thursday the 21st', which both 'Thursday' and '21st' refer to a same date
match = Arrays.stream(RegExpUtility.getMatches(this.config.getWeekDayAndDayOfMonthRegex(), text)).findFirst();
if (match.isPresent()) {
int month = referenceDate.getMonthValue();
int year = referenceDate.getYear();
String dayStr = match.get().getGroup("DayOfMonth").value.toLowerCase();
int start = match.get().getGroup("DayOfMonth").index;
int length = match.get().getGroup("DayOfMonth").length;
// create a extract comments which content ordinal string of text
ExtractResult erTmp = new ExtractResult(start, length, dayStr, null, null);
Object numberParsed = this.config.getNumberParser().parse(erTmp).getValue();
int day = Math.round(((Double)numberParsed).floatValue());
// the validity of the phrase is guaranteed in the Date Extractor
ret.setTimex(DateTimeFormatUtil.luisDate(year, month, day));
ret.setFutureValue(LocalDateTime.of(year, month, day, 0, 0));
ret.setPastValue(LocalDateTime.of(year, month, day, 0, 0));
ret.setSuccess(true);
return ret;
}
return ret;
}