Thomas
Thomas

Reputation: 4297

Working with LUIS datetimeV2 entities in botframework v4

I'm using the Botframework v4 C# with the dispatch tool to get results from LUIS & QnA Maker. Some of my LUIS results have datetimev2 entities which I'm not quite sure how to process properly.

I'm seeing the resolved datetime value inside the AdditionalProperties, is there a built-in class that I can cast this object to? Are there any samples out there that explain how to work with entities in general within the botframework v4? All docs related to this still seem to be for v3 only.

LUIS Datetime Result

Upvotes: 0

Views: 434

Answers (2)

Thomas
Thomas

Reputation: 4297

I ended up using these LuisResolutionExtensions to extract DateTime values and LUIS entities in general.

public static DateTime ProcessDateTimeV2Date(this EntityModel entity)
{
    if (entity.AdditionalProperties.TryGetValue("resolution", out dynamic resolution))
    {
        var resolutionValues = (IEnumerable<dynamic>) resolution.values;
        var datetimes = resolutionValues.Select(val => DateTime.Parse(val.value.Value));

        if (datetimes.Count() > 1)
        {
            // assume the date is in the next 7 days
            var bestGuess = datetimes.Single(dateTime => dateTime > DateTime.Now && (DateTime.Now - dateTime).Days <= 7);
            return bestGuess;
        }

        return datetimes.FirstOrDefault();
    }

    throw new Exception("ProcessDateTimeV2DateTime");
}

public static string ProcessRoom(this EntityModel entity)
{
    if (entity.AdditionalProperties.TryGetValue("resolution", out dynamic resolution))
    {
        var resolutionValues = (IEnumerable<dynamic>) resolution.values;
        return resolutionValues.Select(room => room).FirstOrDefault();
    }

    throw new Exception("ProcessRoom");
}

Upvotes: 0

Horatiu Jeflea
Horatiu Jeflea

Reputation: 7404

datetimeV2 is tricky and had to refactor the logic based on user input (there are dates without year, relative dates and so on)

The code (JS) which handles the datetime is:

const datetime = _.get(
          luisQuery.entities.filter(e => e.type && e.type.includes("builtin.datetimeV2")), 
          '[0].resolution.values[0].timex', 
          null);

const hasYear = (datetime) => {
    return !datetime.includes("XXXX");
};

const makeUseOfDateTime = (datetime) => {
    if (datetime.length === 4) {
        datetime += "-12-31";
    } else if (datetime.length === 7) {
        datetime += "-31";
    }

    // do something with datetime
};

hasYear checks if the year was introduced by the user, makeUseOfDateTime infers the end of year (if only year provided) and infers end of month (if only year and month are provided)

Upvotes: 2

Related Questions