public SortedMap dateTimeResolution()

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;
    }