diff --git a/src/Plugin/facetapi/widget/DateRangeWidget.php b/src/Plugin/facetapi/widget/DateRangeWidget.php
new file mode 100644
index 0000000..4b1ed83
--- /dev/null
+++ b/src/Plugin/facetapi/widget/DateRangeWidget.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Drupal\facetapi\Plugin\facetapi\Widget;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\facetapi\FacetInterface;
+use Drupal\facetapi\Result\Result;
+use Drupal\facetapi\Widget\WidgetInterface;
+use Drupal\search_api\Plugin\facetapi\query_type\SearchApiDate;
+
+/**
+ * @FacetApiWidget(
+ *   id = "date_range",
+ *   label = @Translation("Date range widget"),
+ *   description = @Translation("Date range wiget"),
+ * )
+ */
+class DateRangeWidget implements WidgetInterface {
+
+
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    // Execute all the things.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(FacetInterface $facet) {
+    /** @var Result[] $results */
+    $results = $facet->getResults();
+    $items = [];
+    foreach ($results as $result) {
+      if ($result->getCount()) {
+        // Get the link.
+        $text = $result->getDisplayValue() . ' (' . $result->getCount() . ')';
+        if ($result->isActive()) {
+          $text = '(-) ' . $text;
+        }
+        $link_generator = \Drupal::linkGenerator();
+        $link = $link_generator->generate($text, $result->getUrl());
+        $items[] = $link;
+      }
+    }
+    $build = [
+      '#theme' => 'item_list',
+      '#items' => $items,
+    ];
+
+    $build['#prefix'] = $this->t('Date widget');
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state, $config) {
+
+    $options = [
+      SearchApiDate::FACETAPI_DATE_YEAR => $this->t('Year'),
+      SearchApiDate::FACETAPI_DATE_MONTH => $this->t('Month'),
+      SearchApiDate::FACETAPI_DATE_DAY => $this->t('Day'),
+      SearchApiDate::FACETAPI_DATE_HOUR => $this->t('Hour'),
+      SearchApiDate::FACETAPI_DATE_MINUTE => $this->t('Minute'),
+      SearchApiDate::FACETAPI_DATE_SECOND => $this->t('Seconds'),
+    ];
+
+    $form['granularity'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Granularity'),
+      '#description' => $this->t('Determine the maximum drill-down level.'),
+      '#options' => $options,
+      '#required' => TRUE,
+    ];
+
+    if (!is_null($config)) {
+      $widget_configs = $config->get('widget_configs');
+      if (isset($widget_configs['granularity'])) {
+        $form['granularity']['#default_value'] = $widget_configs['granularity'];
+      }
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQueryType($query_types) {
+    return $query_types['date'];
+  }
+
+}
diff --git a/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php b/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
index 4534507..3126c2b 100644
--- a/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
+++ b/src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
@@ -153,6 +153,7 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
     // Add additional query types for specific data types.
     switch ($data_type_plugin_id) {
       case 'date':
+      case 'date_range':
         $query_types['date'] = 'search_api_date';
         break;
 
diff --git a/src/Plugin/facets/query_type/SearchApiDate.php b/src/Plugin/facets/query_type/SearchApiDate.php
index ff03f37..d0e76d6 100644
--- a/src/Plugin/facets/query_type/SearchApiDate.php
+++ b/src/Plugin/facets/query_type/SearchApiDate.php
@@ -54,10 +54,42 @@ class SearchApiDate extends QueryTypeRangeBase {
   const FACETAPI_DATE_SECOND = 1;
 
   /**
+   * Constant for grouping on year.
+   */
+  const FACETAPI_LAST_YEAR = 'last_year';
+
+  /**
+   * Constant for grouping on month.
+   */
+  const FACETAPI_LAST_MONTH = 'last_month';
+
+  /**
+   * Constant for grouping on day.
+   */
+  const FACETAPI_LAST_DAY = 'last_day';
+
+  /**
+   * Constant for grouping on hour.
+   */
+  const FACETAPI_CUSTOM = 'custom';
+
+  /**
    * {@inheritdoc}
    */
   public function calculateRange($value) {
-    if ($this->getDisplayRelative()) {
+    if ($value == static::FACETAPI_LAST_DAY) {
+      $dateTime = new DrupalDateTime('-1 day');
+      return $this->calculateRangeRelativeToNow($dateTime->format('U'));
+    }
+    elseif($value == static::FACETAPI_LAST_MONTH) {
+      $dateTime = new DrupalDateTime('-1 month');
+      return $this->calculateRangeRelativeToNow($dateTime->format('U'));
+    }
+    elseif($value == static::FACETAPI_LAST_YEAR) {
+      $dateTime = new DrupalDateTime('-1 year');
+      return $this->calculateRangeRelativeToNow($dateTime->format('U'));
+    }
+    elseif ($this->getDisplayRelative()) {
       return $this->calculateRangeRelative($value);
     }
     else {
@@ -190,6 +222,33 @@ class SearchApiDate extends QueryTypeRangeBase {
   }
 
   /**
+   * Returns a start and end date based on a unix timestamp.
+   *
+   * This method returns a start and end date with an relative interval, based
+   * on the granularity set in the widget.
+   *
+   * @param int $value
+   *   Unix timestamp.
+   *
+   * @return array
+   *   An array with a start and end date as unix timestamps.
+   *
+   * @throws \Exception
+   *   Thrown when creating a date fails.
+   */
+  protected function calculateRangeRelativeToNow($value) {
+    $dateTime = new DrupalDateTime();
+    $startDate = $dateTime::createFromTimestamp($value);
+    $stopDate = clone $startDate;
+    $stopDate->add(new \DateInterval('P1Y'));
+    $stopDate->sub(new \DateInterval('PT1S'));
+    return [
+      'start' => $startDate->format('U'),
+      'stop' => $stopDate->format('U'),
+    ];
+  }
+
+  /**
    * Calculates the result of the filter.
    *
    * @param int $value
@@ -199,7 +258,19 @@ class SearchApiDate extends QueryTypeRangeBase {
    *   An array with a start and end date as unix timestamps.
    */
   public function calculateResultFilter($value) {
-    if ($this->getDisplayRelative()) {
+    if ($value == static::FACETAPI_LAST_DAY) {
+      $dateTime = new DrupalDateTime('-1 day');
+      return $this->calculateResultFilterRelative($dateTime->format('U'));
+    }
+    elseif($value == static::FACETAPI_LAST_MONTH) {
+      $dateTime = new DrupalDateTime('-1 month');
+      return $this->calculateResultFilterRelative($dateTime->format('U'));
+    }
+    elseif($value == static::FACETAPI_LAST_YEAR) {
+      $dateTime = new DrupalDateTime('-1 year');
+      return $this->calculateResultFilterRelative($dateTime->format('U'));
+    }
+    elseif ($this->getDisplayRelative()) {
       return $this->calculateResultFilterRelative($value);
     }
     else {
@@ -264,7 +335,6 @@ class SearchApiDate extends QueryTypeRangeBase {
     $now->setTimestamp(REQUEST_TIME);
     $interval = $date->diff($now);
     $future = $date > $now;
-
     switch ($this->getGranularity()) {
       case static::FACETAPI_DATE_YEAR:
         $rounded = new \DateInterval('P' . $interval->y . 'Y');
diff --git a/src/Plugin/facets/widget/DateRangeWidget.php b/src/Plugin/facets/widget/DateRangeWidget.php
new file mode 100644
index 0000000..0472f2d
--- /dev/null
+++ b/src/Plugin/facets/widget/DateRangeWidget.php
@@ -0,0 +1,132 @@
+<?php
+
+namespace Drupal\facets\Plugin\facets\widget;
+
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\facets\FacetInterface;
+use Drupal\facets\Widget\WidgetInterface;
+use Drupal\facets\Plugin\facets\query_type\SearchApiDate;
+use Drupal\Core\Link;
+use Drupal\Core\Datetime\DrupalDateTime;
+
+/**
+ * Date range widget.
+ *
+ * @FacetsWidget(
+ *   id = "date_range",
+ *   label = @Translation("Date range widget"),
+ *   description = @Translation("Date range wiget"),
+ * )
+ */
+class DateRangeWidget extends DateBasicWidget {
+
+
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'display_relative' =>  TRUE,
+      'granularity' => SearchApiDate::FACETAPI_DATE_SECOND,
+      'date_display' => '',
+      'relative_granularity' => 1,
+      'relative_text' => TRUE,
+    ] + parent::defaultConfiguration();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    // Execute all the things.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(FacetInterface $facet) {
+    // Set facet for later.
+    $this->facet = $facet;
+    // Get the range sorting items.
+    $rangeOptions = $this->getDateRangeOptions();
+    // Get facet url alias.
+    $alias = $facet->getUrlAlias();
+    // Get first result to extract url.
+    $firstItem = current($facet->getResults());
+    // Build list items.
+    $items = [];
+    foreach ($rangeOptions as $key => $text) {
+      $url = $this->getUrl($alias, $key, $firstItem);
+      $classes = ['facet-item'];
+      $item = (new Link($text, $url))->toRenderable();
+      $item['#wrapper_attributes'] = ['class' => $classes];
+      $item['#attributes']['data-drupal-facet-item-id'] = $alias . '-' . $key;
+      //$item['#attributes'] = ['class' => 'active-trail'];
+      $items[] = $item;
+    }
+    $format = 'Y-m-d H:i';
+    $dateTime = new DrupalDateTime();
+    $return = [
+      'list' => [
+        '#theme' => 'item_list',
+        '#items' => $items,
+        '#attributes' => ['data-drupal-facet-id' => $facet->id()],
+        '#cache' => [
+          'contexts' => [
+            'url.path',
+            'url.query_args',
+          ],
+        ],
+      ],
+      'custom_start' => [
+        '#title' => $this->t('Start'),
+        '#type' => 'date_select', // types 'date_text' and 'date_timezone' are also supported. See .inc file.
+        '#default_value' => $dateTime->format($format),
+        '#date_format' => $format,
+        '#date_label_position' => 'within', // See other available attributes and what they do in date_api_elements.inc
+        '#date_timezone' => 'America/Chicago', // Optional, if your date has a timezone other than the site timezone.
+        '#date_increment' => 15, // Optional, used by the date_select and date_popup elements to increment minutes and seconds.
+        '#date_year_range' => '-3:+3', // Optional, used to set the year range (back 3 years and forward 3 years is the default).
+      ],
+      'custom_end' => [
+        '#theme' => 'date_select',
+        '#title' => $this->t('End'),
+      ],
+    ];
+    // Add custom selection.
+    return $return;
+  }
+
+  protected function getUrl($alias, $value, $result) {
+    $url = clone $result->getUrl();
+    $alias_value = $alias . ':' . $value;
+    $options = $url->getOptions();
+    foreach ($options['query']['f'] as $key => $fragment) {
+      if(strpos($fragment, $alias) !== FALSE) {
+        unset($options['query']['f'][$key]);
+      }
+    }
+    $options['query']['f'][] = $alias_value;
+    $options['query']['f'] = array_values($options['query']['f']);
+    $url->setOptions($options);
+    return $url;
+  }
+
+  public function getDateRangeOptions() {
+    return [
+      SearchApiDate::FACETAPI_LAST_DAY => $this->t('Last day'),
+      SearchApiDate::FACETAPI_LAST_MONTH => $this->t('Last month'),
+      SearchApiDate::FACETAPI_LAST_YEAR => $this->t('Last year'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQueryType($query_types) {
+    return $query_types['date'];
+  }
+
+}
