The Problem
I know in the docs that AMAZON.DATE slot type defaults to look for future dates. As far as I can see there's no way for me to set it to past dates by default.
If that's the case, what can I do within my code to handle this?
Example
A simpler version of my case: fetch news articles from a specific day. With today's date (2021-11-14) a user says the following:
User Input | Intended Date | input_date |
diff = (input_date- today).days |
Handling |
---|---|---|---|---|
Get me news articles from last Wednesday | 2021-11-10 | 2021-11-10 | -4 | Accept as-is |
Get me news articles from November 10th 2021 | 2021-11-10 | 2021-11-10 | -4 | Accept as-is |
Get me Wednesday's news | 2021-11-10 | 2021-11-17 | 3 | Subtract 7 days |
Get me the news from November 10th | 2021-11-10 | 2022-11-10 | 361 | Returned date is in future: needs 1 year subtracted |
Get me the news for next week | 2022-11-15 | 2022-11-15 | 1 | Returned date is in future: user specifically asked for future news (for some reason), should give user friendly error response |
Near-Solution I've Tried
Here's a function I mocked up in Python for troubleshooting with some detailed comments:
def getArticleDate(input_date):
today = datetime.date.today()
diff = (input_date - today).days
if diff <= 0:
# === CASE A ===
# Condition: input_date is in the past
# Input: User must have been specific enough or used keyword like "last" or "previous"
# Example input: "from last Wednesday", or "June 19th 2021", or "in the previous month"
# Handling: None
return input_date
if diff <= 7:
# === CASE B ===
# Condition: input_date is up to a week in the future
# Input: User MIGHT have specified day of week
# Example input: "Wednesday" on any day but Wednesday
# Handling: Subtract 7 days
return input_date - datetime.timedelta(days=7)
if input_date.month == today.month and input_date.year == today.year:
# === CASE C ===
# Condition: input_date is within the same month and year as today, but more than 1 week in the future
# Input: User MIGHT have specified the day of the month but not the month
# Example input: "on the 21st"
# Handling: Get the last occurrance of that day of the month
# Note: Usually, but not necessarily the previous month, e.g. user says "on the 31st" on October 20th and there is no September 31st so must be July 31st
end_of_month = today
while end_of_month.day < input_date.day:
end_of_month = end_of_month.replace(day=1) - datetime.timedelta(days=1)
return end_of_month.replace(day=input_date.day)
if input_date.replace(year=input_date.year - 1) < today:
# === CASE D ===
# Condition: input_date is more than a week in the future but no more than 1 year
# Input: User MIGHT have specified day and a month, but not a year
# Example: "May 10th", or "on 27th September"
# Handling: Subtract 1 year
return input_date.replace(year=input_date.year - 1)
# === CASE E ===
# Condition: input_date is more than 1 year in the future
# Input: User must have specified a date more than 1 year in the future
# Example: "August 21st, 2022"
# Handling: Raise error
raise ValueError(
f"{input_date.isoformat()} is out of range."
)
This doesn't work in 2 cases:
- The user specifies a date less than a year in the future e.g. "tomorrow", or "next month", or "January 30th, 2022". Instead it is handled by
CASE B
,CASE C
, orCASE D
. - The user specifies a day of the month, but not the month, AND the
input_date
is less than a week in the future e.g. "from the 17th" on November 14th. This should be handled byCASE C
but instead is handled byCASE B
. Switching the order just reverses the problem, making weekday-specifying inputs handled byCASE C
instead ofCASE B
.
Thanks for any help, I've been really stuck on this!