public function clean($value)
  {
    // First prune whitespace.
    $value = PruneWhitespaceCleaner::get()->clean($value);

    // If the value is empty return immediately.
    if ($value==='' || $value===null || $value===false)
    {
      return $this->openDate;
    }

    // First validate against ISO 8601.
    $match = preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})$/', $value, $parts);
    $valid = ($match && checkdate((int)$parts[2], (int)$parts[3], (int)$parts[1]));
    if ($valid)
    {
      $date = new \DateTime($value);

      return $date->format('Y-m-d');
    }

    // Replace alternative separators with the expected separator.
    if ($this->separator!==null && $this->alternativeSeparators!==null)
    {
      $value = strtr($value,
                     $this->alternativeSeparators,
                     str_repeat($this->separator[0], strlen($this->alternativeSeparators)));
    }

    // Validate against $format.
    $date = \DateTime::createFromFormat($this->format, $value);
    if ($date)
    {
      // Note: String '2000-02-30' will transformed to date '2000-03-01' with a warning. We consider this as an
      // invalid date.
      $tmp = $date::getLastErrors();
      if ($tmp['warning_count']==0) return $date->format('Y-m-d');
    }

    return $value;
  }