in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseDatePeriodParser.java [550:833]
private DateTimeResolutionResult parseOneWordPeriod(String text, LocalDateTime referenceDate) {
DateTimeResolutionResult ret = new DateTimeResolutionResult();
int year = referenceDate.getYear();
int month = referenceDate.getMonthValue();
int futureYear = year;
int pastYear = year;
boolean earlyPrefix = false;
boolean latePrefix = false;
boolean midPrefix = false;
boolean isRef = false;
boolean earlierPrefix = false;
boolean laterPrefix = false;
String trimmedText = text.trim().toLowerCase();
ConditionalMatch match = RegexExtension.matchExact(this.config.getOneWordPeriodRegex(), trimmedText, true);
if (!match.getSuccess()) {
match = RegexExtension.matchExact(this.config.getLaterEarlyPeriodRegex(), trimmedText, true);
}
// For cases "that week|month|year"
if (!match.getSuccess()) {
match = RegexExtension.matchExact(this.config.getReferenceDatePeriodRegex(), trimmedText, true);
isRef = true;
ret.setMod(Constants.REF_UNDEF_MOD);
}
if (match.getSuccess()) {
if (!match.getMatch().get().getGroup("EarlyPrefix").value.equals("")) {
earlyPrefix = true;
trimmedText = match.getMatch().get().getGroup(Constants.SuffixGroupName).value;
ret.setMod(Constants.EARLY_MOD);
} else if (!match.getMatch().get().getGroup("LatePrefix").value.equals("")) {
latePrefix = true;
trimmedText = match.getMatch().get().getGroup(Constants.SuffixGroupName).value;
ret.setMod(Constants.LATE_MOD);
} else if (!match.getMatch().get().getGroup("MidPrefix").value.equals("")) {
midPrefix = true;
trimmedText = match.getMatch().get().getGroup(Constants.SuffixGroupName).value;
ret.setMod(Constants.MID_MOD);
}
int swift = 0;
String monthStr = match.getMatch().get().getGroup("month").value;
if (!StringUtility.isNullOrEmpty(monthStr)) {
swift = this.config.getSwiftYear(trimmedText);
} else {
swift = this.config.getSwiftDayOrMonth(trimmedText);
}
// Handle the abbreviation of DatePeriod, e.g., 'eoy(end of year)', the behavior of 'eoy' should be the same as 'end of year'
Optional<Match> unspecificEndOfRangeMatch = Arrays.stream(RegExpUtility.getMatches(config.getUnspecificEndOfRangeRegex(), match.getMatch().get().value)).findFirst();
if (unspecificEndOfRangeMatch.isPresent()) {
latePrefix = true;
trimmedText = match.getMatch().get().value;
ret.setMod(Constants.LATE_MOD);
}
if (!match.getMatch().get().getGroup("RelEarly").value.equals("")) {
earlierPrefix = true;
if (isPresent(swift)) {
ret.setMod(null);
}
} else if (!match.getMatch().get().getGroup("RelLate").value.equals("")) {
laterPrefix = true;
if (isPresent(swift)) {
ret.setMod(null);
}
}
if (this.config.isYearToDate(trimmedText)) {
ret.setTimex(String.format("%04d", referenceDate.getYear()));
ret.setFutureValue(new Pair<>(
DateUtil.safeCreateFromMinValue(referenceDate.getYear(), 1, 1), referenceDate));
ret.setPastValue(new Pair<>(
DateUtil.safeCreateFromMinValue(referenceDate.getYear(), 1, 1), referenceDate));
ret.setSuccess(true);
return ret;
}
if (this.config.isMonthToDate(trimmedText)) {
ret.setTimex(String.format("%04d-%02d", referenceDate.getYear(), referenceDate.getMonthValue()));
ret.setFutureValue(new Pair<>(
DateUtil.safeCreateFromMinValue(referenceDate.getYear(), referenceDate.getMonthValue(), 1),
referenceDate));
ret.setPastValue(new Pair<>(
DateUtil.safeCreateFromMinValue(referenceDate.getYear(), referenceDate.getMonthValue(), 1),
referenceDate));
ret.setSuccess(true);
return ret;
}
if (!StringUtility.isNullOrEmpty(monthStr)) {
swift = this.config.getSwiftYear(trimmedText);
month = this.config.getMonthOfYear().get(monthStr.toLowerCase());
if (swift >= -1) {
ret.setTimex(String.format("%04d-%02d", referenceDate.getYear() + swift, month));
year = year + swift;
futureYear = pastYear = year;
} else {
ret.setTimex(String.format("XXXX-%02d", month));
if (month < referenceDate.getMonthValue()) {
futureYear++;
}
if (month >= referenceDate.getMonthValue()) {
pastYear--;
}
}
} else {
swift = this.config.getSwiftDayOrMonth(trimmedText);
if (this.config.isWeekOnly(trimmedText)) {
LocalDateTime thursday = DateUtil.thisDate(referenceDate, DayOfWeek.THURSDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
ret.setTimex(isRef ? TimexUtility.generateWeekTimex() : TimexUtility.generateWeekTimex(thursday));
LocalDateTime beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.MONDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
LocalDateTime endValue = DateUtil.thisDate(referenceDate, DayOfWeek.SUNDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
LocalDateTime endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
if (earlyPrefix) {
endValue = DateUtil.thisDate(referenceDate, DayOfWeek.WEDNESDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
} else if (midPrefix) {
beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.TUESDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
endValue = DateUtil.thisDate(referenceDate, DayOfWeek.FRIDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
} else if (latePrefix) {
beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.THURSDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
}
if (earlierPrefix && swift == 0) {
if (endDate.isAfter(referenceDate)) {
endDate = referenceDate;
}
} else if (laterPrefix && swift == 0) {
if (beginDate.isBefore(referenceDate)) {
beginDate = referenceDate;
}
}
if (latePrefix && swift != 0) {
ret.setMod(Constants.LATE_MOD);
}
ret.setFutureValue(new Pair<>(beginDate, endDate));
ret.setPastValue(new Pair<>(beginDate, endDate));
ret.setSuccess(true);
return ret;
}
if (this.config.isWeekend(trimmedText)) {
LocalDateTime beginDate = DateUtil.thisDate(referenceDate, DayOfWeek.SATURDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
LocalDateTime endValue = DateUtil.thisDate(referenceDate, DayOfWeek.SUNDAY.getValue()).plusDays(Constants.WeekDayCount * swift);
ret.setTimex(isRef ? TimexUtility.generateWeekendTimex() : TimexUtility.generateWeekendTimex(beginDate));
LocalDateTime endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
ret.setFutureValue(new Pair<>(beginDate, endDate));
ret.setPastValue(new Pair<>(beginDate, endDate));
ret.setSuccess(true);
return ret;
}
if (this.config.isMonthOnly(trimmedText)) {
LocalDateTime date = referenceDate.plusMonths(swift);
month = date.getMonthValue();
year = date.getYear();
ret.setTimex(isRef ? TimexUtility.generateMonthTimex() : TimexUtility.generateMonthTimex(date));
futureYear = pastYear = year;
} else if (this.config.isYearOnly(trimmedText)) {
LocalDateTime date = referenceDate.plusYears(swift);
year = date.getYear();
if (!StringUtility.isNullOrEmpty(match.getMatch().get().getGroup("special").value)) {
String specialYearPrefixes = this.config.getSpecialYearPrefixesMap().get(match.getMatch().get().getGroup("special").value.toLowerCase());
swift = this.config.getSwiftYear(trimmedText);
year = swift < -1 ? Constants.InvalidYear : year;
ret.setTimex(TimexUtility.generateYearTimex(year, specialYearPrefixes));
ret.setSuccess(true);
return ret;
}
LocalDateTime beginDate = DateUtil.safeCreateFromMinValue(year, 1, 1);
LocalDateTime endValue = DateUtil.safeCreateFromMinValue(year, 12, 31);
LocalDateTime endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
if (earlyPrefix) {
endValue = DateUtil.safeCreateFromMinValue(year, 6, 30);
endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
} else if (midPrefix) {
beginDate = DateUtil.safeCreateFromMinValue(year, 4, 1);
endValue = DateUtil.safeCreateFromMinValue(year, 9, 30);
endDate = inclusiveEndPeriod ? endValue : endValue.plusDays(1);
} else if (latePrefix) {
beginDate = DateUtil.safeCreateFromMinValue(year, 7, 1);
}
if (earlierPrefix && swift == 0) {
if (endDate.isAfter(referenceDate)) {
endDate = referenceDate;
}
} else if (laterPrefix && swift == 0) {
if (beginDate.isBefore(referenceDate)) {
beginDate = referenceDate;
}
}
year = isRef ? Constants.InvalidYear : year;
ret.setTimex(TimexUtility.generateYearTimex(year));
ret.setFutureValue(new Pair<>(beginDate, endDate));
ret.setPastValue(new Pair<>(beginDate, endDate));
ret.setSuccess(true);
return ret;
}
}
} else {
return ret;
}
// only "month" will come to here
LocalDateTime futureStart = DateUtil.safeCreateFromMinValue(futureYear, month, 1);
LocalDateTime futureEnd = inclusiveEndPeriod ? futureStart.plusMonths(1).minusDays(1) : futureStart.plusMonths(1);
LocalDateTime pastStart = DateUtil.safeCreateFromMinValue(pastYear, month, 1);
LocalDateTime pastEnd = inclusiveEndPeriod ? pastStart.plusMonths(1).minusDays(1) : pastStart.plusMonths(1);
if (earlyPrefix) {
futureEnd = inclusiveEndPeriod ?
DateUtil.safeCreateFromMinValue(futureYear, month, 15) :
DateUtil.safeCreateFromMinValue(futureYear, month, 15).plusDays(1);
pastEnd = inclusiveEndPeriod ?
DateUtil.safeCreateFromMinValue(pastYear, month, 15) :
DateUtil.safeCreateFromMinValue(pastYear, month, 15).plusDays(1);
} else if (midPrefix) {
futureStart = DateUtil.safeCreateFromMinValue(futureYear, month, 10);
pastStart = DateUtil.safeCreateFromMinValue(pastYear, month, 10);
futureEnd = inclusiveEndPeriod ?
DateUtil.safeCreateFromMinValue(futureYear, month, 20) :
DateUtil.safeCreateFromMinValue(futureYear, month, 20).plusDays(1);
pastEnd = inclusiveEndPeriod ?
DateUtil.safeCreateFromMinValue(pastYear, month, 20) :
DateUtil.safeCreateFromMinValue(pastYear, month, 20).plusDays(1);
} else if (latePrefix) {
futureStart = DateUtil.safeCreateFromMinValue(futureYear, month, 16);
pastStart = DateUtil.safeCreateFromMinValue(pastYear, month, 16);
}
if (earlierPrefix && futureEnd.isEqual(pastEnd)) {
if (futureEnd.isAfter(referenceDate)) {
futureEnd = pastEnd = referenceDate;
}
} else if (laterPrefix && futureStart.isEqual(pastStart)) {
if (futureStart.isBefore(referenceDate)) {
futureStart = pastStart = referenceDate;
}
}
ret.setFutureValue(new Pair<>(futureStart, futureEnd));
ret.setPastValue(new Pair<>(pastStart, pastEnd));
ret.setSuccess(true);
return ret;
}