in JavaScript/packages/recognizers-date-time/src/dateTime/baseDate.ts [392:591]
protected parseImplicitDate(source: string, referenceDate: Date): DateTimeResolutionResult {
let trimmedSource = source.trim();
let result = new DateTimeResolutionResult();
// handle "on 12"
let match = RegExpUtility.getMatches(this.config.onRegex, this.config.dateTokenPrefix + trimmedSource).pop();
if (match && match.index === this.config.dateTokenPrefix.length && match.length === trimmedSource.length) {
let day = 0;
let month = referenceDate.getMonth();
let year = referenceDate.getFullYear();
let dayStr = match.groups('day').value;
day = this.config.dayOfMonth.get(dayStr);
result.timex = DateTimeFormatUtil.luisDate(-1, -1, day);
let tryStr = DateTimeFormatUtil.luisDate(year, month, day);
let tryDate = Date.parse(tryStr);
let futureDate: Date;
let pastDate: Date;
if (tryDate && !isNaN(tryDate)) {
futureDate = DateUtils.safeCreateFromMinValue(year, month, day);
pastDate = DateUtils.safeCreateFromMinValue(year, month, day);
if (futureDate < referenceDate) {
futureDate.setMonth(futureDate.getMonth() + 1);
}
if (pastDate >= referenceDate) {
pastDate.setMonth(pastDate.getMonth() - 1);
}
}
else {
futureDate = DateUtils.safeCreateFromMinValue(year, month + 1, day);
pastDate = DateUtils.safeCreateFromMinValue(year, month - 1, day);
}
result.futureValue = futureDate;
result.pastValue = pastDate;
result.success = true;
return result;
}
// handle "today", "the day before yesterday"
match = RegExpUtility.getMatches(this.config.specialDayRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let swift = this.config.getSwiftDay(match.value);
let today = DateUtils.safeCreateFromMinValue(referenceDate.getFullYear(), referenceDate.getMonth(), referenceDate.getDate());
let value = DateUtils.addDays(today, swift);
result.timex = DateTimeFormatUtil.luisDateFromDate(value);
result.futureValue = value;
result.pastValue = value;
result.success = true;
return result;
}
// handle "two days from tomorrow"
match = RegExpUtility.getMatches(this.config.specialDayWithNumRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let swift = this.config.getSwiftDay(match.groups('day').value);
let numErs = this.config.integerExtractor.extract(trimmedSource);
let numOfDays = Number.parseInt(this.config.numberParser.parse(numErs[0]).value);
let value = DateUtils.addDays(referenceDate, swift + numOfDays);
result.timex = DateTimeFormatUtil.luisDateFromDate(value);
result.futureValue = value;
result.pastValue = value;
result.success = true;
return result;
}
// handle "two sundays from now"
match = RegExpUtility.getMatches(this.config.relativeWeekDayRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let numErs = this.config.integerExtractor.extract(trimmedSource);
let num = Number.parseInt(this.config.numberParser.parse(numErs[0]).value);
let weekdayStr = match.groups('weekday').value.toLowerCase();
let value = referenceDate;
// Check whether the determined day of this week has passed.
if (value.getDay() > this.config.dayOfWeek.get(weekdayStr)) {
num--;
}
while (num-- > 0) {
value = DateUtils.next(value, this.config.dayOfWeek.get(weekdayStr));
}
result.timex = DateTimeFormatUtil.luisDateFromDate(value);
result.futureValue = value;
result.pastValue = value;
result.success = true;
return result;
}
// handle "next Sunday"
match = RegExpUtility.getMatches(this.config.nextRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let weekdayStr = match.groups('weekday').value;
let value = DateUtils.next(referenceDate, this.config.dayOfWeek.get(weekdayStr));
result.timex = DateTimeFormatUtil.luisDateFromDate(value);
result.futureValue = value;
result.pastValue = value;
result.success = true;
return result;
}
// handle "this Friday"
match = RegExpUtility.getMatches(this.config.thisRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let weekdayStr = match.groups('weekday').value;
let value = DateUtils.this(referenceDate, this.config.dayOfWeek.get(weekdayStr));
result.timex = DateTimeFormatUtil.luisDateFromDate(value);
result.futureValue = value;
result.pastValue = value;
result.success = true;
return result;
}
// handle "last Friday", "last mon"
match = RegExpUtility.getMatches(this.config.lastRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let weekdayStr = match.groups('weekday').value;
let value = DateUtils.last(referenceDate, this.config.dayOfWeek.get(weekdayStr));
result.timex = DateTimeFormatUtil.luisDateFromDate(value);
result.futureValue = value;
result.pastValue = value;
result.success = true;
return result;
}
// handle "Friday"
match = RegExpUtility.getMatches(this.config.weekDayRegex, trimmedSource).pop();
if (match && match.index === 0 && match.length === trimmedSource.length) {
let weekdayStr = match.groups('weekday').value;
let weekday = this.config.dayOfWeek.get(weekdayStr);
let value = DateUtils.this(referenceDate, this.config.dayOfWeek.get(weekdayStr));
if (weekday === 0) {
weekday = 7;
}
if (weekday < referenceDate.getDay()) {
value = DateUtils.next(referenceDate, weekday);
}
result.timex = 'XXXX-WXX-' + weekday;
let futureDate = new Date(value);
let pastDate = new Date(value);
if (futureDate < referenceDate) {
futureDate.setDate(value.getDate() + 7);
}
if (pastDate >= referenceDate) {
pastDate.setDate(value.getDate() - 7);
}
result.futureValue = futureDate;
result.pastValue = pastDate;
result.success = true;
return result;
}
// handle "for the 27th."
match = RegExpUtility.getMatches(this.config.forTheRegex, trimmedSource).pop();
if (match) {
let dayStr = match.groups('DayOfMonth').value;
let er = ExtractResult.getFromText(dayStr);
let day = Number.parseInt(this.config.numberParser.parse(er).value);
let month = referenceDate.getMonth();
let year = referenceDate.getFullYear();
result.timex = DateTimeFormatUtil.luisDate(-1, -1, day);
let date = new Date(year, month, day);
result.futureValue = date;
result.pastValue = date;
result.success = true;
return result;
}
// handling cases like 'Thursday the 21st', which both 'Thursday' and '21st' refer to a same date
match = RegExpUtility.getMatches(this.config.weekDayAndDayOfMonthRegex, trimmedSource).pop();
if (match) {
let dayStr = match.groups('DayOfMonth').value;
let er = ExtractResult.getFromText(dayStr);
let day = Number.parseInt(this.config.numberParser.parse(er).value);
let month = referenceDate.getMonth();
let year = referenceDate.getFullYear();
// the validity of the phrase is guaranteed in the Date Extractor
result.timex = DateTimeFormatUtil.luisDate(year, month, day);
result.futureValue = new Date(year, month, day);
result.pastValue = new Date(year, month, day);
result.success = true;
return result;
}
return result;
}