How to detect the browser's format for input[type=date]

ideally there would be a function to get the date by a consistent "wire format"

There's a input.valueAsDate method which returns a Date object reflecting the input's current value.

According to experimentation (edit: with Chrome & Opera desktop versions on 2013-12-20), it appears that the displayed value of date inputs follows the same format as that returned by new Date().toLocaleDateString(), at least in Chrome.

There are then 3 representations of a date in action on the front-end:

  1. The Javascript date object
  2. The ISO date string for the input's attributes and ostensible value
  3. The date string represented to the user by the input.

To get any one of these from any of the other:

// From Javascript `Date` object to input value:
new Date().toISOString().substr( 0, 10 );

// From Javascript `Date` object to input display:
new Date().toLocaleDateString();

// From input value to Javascript `Date`:
input.valueAsDate;

// From input value to input display (step 3, then step 2):
input.valueAsDate.toLocaleDateString();

// From input display to Javascript `Date` object:
new Date( input.valueAsDate );

// From input display to input value (step 5, then step 1):
new Date( input.valueAsDate ).toISOString().substr( 0, 10 );

EDIT:

The above happens to work on Chrome. Desktop Safari 5.1.7 displays time in ISO format, meaning what you input is what the user sees. iOS Safari displays a dropdown with abbreviated month names in the format dd mmm yyyy. So it seems there is no standard.

Here's a little function that will give you the right conversions for desktop Chrome & Opera only:

var dateInput = ( function inputDateClosure(){
    // Type checking
    function getType( x ){
        return Object.prototype.toString.call( x );
    }

    function isDate( x ){
        return getType( x ) === '[object Date]';
    }

    function isInput( x ){
        return getType( x ) === '[object HTMLInputElement]' || '[object Object]' && Object.prototype.hasOwnProperty.call( x, 'value' );
    }

    function isString( x ){
        return getType( x ) === '[object String]';
    }

    function fromDateToValue( x ){
        return x.toISOString().substr( 0, 10 );
    }

    function fromDateToString( x ){
        return x.toLocaleDateString();
    }

    function fromInputToDate( x ){
        return x.valueAsDate;
    }

    function fromStringToDate( x ){
        return new Date( x.valueAsDate );
    }

    return function( x ){
        if( isDate( x ) ){
            return {
                asDate   :                   x,
                asValue  : fromDateToValue(  x ),
                asString : fromDateToString( x )
            }
        }
        else if( isString( x ) ){
            return {
                asDate   :                   fromStringToDate( x ),
                asValue  : fromDateToValue(  fromStringToDate( x ) ),
                asString : fromStringToDate( fromDateToString( x ) )
            }
        }
        else if( isInput( x ) ){
            return {
                asDate   :                   fromInputToDate( x ),
                asValue  : fromDateToValue(  fromInputToDate( x ) ),
                asString : fromDateToString( fromInputToDate( x ) )
            }
        }
    }
}() );