in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java [435:582]
public SortedMap<String, Object> dateTimeResolution(DateTimeParseResult slot) {
if (slot == null) {
return null;
}
List<Map<String, String>> resolutions = new ArrayList<>();
LinkedHashMap<String, Object> res = new LinkedHashMap<>();
DateTimeResolutionResult val = (DateTimeResolutionResult)slot.getValue();
if (val == null) {
return null;
}
boolean islunar = val.getIsLunar() != null ? val.getIsLunar() : false;
String mod = val.getMod();
String list = null;
// Resolve dates list for date periods
if (slot.getType().equals(Constants.SYS_DATETIME_DATEPERIOD) && val.getList() != null) {
list = String.join(",", val.getList().stream().map(o -> DateTimeFormatUtil.luisDate((LocalDateTime)o)).collect(Collectors.toList()));
}
// With modifier, output Type might not be the same with type in resolution comments
// For example, if the resolution type is "date", with modifier the output type should be "daterange"
String typeOutput = determineDateTimeType(slot.getType(), !StringUtility.isNullOrEmpty(mod));
String sourceEntity = determineSourceEntityType(slot.getType(), typeOutput, val.getHasRangeChangingMod());
String comment = val.getComment();
String type = slot.getType();
String timex = slot.getTimexStr();
// The following should be added to res first, since ResolveAmPm requires these fields.
addResolutionFields(res, DateTimeResolutionKey.Timex, timex);
addResolutionFields(res, Constants.Comment, comment);
addResolutionFields(res, DateTimeResolutionKey.Mod, mod);
addResolutionFields(res, ResolutionKey.Type, typeOutput);
addResolutionFields(res, DateTimeResolutionKey.IsLunar, islunar ? Boolean.toString(islunar) : "");
boolean hasTimeZone = false;
// For standalone timezone entity recognition, we generate TimeZoneResolution for each entity we extracted.
// We also merge time entity with timezone entity and add the information in TimeZoneResolution to every DateTime resolutions.
if (val.getTimeZoneResolution() != null) {
if (slot.getType().equals(Constants.SYS_DATETIME_TIMEZONE)) {
// single timezone
Map<String, String> resolutionField = new LinkedHashMap<>();
resolutionField.put(ResolutionKey.Value, val.getTimeZoneResolution().getValue());
resolutionField.put(Constants.UtcOffsetMinsKey, val.getTimeZoneResolution().getUtcOffsetMins().toString());
addResolutionFields(res, Constants.ResolveTimeZone, resolutionField);
} else {
// timezone as clarification of datetime
hasTimeZone = true;
addResolutionFields(res, Constants.TimeZone, val.getTimeZoneResolution().getValue());
addResolutionFields(res, Constants.TimeZoneText, val.getTimeZoneResolution().getTimeZoneText());
addResolutionFields(res, Constants.UtcOffsetMinsKey, val.getTimeZoneResolution().getUtcOffsetMins().toString());
}
}
LinkedHashMap<String, String> pastResolutionStr = new LinkedHashMap<>();
if (((DateTimeResolutionResult)slot.getValue()).getPastResolution() != null) {
pastResolutionStr.putAll(((DateTimeResolutionResult)slot.getValue()).getPastResolution());
}
Map<String, String> futureResolutionStr = ((DateTimeResolutionResult)slot.getValue()).getFutureResolution();
if (typeOutput.equals(Constants.SYS_DATETIME_DATETIMEALT) && pastResolutionStr.size() > 0) {
typeOutput = determineResolutionDateTimeType(pastResolutionStr);
}
Map<String, String> resolutionPast = generateResolution(type, pastResolutionStr, mod);
Map<String, String> resolutionFuture = generateResolution(type, futureResolutionStr, mod);
// If past and future are same, keep only one
if (resolutionFuture.equals(resolutionPast)) {
if (resolutionPast.size() > 0) {
addResolutionFields(res, Constants.Resolve, resolutionPast);
}
} else {
if (resolutionPast.size() > 0) {
addResolutionFields(res, Constants.ResolveToPast, resolutionPast);
}
if (resolutionFuture.size() > 0) {
addResolutionFields(res, Constants.ResolveToFuture, resolutionFuture);
}
}
// If 'ampm', double our resolution accordingly
if (!StringUtility.isNullOrEmpty(comment) && comment.equals(Constants.Comment_AmPm)) {
if (res.containsKey(Constants.Resolve)) {
resolveAmPm(res, Constants.Resolve);
} else {
resolveAmPm(res, Constants.ResolveToPast);
resolveAmPm(res, Constants.ResolveToFuture);
}
}
// If WeekOf and in CalendarMode, modify the past part of our resolution
if (config.getOptions().match(DateTimeOptions.CalendarMode) &&
!StringUtility.isNullOrEmpty(comment) && comment.equals(Constants.Comment_WeekOf)) {
resolveWeekOf(res, Constants.ResolveToPast);
}
if (comment != null && !comment.isEmpty() && TimexUtility.hasDoubleTimex(comment)) {
res = TimexUtility.processDoubleTimex(res, Constants.ResolveToFuture, Constants.ResolveToPast, timex);
}
for (Map.Entry<String,Object> p : res.entrySet()) {
if (p.getValue() instanceof Map) {
Map<String, String> value = new LinkedHashMap<>();
addResolutionFields(value, DateTimeResolutionKey.Timex, timex);
addResolutionFields(value, DateTimeResolutionKey.Mod, mod);
addResolutionFields(value, ResolutionKey.Type, typeOutput);
addResolutionFields(value, DateTimeResolutionKey.IsLunar, islunar ? Boolean.toString(islunar) : "");
addResolutionFields(value, DateTimeResolutionKey.List, list);
addResolutionFields(value, DateTimeResolutionKey.SourceEntity, sourceEntity);
if (hasTimeZone) {
addResolutionFields(value, Constants.TimeZone, val.getTimeZoneResolution().getValue());
addResolutionFields(value, Constants.TimeZoneText, val.getTimeZoneResolution().getTimeZoneText());
addResolutionFields(value, Constants.UtcOffsetMinsKey, val.getTimeZoneResolution().getUtcOffsetMins().toString());
}
for (Map.Entry<String, String> q : ((Map<String, String>)p.getValue()).entrySet()) {
value.put(q.getKey(), q.getValue());
}
resolutions.add(value);
}
}
if (resolutionPast.size() == 0 && resolutionFuture.size() == 0 && val.getTimeZoneResolution() == null) {
Map<String, String> notResolved = new LinkedHashMap<>();
notResolved.put(DateTimeResolutionKey.Timex, timex);
notResolved.put(ResolutionKey.Type, typeOutput);
notResolved.put(ResolutionKey.Value, "not resolved");
resolutions.add(notResolved);
}
SortedMap<String, Object> result = new TreeMap<>();
result.put(ResolutionKey.ValueSet, resolutions);
return result;
}