It's a core bug, as @prkos mentioned, end time is assumed 00:00:00 when it needs to be 23:59:59
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_views_exposed_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if (!empty($form['created']['max'])) {
// use array_unshift() so custom submit runs before the default submit.
array_unshift($form['#submit'], '_fix_max_date_submit_function');
}
}
function _fix_max_date_submit_function($form, FormStateInterface $form_state) {
$date_filter = $form_state->getValue('created');
if ($date_filter['max']) {
$date_filter['max'] = $date_filter['max'] . ' 23:59:59';
$form_state->setValue('created', $date_filter);
}
}
Alternative solution
You might have to use this solution if you don't like the default Y-m-d
formatting and rather have a m/d/Y
input for example. Below I use Y-m-d
, but you can always change it.
It's a core bug, as @prkos mentioned, end time is assumed 12:00:00 AM when it needs to be 11:59:59 PM
If you enable Views sql query at /admin/structure/views/settings
you'll see the query is like:

So all you have to do is swap the last timestamp with the corrected timestamp that takes 11:59:59 PM into account.
You can do that with hook_views_query_alter, but hold your horses, this hook can only run inside of mymodule.views_execution.inc file, so create that file and then you can do
<?php
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;
/**
* Implements hook_views_query_alter()
*/
function mymodule_views_query_alter($view, $query) {
if (!empty($query->where[1]['conditions'])) {
foreach ($query->where[1]['conditions'] as $con_key => $con_val) {
$has_created_date_condition = strpos($con_val['field'], 'node_field_data.created') !== FALSE;
if (($has_created_date_condition)) {
// timezone set in /admin/config/regional/settings, will get "Users may set their own time zone" if checked.
$timezone = date_default_timezone_get();
$min_date = $view->exposed_data['created']['min'];
$min_date_obj = DrupalDateTime::createFromFormat('Y-m-d', $min_date, $timezone);
$min_date_timestamp = $min_date_obj->getTimestamp();
$max_date = $view->exposed_data['created']['max'];
$fixed_max_date_obj = DrupalDateTime::createFromFormat('Y-m-d h:i:s A', $max_date . ' 11:59:59 PM', $timezone);
$fixed_max_date_timestamp = $fixed_max_date_obj->getTimestamp();
$query->where[1]['conditions'][$con_key]['field'] = 'node_field_data.created';
$query->where[1]['conditions'][$con_key]['value'][0] = $min_date_timestamp;
$query->where[1]['conditions'][$con_key]['value'][1] = $fixed_max_date_timestamp;
$query->where[1]['conditions'][$con_key]['operator'] = 'BETWEEN';
}
}
}
}