in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseDateTimeParser.java [101:234]
private DateTimeResolutionResult mergeDateAndTime(String text, LocalDateTime reference) {
DateTimeResolutionResult result = new DateTimeResolutionResult();
List<ExtractResult> ersDate = config.getDateExtractor().extract(text, reference);
if (ersDate.isEmpty()) {
ersDate = config.getDateExtractor().extract(config.getTokenBeforeDate() + text, reference);
if (ersDate.size() == 1) {
int newStart = ersDate.get(0).getStart() - config.getTokenBeforeDate().length();
ersDate.get(0).setStart(newStart);
ersDate.set(0, ersDate.get(0));
} else {
return result;
}
} else {
// This is to understand if there is an ambiguous token in the text. For some
// languages (e.g. spanish),
// the same word could mean different things (e.g a time in the day or an
// specific day).
if (config.containsAmbiguousToken(text, ersDate.get(0).getText())) {
return result;
}
}
List<ExtractResult> ersTime = config.getTimeExtractor().extract(text, reference);
if (ersTime.isEmpty()) {
// Here we filter out "morning, afternoon, night..." time entities
ersTime = config.getTimeExtractor().extract(config.getTokenBeforeTime() + text, reference);
if (ersTime.size() == 1) {
int newStart = ersTime.get(0).getStart() - config.getTokenBeforeTime().length();
ersTime.get(0).setStart(newStart);
ersTime.set(0, ersTime.get(0));
} else if (ersTime.isEmpty()) {
// check whether there is a number being used as a time point
boolean hasTimeNumber = false;
List<ExtractResult> numErs = config.getIntegerExtractor().extract(text);
if (!numErs.isEmpty() && ersDate.size() == 1) {
for (ExtractResult num : numErs) {
int middleBegin = ersDate.get(0).getStart() + ersDate.get(0).getLength();
int middleEnd = num.getStart();
if (middleBegin > middleEnd) {
continue;
}
String middleStr = text.substring(middleBegin, middleEnd).trim().toLowerCase();
Optional<Match> match = Arrays
.stream(RegExpUtility.getMatches(config.getDateNumberConnectorRegex(), middleStr))
.findFirst();
if (StringUtility.isNullOrEmpty(middleStr) || match.isPresent()) {
num.setType(Constants.SYS_DATETIME_TIME);
ersTime.add(num);
hasTimeNumber = true;
}
}
}
if (!hasTimeNumber) {
return result;
}
}
}
// Handle cases like "Oct. 5 in the afternoon at 7:00";
// in this case "5 in the afternoon" will be extracted as a Time entity
int correctTimeIdx = 0;
while (correctTimeIdx < ersTime.size() && ersTime.get(correctTimeIdx).isOverlap(ersDate.get(0))) {
correctTimeIdx++;
}
if (correctTimeIdx >= ersTime.size()) {
return result;
}
DateTimeParseResult prDate = config.getDateParser().parse(ersDate.get(0), reference);
DateTimeParseResult prTime = config.getTimeParser().parse(ersTime.get(correctTimeIdx), reference);
if (prDate.getValue() == null || prTime.getValue() == null) {
return result;
}
LocalDateTime futureDate = (LocalDateTime)((DateTimeResolutionResult)prDate.getValue()).getFutureValue();
LocalDateTime pastDate = (LocalDateTime)((DateTimeResolutionResult)prDate.getValue()).getPastValue();
LocalDateTime time = (LocalDateTime)((DateTimeResolutionResult)prTime.getValue()).getPastValue();
int hour = time.getHour();
int min = time.getMinute();
int sec = time.getSecond();
// Handle morning, afternoon
if (RegExpUtility.getMatches(config.getPMTimeRegex(), text).length != 0 && withinAfternoonHours(hour)) {
hour += Constants.HalfDayHourCount;
} else if (RegExpUtility.getMatches(config.getAMTimeRegex(), text).length != 0 &&
withinMorningHoursAndNoon(hour, min, sec)) {
hour -= Constants.HalfDayHourCount;
}
String timeStr = prTime.getTimexStr();
if (timeStr.endsWith(Constants.Comment_AmPm)) {
timeStr = timeStr.substring(0, timeStr.length() - 4);
}
timeStr = String.format("T%02d%s", hour, timeStr.substring(3));
result.setTimex(prDate.getTimexStr() + timeStr);
DateTimeResolutionResult val = (DateTimeResolutionResult)prTime.getValue();
if (hour <= Constants.HalfDayHourCount && RegExpUtility.getMatches(config.getPMTimeRegex(), text).length == 0 &&
RegExpUtility.getMatches(config.getAMTimeRegex(), text).length == 0 &&
!StringUtility.isNullOrEmpty(val.getComment())) {
result.setComment(Constants.Comment_AmPm);
}
result.setFutureValue(DateUtil.safeCreateFromMinValue(futureDate.getYear(), futureDate.getMonthValue(),
futureDate.getDayOfMonth(), hour, min, sec));
result.setPastValue(DateUtil.safeCreateFromMinValue(pastDate.getYear(), pastDate.getMonthValue(),
pastDate.getDayOfMonth(), hour, min, sec));
result.setSuccess(true);
// Change the value of time object
prTime.setTimexStr(timeStr);
if (!StringUtility.isNullOrEmpty(result.getComment())) {
DateTimeResolutionResult newValue = (DateTimeResolutionResult)prTime.getValue();
newValue.setComment(result.getComment().equals(Constants.Comment_AmPm) ? Constants.Comment_AmPm : "");
prTime.setValue(newValue);
prTime.setTimexStr(timeStr);
}
// Add the date and time object in case we want to split them
List<Object> entities = new ArrayList<>();
entities.add(prDate);
entities.add(prTime);
result.setSubDateTimeEntities(entities);
result.setTimeZoneResolution(((DateTimeResolutionResult)prTime.getValue()).getTimeZoneResolution());
return result;
}