public static Extraction ValidateAndExtract(string input, string culture) { // Get DateTime model for the specified culture var model = DateTimeRecognizer.GetSingleCultureInstance(culture).GetDateTimeModel(); var results = model.Parse(input); // Check there are valid results if (results.Count > 0 && results.First().TypeName.StartsWith("datetimeV2")) { // The DateTime model can return several resolution types (https://github.com/Microsoft/Recognizers-Text/blob/master/.NET/Microsoft.Recognizers.Text.DateTime/Constants.cs#L7-L14) // We only care for those with a date, date and time, or date time period: // date, daterange, datetime, datetimerange var first = results.First(); var resolutionValues = (IList <Dictionary <string, string> >)first.Resolution["values"]; var subType = first.TypeName.Split('.').Last(); if (subType.Contains("date") && !subType.Contains("range")) { // a date (or date & time) or multiple var moment = resolutionValues.Select(v => DateTime.Parse(v["value"])).FirstOrDefault(); if (IsFuture(moment)) { // a future moment, valid! return(new Extraction { IsValid = true, Values = new[] { moment } }); } // a past moment return(new Extraction { IsValid = false, Values = new[] { moment }, ErrorMessage = PastValueErrorMessage.Replace("$moment$", MomentOrRangeToString(moment)) }); } else if (subType.Contains("date") && subType.Contains("range")) { // range var from = DateTime.Parse(resolutionValues.First()["start"]); var to = DateTime.Parse(resolutionValues.First()["end"]); if (IsFuture(from) && IsFuture(to)) { // future return(new Extraction { IsValid = true, Values = new[] { from, to } }); } var values = new[] { from, to }; return(new Extraction { IsValid = false, Values = values, ErrorMessage = PastValueErrorMessage.Replace("$moment$", MomentOrRangeToString(values)) }); } } return(new Extraction { IsValid = false, Values = Enumerable.Empty <DateTime>(), ErrorMessage = "I'm sorry, that doesn't seem to be a valid delivery date and time" }); }