Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Using Javascript, how would it be possible to detect the format of dates in date input fields (input[type=date])?

Tools like Modernizr only detect the capability of using an HTML5 datepicker (desirable especially for mobile devices, and their UI for selecting dates). However, I haven't been able to find any solution on detecting the format used by the browser.

I have an input field like this:

<input type="date" class="border-radius" min="2013-12-21" max="2015-12-20" data-persist-local="FromDate">

The value is entered with a jQuery call .val() if it's found in localStorage. I thought that since valid date formats for min and max attributes are in valid ISO format, getting the value of the field would return the same format. It turns out, it doesn't.

Testing on a Chrome browser (31.0.1650.63 m) with Swedish as primary language gives the ISO format, but using the same browser with Danish as primary language reverses the date format to dd-mm-yyyy instead of yyyy-mm-dd. I suspect it's the same for other locales.

I'm not looking to change the input format - and ideally there would be a function to get the date by a consistent "wire format" but I haven't found a way to get anything but the display format.

How do I detect the format of the input field, and consistently convert to a valid Date in JS, and back again?

like image 804
Calle Avatar asked Dec 20 '13 12:12

Calle


People also ask

How do I display the date format in input?

To set and get the input type date in dd-mm-yyyy format we will use <input> type attribute. The <input> type attribute is used to define a date picker or control field. In this attribute, you can set the range from which day-month-year to which day-month-year date can be selected from.

What is the format of input type date?

dd/mm/yyyy.

How do I make input type date support on all browsers?

Just use <script src="modernizr. js"></script> in the <head> section, and the script will add classes which help you to separate the two cases: if it's supported by the current browser, or if it's not. Save this answer.

Is input type date accessible?

HTML5 input type="date" will give you an accessible date picker in most browsers, but not all like Safari macOS where native datepickers are not supported yet.


1 Answers

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 ) )
            }
        }
    }
}() );
like image 123
Barney Avatar answered Oct 28 '22 18:10

Barney