API4 dates entered without time can give unexpected results
For a datetime field, any date in an API call is converted to a datetime (midnight on the date in question). This can give unexpected results for gets, especially using Search Kit or Form Builder, where users probably aren't thinking about dates versus datetimes. These results also aren't consistent with what you get from Advanced Search or other searches.
For example, searching for a contribution with receive_date = 2022-01-01 does not return all contributions received on that date. It only returns contributions received at exactly midnight, i.e. with receive_date = 20220101000000.
Similar issues exist for other operators, like !=, > (will include the date), <= (won't include the date), BETWEEN and NOT BETWEEN (will include the from date, but not the to date), and IN and NOT IN.
The simplest solution would be to put a SQL DATEFORMAT() around the database date field when the date does not include a time and use a Ymd format. This wouldn't work for BETWEEN or IN when one date includes a time and the other doesn't though.
Or if we don't want to change the query, another approach would be to check absolute dates entered into the API to see if they include a time component or not.
- If they include a time, proceed as usual.
- If they don't include times, for all operators except = and !=/<>, set the time component or components depending on the operator (e.g. for BETWEEN set 000000 for the from date, 235959 for the to date).
- For = or !=, switch the operator to BETWEEN or NOT BETWEEN, set the from date to 000000 and the to date to 235959.
- For IN and NOT IN, I'm not sure there's an easy solution in this case. We'd have to convert that to a series of BETWEENs and that's going to be difficult. Is there a good way to warn users that this won't work?
- Not sure what the other operators are supposed to do with dates.
But maybe there's a more elegant solution to this problem. Hoping to get some expert feedback before starting any work on this, since date stuff can be such a quagmire.