如何检测浏览器的输入格式[type=date]

Posted

技术标签:

【中文标题】如何检测浏览器的输入格式[type=date]【英文标题】:How to detect the browser's format for input[type=date] 【发布时间】:2014-01-09 07:57:47 【问题描述】:

使用 javascript,如何检测日期输入字段 (input[type=date]) 中的日期格式?

Modernizr 之类的工具仅检测使用 html5 日期选择器的能力(尤其适用于移动设备,以及用于选择日期的 UI)。但是,我还没有找到任何关于检测浏览器使用的格式的解决方案。

我有一个这样的输入字段:

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

如果在 localStorage 中找到该值,则使用 jQuery 调用 .val() 输入该值。我认为由于 min 和 max 属性的有效日期格式采用有效的 ISO 格式,因此获取该字段的值将返回相同的格式。事实证明,它没有。

在以瑞典语为主要语言的 Chrome 浏览器 (31.0.1650.63 m) 上进行测试会得到 ISO 格式,但使用以丹麦语为主要语言的同一浏览器会将日期格式反转为 dd-mm-yyyy 而不是 yyyy-mm- dd。我怀疑其他语言环境也一样。

我不希望使用 change the input format - 理想情况下会有一个函数通过一致的 "wire format" 获取日期,但除了显示格式之外我没有找到任何方法。

如何检测输入字段的格式,并在 JS 中始终转换为有效的日期,然后再返回?

【问题讨论】:

当使用 javascript 获取值或使用表单提交时,HTML5 规范声称它应该始终采用 RFC 3339/ISO 8601 “有线格式”:YYYY-MM-DD,但是它是如何实现的显示给用户取决于浏览器,并且某些浏览器确实使用区域设置以用户本地日期格式显示日期。 @adeneo 谢谢,但我在没有发送表单的情况下获得了有效格式的值。这是针对 AJAX 调用的,因此该值由 Javascript 解析并作为参数添加到调用中。 【参考方案1】:

理想情况下,会有一个函数通过一致的“有线格式”获取日期

有一个input.valueAsDate 方法返回一个反映输入当前值的Date 对象。

根据实验(编辑:2013 年 12 月 20 日使用 Chrome 和 Opera 桌面版本),日期输入的 显示 值似乎遵循相同的格式正如new Date().toLocaleDateString() 返回的那样,至少在 Chrome 中是这样。

然后在前端有 3 种日期表示:

    Javascript 日期对象 输入属性和表面值的 ISO 日期字符串 输入表示给用户的日期字符串。

要从其他任何一个中获取其中任何一个:

// 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 );

编辑:

以上内容恰好适用于 Chrome。 Desktop Safari 5.1.7 以 ISO 格式显示时间,这意味着您输入的内容就是用户看到的内容。 ios Safari 以dd mmm yyyy 的格式显示带有缩写月份名称的下拉菜单。所以好像没有标准。

这里有一个小功能,可以为您提供仅适用于桌面 Chrome 和 Opera 的正确转换:

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 ) )
            
        
    
() );

【讨论】:

很好的答案,至少对于读取值的部分。我将进一步研究 valueAsDate,以前没有见过。谢谢! @Calle 多玩一点,我想我可能已经解决了你的问题。检查编辑! 谢谢 - 在这种情况下,您会建议哪种转换方法? @Calle 原来这只适用于现代 Chrome 和 Opera:Safari 桌面显示 ISO 字符串,iOS Safari 是非标准的。 非常感谢您对此进行如此详细的调查。我很感激反馈。我将在移动设备上进行额外的测试。【参考方案2】:

我想我有一个更简单的解决方案。不确定它是否适用于任何浏览器,但假设 javascript 日期函数使用相同的本地格式,这将起作用:

 $(".date").on("change", function () 
      var selectedDate = new Date(jQuery(this).val());

      var selectedDateFormat = selectedDate.toLocaleDateString()
          .replace(selectedDate.getDate(), "DD")
          .replace(selectedDate.getMonth()+1, "MM")
          .replace(selectedDate.getFullYear(), "YYYY");

           console.log(selectedDateFormat);
 );

但无论如何,到达这一点我们可能不需要这个,因为关键是使用任何浏览器日期格式,如果我没有错,就以我们想要的格式发送它。在这种情况下,我会以另一种方式进行,如下所示:

$(".date").on("change", function () 
   var selectedDate = new Date(jQuery(this).val());
   this.setAttribute('value', 
   (selectedDate.getMonth() + 1) +
   '/' + selectedDate.getDate() +
   '/' + selectedDate.getFullYear());
);

【讨论】:

以上是关于如何检测浏览器的输入格式[type=date]的主要内容,如果未能解决你的问题,请参考以下文章

如何在所有浏览器中使用 input type=date

处理浏览器对 HTML 输入 type="date" 的特定支持

在浏览器支持不可用的情况下,为 input type="date" 添加 javascript 回退

如何在 chrome 中更改 <input type=date> 的外观

如何检测chrome浏览器[重复]

HTML5日期时间输入类型注意事项(time,date)