Fuzzy date input

This control allows a user to record a date to three levels of detail - exact day, month+year or year only. It uses javascript to convert various input formats into yyyy-mm-dd, yyyy-mm or yyyy, & provide the user with confirmation. If an input is ambiguous (eg 01/02/2015) it asks the user for confirmation of the correct date.


This button doesn't do anything other than provide something to tab to.

Accepted input formats

Despite the label requesting a specific input format, users will inevitably ignore this and stick any old thing in it.

Numbers can be separated with a - / . , or any other non-alphanumeric character.

Days can be entered as one or two digits & will work with or without st/nd/rd/th suffix.

Months can be entered as one or two digits, or spelt in full (case insensitive) or just the first 3 letters & handles people who spell February as Febuary.

Given the above rules this control will handle the following date formats (items marked with a * will ask users to pick the correct date if the input is ambiguous):

Client side

View the source of this page for the commented javascript code. This can be minified to 2.6KB.

Server side

If your user base includes a lot of non-javascript users you could rewrite the client side code as server side, however I just use the following.:


<?php
  $DateVal=preg_replace('/\D+/','-',trim($_POST['InputDate']));
  if(empty($DateVal))
    {
      $DateText='';
    }
  else
    {
// Get component parts
      $DateBits=explode('-',$DateVal);

      if(preg_match('/^\d{4}-\d{2}-\d{2}$/',$DateVal) && checkdate($DateBits[1],$DateBits[2],$DateBits[0]))
        {
// Full date
          $DateText=date('jS F Y',strtotime($DateVal));
        }
      elseif(preg_match('/^\d{4}-\d{2}$/',$DateVal) && preg_match('/-(0[1-9]|1[0-2])$/',$DateVal))
        {
// Year + month
// MySQL's date datatype handles months as yyyy-mm-00
          $DateText=date('F Y',strtotime($DateVal.'-01'));
          $DateVal.='-00';
        }
      elseif(preg_match('/^\d{4}$/',$DateVal) && (int) $DateVal>1900)
        {
// Year only
// MySQL's date datatype handles years as yyyy-00-00
          $DateText=$DateVal;
          $DateVal.='-00-00';
        }
      else
       {
// error
          $Feedback='The input date must be a valid date in the format yyyy-mm-dd, yyyy-mm or yyyy.';
       }

    }
// Return $Feedback to user if invalid or store $DateVal to date field & store $DateText to varchar field
?>