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:
- The Javascript date object
- The ISO date string for the input's attributes and ostensible value
- 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 ) )
}
}
}
}() );