diff --git a/core/modules/views/config/schema/views.filter.schema.yml b/core/modules/views/config/schema/views.filter.schema.yml
index e411489..09f0278 100644
--- a/core/modules/views/config/schema/views.filter.schema.yml
+++ b/core/modules/views/config/schema/views.filter.schema.yml
@@ -38,6 +38,9 @@ views.filter_value.date:
     type:
       type: string
       label: 'Type'
+    widget:
+      type: string
+      label: 'Widget'
 
 views.filter_value.groupby_numeric:
   type: views.filter_value.numeric
diff --git a/core/modules/views/src/Plugin/views/filter/Date.php b/core/modules/views/src/Plugin/views/filter/Date.php
index 84a1c42..4410e94 100644
--- a/core/modules/views/src/Plugin/views/filter/Date.php
+++ b/core/modules/views/src/Plugin/views/filter/Date.php
@@ -18,6 +18,7 @@ protected function defineOptions() {
 
     // value is already set up properly, we're just adding our new field to it.
     $options['value']['contains']['type']['default'] = 'date';
+    $options['value']['contains']['widget']['default'] = 'datetime';
 
     return $options;
   }
@@ -36,6 +37,21 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
         ),
         '#default_value' => !empty($this->value['type']) ? $this->value['type'] : 'date',
       );
+
+      $form['value']['widget'] = array(
+        '#type' => 'radios',
+        '#title' => $this->t('Widget'),
+        '#options' => array(
+          'datetime' => $this->t('Date and time'),
+          'date' => $this->t('Date only'),
+        ),
+        '#default_value' => !empty($this->value['widget']) ? $this->value['widget'] : 'datetime',
+        '#states' => array(
+          'visible' => array(
+            ':input[name="options[value][type]"]' => array('value' => 'date'),
+          ),
+        ),
+      );
     }
     parent::valueForm($form, $form_state);
   }
@@ -174,4 +190,23 @@ protected function opSimple($field) {
     $this->query->addWhereExpression($this->options['group'], "$field $this->operator $value");
   }
 
+  /**
+   * Override parent method to change input type.
+   */
+  public function buildExposedForm(&$form, FormStateInterface $form_state) {
+    parent::buildExposedForm($form, $form_state);
+
+    if ($this->value['type'] == 'date') {
+      $field_identifier = $this->options['expose']['identifier'];
+
+      if ($this->operator == 'between') {
+        $form[$field_identifier]['min']['#type'] = $this->value['widget'];
+        $form[$field_identifier]['max']['#type'] = $this->value['widget'];
+      }
+      else {
+        $form[$field_identifier]['#type'] = $this->value['widget'];
+      }
+    }
+  }
+
 }
diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
index 5c2a8d8..bcd0973 100644
--- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -131,9 +131,11 @@ protected function defineOptions() {
         'required' => array('default' => FALSE),
         'remember' => array('default' => FALSE),
         'multiple' => array('default' => FALSE),
-        'remember_roles' => array('default' => array(
-          RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID,
-        )),
+        'remember_roles' => array(
+          'default' => array(
+            RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID,
+          )
+        ),
       ),
     );
 
@@ -174,7 +176,9 @@ public function adminSummary() {
   /**
    * Determine if a filter can be exposed.
    */
-  public function canExpose() { return TRUE; }
+  public function canExpose() {
+    return TRUE;
+  }
 
   /**
    * Determine if a filter can be converted into a group.
@@ -302,18 +306,22 @@ protected function operatorForm(&$form, FormStateInterface $form_state) {
    * Provide a list of options for the default operator form.
    * Should be overridden by classes that don't override operatorForm
    */
-  public function operatorOptions() { return array(); }
+  public function operatorOptions() {
+    return array();
+  }
 
   /**
    * Validate the operator form.
    */
-  protected function operatorValidate($form, FormStateInterface $form_state) { }
+  protected function operatorValidate($form, FormStateInterface $form_state) {
+  }
 
   /**
    * Perform any necessary changes to the form values prior to storage.
    * There is no need for this function to actually store the data.
    */
-  public function operatorSubmit($form, FormStateInterface $form_state) { }
+  public function operatorSubmit($form, FormStateInterface $form_state) {
+  }
 
   /**
    * Shortcut to display the value form.
@@ -341,13 +349,15 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
   /**
    * Validate the options form.
    */
-  protected function valueValidate($form, FormStateInterface $form_state) { }
+  protected function valueValidate($form, FormStateInterface $form_state) {
+  }
 
   /**
    * Perform any necessary changes to the form values prior to storage.
    * There is no need for this function to actually store the data.
    */
-  protected function valueSubmit($form, FormStateInterface $form_state) { }
+  protected function valueSubmit($form, FormStateInterface $form_state) {
+  }
 
   /**
    * Shortcut to display the exposed options form.
@@ -509,7 +519,10 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) {
     // prior to rendering. That's why the preRender for it needs to run first,
     // so that when the next preRender (the one for fieldsets) runs, it gets
     // the flattened data.
-    array_unshift($form['#pre_render'], array(get_class($this), 'preRenderFlattenData'));
+    array_unshift($form['#pre_render'], array(
+      get_class($this),
+      'preRenderFlattenData'
+    ));
     $form['expose']['#flatten'] = TRUE;
 
     if (empty($this->always_required)) {
@@ -614,7 +627,11 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) {
    * Validate the options form.
    */
   public function validateExposeForm($form, FormStateInterface $form_state) {
-    $identifier = $form_state->getValue(array('options', 'expose', 'identifier'));
+    $identifier = $form_state->getValue(array(
+      'options',
+      'expose',
+      'identifier'
+    ));
     $this->validateIdentifier($identifier, $form_state, $form['expose']['identifier']);
   }
 
@@ -655,11 +672,20 @@ protected function hasValidGroupedValue(array $group) {
    */
   protected function buildGroupValidate($form, FormStateInterface $form_state) {
     if (!$form_state->isValueEmpty(array('options', 'group_info'))) {
-      $identifier = $form_state->getValue(array('options', 'group_info', 'identifier'));
+      $identifier = $form_state->getValue(array(
+        'options',
+        'group_info',
+        'identifier'
+      ));
       $this->validateIdentifier($identifier, $form_state, $form['group_info']['identifier']);
     }
 
-    if ($group_items = $form_state->getValue(array('options', 'group_info', 'group_items'))) {
+    if ($group_items = $form_state->getValue(array(
+      'options',
+      'group_info',
+      'group_items'
+    ))
+    ) {
       foreach ($group_items as $id => $group) {
         if (empty($group['remove'])) {
           $has_valid_value = $this->hasValidGroupedValue($group);
@@ -721,8 +747,15 @@ protected function validateIdentifier($identifier, FormStateInterface $form_stat
    */
   protected function buildGroupSubmit($form, FormStateInterface $form_state) {
     $groups = array();
-    $group_items = $form_state->getValue(array('options', 'group_info', 'group_items'));
-    uasort($group_items, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
+    $group_items = $form_state->getValue(array(
+      'options',
+      'group_info',
+      'group_items'
+    ));
+    uasort($group_items, array(
+      'Drupal\Component\Utility\SortArray',
+      'sortByWeightElement'
+    ));
     // Filter out removed items.
 
     // Start from 1 to avoid problems with #default_value in the widget.
@@ -735,19 +768,40 @@ protected function buildGroupSubmit($form, FormStateInterface $form_state) {
         unset($group['weight']);
         $groups[$new_id] = $group;
 
-        if ($form_state->getValue(array('options', 'group_info', 'default_group')) == $id) {
+        if ($form_state->getValue(array(
+            'options',
+            'group_info',
+            'default_group'
+          )) == $id
+        ) {
           $new_default = $new_id;
         }
       }
       $new_id++;
     }
     if ($new_default != 'All') {
-      $form_state->setValue(array('options', 'group_info', 'default_group'), $new_default);
-    }
-    $filter_default_multiple = $form_state->getValue(array('options', 'group_info', 'default_group_multiple'));
-    $form_state->setValue(array('options', 'group_info', 'default_group_multiple'), array_filter($filter_default_multiple));
-
-    $form_state->setValue(array('options', 'group_info', 'group_items'), $groups);
+      $form_state->setValue(array(
+        'options',
+        'group_info',
+        'default_group'
+      ), $new_default);
+    }
+    $filter_default_multiple = $form_state->getValue(array(
+      'options',
+      'group_info',
+      'default_group_multiple'
+    ));
+    $form_state->setValue(array(
+      'options',
+      'group_info',
+      'default_group_multiple'
+    ), array_filter($filter_default_multiple));
+
+    $form_state->setValue(array(
+      'options',
+      'group_info',
+      'group_items'
+    ), $groups);
   }
 
   /**
@@ -890,7 +944,10 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form
     // prior to rendering. That's why the preRender for it needs to run first,
     // so that when the next preRender (the one for fieldsets) runs, it gets
     // the flattened data.
-    array_unshift($form['#pre_render'], array(get_class($this), 'preRenderFlattenData'));
+    array_unshift($form['#pre_render'], array(
+      get_class($this),
+      'preRenderFlattenData'
+    ));
     $form['group_info']['#flatten'] = TRUE;
 
     if (!empty($this->options['group_info']['identifier'])) {
@@ -999,7 +1056,14 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form
     // After the general settings, comes a table with all the existent groups.
     $default_weight = 0;
     foreach ($this->options['group_info']['group_items'] as $item_id => $item) {
-      if (!$form_state->isValueEmpty(array('options', 'group_info', 'group_items', $item_id, 'remove'))) {
+      if (!$form_state->isValueEmpty(array(
+        'options',
+        'group_info',
+        'group_items',
+        $item_id,
+        'remove'
+      ))
+      ) {
         continue;
       }
       // Each rows contains three widgets:
@@ -1196,7 +1260,6 @@ protected function exposedTranslate(&$form, $type) {
   }
 
 
-
   /**
    * Sanitizes the HTML select element's options.
    *
@@ -1404,7 +1467,12 @@ public function acceptExposedInput($input) {
         }
       }
       if (isset($value)) {
-        $this->value = $value;
+        if (!is_array($value)) {
+          $this->value = $value;
+        }
+        else {
+          $this->value = array_merge($this->value, $value);
+        }
         if (empty($this->alwaysMultiple) && empty($this->options['expose']['multiple']) && !is_array($value)) {
           $this->value = array($value);
         }
diff --git a/core/modules/views/src/Tests/Handler/FilterDateTest.php b/core/modules/views/src/Tests/Handler/FilterDateTest.php
index 2045b8a..99846ba 100644
--- a/core/modules/views/src/Tests/Handler/FilterDateTest.php
+++ b/core/modules/views/src/Tests/Handler/FilterDateTest.php
@@ -16,7 +16,7 @@ class FilterDateTest extends HandlerTestBase {
    *
    * @var array
    */
-  public static $testViews = array('test_filter_date_between');
+  public static $testViews = array('test_filter_date_between', 'test_filter_date_between_exposed');
 
   /**
    * Modules to enable.
@@ -136,6 +136,95 @@ protected function _testBetween() {
   }
 
   /**
+   * Make sure the exposed date filters work.
+   */
+  protected function _testFilterDate() {
+    $this->drupalLogin($this->drupalCreateUser(array('access content')));
+
+    // Test the exposed "=" filter.
+    $this->drupalGet('test-filter-date-exposed');
+
+    // Verify that exposed input elements exists in the output with the proper
+    // types.
+    $this->assertFieldByXPath('//input[@id="edit-created-date" and @type="date"]', '', 'Found date input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-time" and @type="time"]', '', 'Found time input element.');
+
+    // Verify the node list.
+    $this->assertText($this->nodes[0]->getTitle());
+    $this->assertText($this->nodes[1]->getTitle());
+    $this->assertText($this->nodes[2]->getTitle());
+    $this->assertText($this->nodes[3]->getTitle());
+
+    // Apply the filter.
+    $timezone = $this->config('system.date')->get('timezone.default');
+    $created = $this->nodes[1]->getCreatedTime();
+    $date = format_date($created, 'custom', 'Y-m-d', $timezone);
+    $time = format_date($created, 'custom', 'H:i:s', $timezone);
+
+    $edit = [
+      'created[date]' => $date,
+      'created[time]' => $time,
+    ];
+
+    $this->drupalGet('test-filter-date-exposed', ['query' => $edit]);
+
+    // Verify the exposed inputs have the values being filtered on.
+    $this->assertFieldByXPath('//input[@id="edit-created-date" and @type="date"]', $date, 'Found populated date input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-time" and @type="time"]', $time, 'Found populated time input element.');
+
+    // Verify the node list.
+    $this->assertNoText($this->nodes[0]->getTitle());
+    $this->assertText($this->nodes[1]->getTitle());
+    $this->assertNoText($this->nodes[2]->getTitle());
+    $this->assertNoText($this->nodes[3]->getTitle());
+
+    // Test the exposed "between" filter.
+    $this->drupalGet('test-filter-date-between-exposed');
+
+    // Verify that exposed input elements exists in the output with the proper
+    // types.
+    $this->assertFieldByXPath('//input[@id="edit-created-min-date" and @type="date"]', '', 'Found min date input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-min-time" and @type="time"]', '', 'Found min time input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-max-date" and @type="date"]', '', 'Found max date input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-max-time" and @type="time"]', '', 'Found max time input element.');
+
+    // Verify the node list.
+    $this->assertText($this->nodes[0]->getTitle());
+    $this->assertText($this->nodes[1]->getTitle());
+    $this->assertText($this->nodes[2]->getTitle());
+    $this->assertText($this->nodes[3]->getTitle());
+
+    // Apply the filter.
+    $timezone = $this->config('system.date')->get('timezone.default');
+    $created = $this->nodes[1]->getCreatedTime();
+    $min_date = format_date($created - 3600, 'custom', 'Y-m-d', $timezone);
+    $min_time = format_date($created - 3600, 'custom', 'H:i:s', $timezone);
+    $max_date = format_date($created + 3600, 'custom', 'Y-m-d', $timezone);
+    $max_time = format_date($created + 3600, 'custom', 'H:i:s', $timezone);
+
+    $edit = [
+      'created[min][date]' => $min_date,
+      'created[min][time]' => $min_time,
+      'created[max][date]' => $max_date,
+      'created[max][time]' => $max_time,
+    ];
+
+    $this->drupalGet('test-filter-date-between-exposed', ['query' => $edit]);
+
+    // Verify the exposed inputs have the values being filtered on.
+    $this->assertFieldByXPath('//input[@id="edit-created-min-date" and @type="date"]', $min_date, 'Found populated min date input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-min-time" and @type="time"]', $min_time, 'Found populated min time input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-max-date" and @type="date"]', $max_date, 'Found populated max date input element.');
+    $this->assertFieldByXPath('//input[@id="edit-created-max-time" and @type="time"]', $max_time, 'Found populated max time input element.');
+
+    // Verify the node list.
+    $this->assertNoText($this->nodes[0]->getTitle());
+    $this->assertText($this->nodes[1]->getTitle());
+    $this->assertNoText($this->nodes[2]->getTitle());
+    $this->assertNoText($this->nodes[3]->getTitle());
+  }
+
+  /**
    * Make sure the validation callbacks works.
    */
   protected function _testUiValidation() {
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between_exposed.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between_exposed.yml
new file mode 100644
index 0000000..5a3a613
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between_exposed.yml
@@ -0,0 +1,322 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+    - user
+id: test_filter_date_between_exposed
+label: test_filter_date_between_exposed
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: mini
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: ‹‹
+            next: ››
+      style:
+        type: default
+      row:
+        type: fields
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+      filters:
+        status:
+          value: '1'
+          table: node_field_data
+          field: status
+          plugin_id: boolean
+          entity_type: node
+          entity_field: status
+          id: status
+          expose:
+            operator: ''
+          group: 1
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: '='
+          value:
+            min: ''
+            max: ''
+            value: ''
+            type: date
+            widget: datetime
+          group: 1
+          exposed: true
+          expose:
+            operator_id: created_op
+            label: 'Authored on'
+            description: ''
+            use_operator: false
+            operator: created_op
+            identifier: created
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          order: ASC
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      title: test_filter_date_exposed
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      tags: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: test-filter-date-exposed
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      tags: {  }
+  page_2:
+    display_plugin: page
+    id: page_2
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: test-filter-date-between-exposed
+      filters:
+        status:
+          value: '1'
+          table: node_field_data
+          field: status
+          plugin_id: boolean
+          entity_type: node
+          entity_field: status
+          id: status
+          expose:
+            operator: ''
+          group: 1
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: between
+          value:
+            min: ''
+            max: ''
+            value: ''
+            type: date
+            widget: datetime
+          group: 1
+          exposed: true
+          expose:
+            operator_id: created_op
+            label: 'Authored on'
+            description: ''
+            use_operator: false
+            operator: created_op
+            identifier: created
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      defaults:
+        filters: false
+        filter_groups: false
+      filter_groups:
+        operator: AND
+        groups:
+          1: AND
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      tags: {  }
