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