【问题标题】:Safari JS cannot parse YYYY-MM-DD date format?Safari JS 无法解析 YYYY-MM-DD 日期格式?
【发布时间】:2011-03-06 09:11:27
【问题描述】:

在我正在进行的项目中,我需要验证输入到 <input type="date"> 中的日期

对于 Safari 4/5(在 Mac OSX 上),Javascript 无法解析 YYYY-MM-DD 格式的日期,返回 NaN 而不是预期的纪元时间戳。

我正在使用以下技术在提交表单之前验证该字段:

//value = '2010-06-21'
var stamp = Date.parse(value);
if (isNaN(stamp)) {
    //notify user
} else {
    value = new Date(stamp).format_mysql();
}

format_mysql() 是一个原型函数,它将日期(正确)格式化为 MySQL 日期时间格式 (YYYY-MM-DD)。

- 替换为/ (YYYY/MM/DD) 会产生“正确”的时间戳。

我应该注意,该字段应该接受任何日期格式,而不仅仅是 YYYY-MM-DD,尽管我愿意,但我不能使用 Date.js 之类的库

我该如何解决这个问题,或者有没有更好的方法来解析/验证日期?

【问题讨论】:

  • 我有 Safari 5.17,这对我来说很好用(也在 iOS 5.12 上测试过):when = Date.parse("2013-01-29 08:30");
  • Date() 构造函数接受的字符串因浏览器而异,但最安全的字符串似乎是 YYYY/MM/DD——参见 dygraphs.com/date-formats.html

标签: javascript validation datetime safari


【解决方案1】:

Date.parse 方法的行为取决于实现,在 ECMAScript 5 上,此方法可以解析 ISO8601 格式的日期,但我建议您手动进行解析。

前段时间我做了一个简单的函数,可以处理格式说明符参数:

function parseDate(input, format) {
  format = format || 'yyyy-mm-dd'; // default format
  var parts = input.match(/(\d+)/g), 
      i = 0, fmt = {};
  // extract date-part indexes from the format
  format.replace(/(yyyy|dd|mm)/g, function(part) { fmt[part] = i++; });

  return new Date(parts[fmt['yyyy']], parts[fmt['mm']]-1, parts[fmt['dd']]);
}

parseDate('06.21.2010', 'mm.dd.yyyy');
parseDate('21.06.2010', 'dd.mm.yyyy');
parseDate('2010/06/21', 'yyyy/mm/dd');
parseDate('2010-06-21');

您还可以检测 ECMAScript 5 的行为来解析 ISO 格式的日期,您可以检查 Date.prototype.toISOString 是否可用,例如:

if (typeof Date.prototype.toISOString == "function") {
  // ES5 ISO date parsing available
}

【讨论】:

  • +1,你打败了我。作为对 OP 的建议,我会考虑放弃日期的单个输入元素,以避免用户在自己的语言环境中输入日期的情况(例如,混淆 dd 和 mm)。或者使用只读输入和日期选择器控件。
  • 除非我理解错误,否则只有在我事先知道日期格式的情况下,您的功能才适用,对吗? @Andy E 的负责人:单独的输入是个好主意,我会研究一下。感谢您的提示。
  • @Austin,是的,你必须以某种方式知道格式,否则你会有很多歧义,例如"01/02/2010" vs "02/01/2010",哪个是 1 月 2 日,哪个是 2 月 1 日?
  • @CMS 如何使用你的函数显示 dd/mm/yyyy
  • 我发现typeof Date.prototype.toISOString == "function" 在 Safari 5.1.2 上返回 true,所以我不得不更改 Date.parse 的检查
【解决方案2】:

该字段应接受任何日期格式

你的意思不是你认为你的意思。

  • 很难可靠地区分 M/D/Y(美国)和 D/M/Y(英国)。 D.M.Y 在英国更为常见,但绝不是普遍的。
  • 祝你在 1600 年前的日期好运 - 公历(阳历)于 1582 年推出,并且仅在 20 世纪(大部分普遍)采用(维基百科给出 1929 年)。 2 月 30 日是瑞典的有效日期。
  • OS X 提供 13 个 (!) 日历供您选择,但默认为公历。

相反,我建议使用日历小部件。我认为 JQuery 有一个,但是 ICBW。

【讨论】:

  • 好吧,我的目标受众是相当少的美国观众,他们关注的是 2000 年以上的日期,而且很可能是公历。是的,jQuery 有一个 datepicker 小部件作为其 UI 包的一部分,但我不能使用它:(。当我说“任何日期格式”时,我的意思是“2010 年 6 月 21 日”、“2010 年 6 月 21 日”、“2010- 06-21"等都代表相同的日期。
  • 如果您的意思是“美国任何模糊的常见日期格式”,您可能必须自己编写。
【解决方案3】:

您可以从输入中获得明确的日期, 但是您仍然需要检查它,因此用户不会给您 4 月 31 日。

<fieldset id= "localdate"> 
<select id= "monthselect" size= "1"> 
<option selected= "selected"> January</option> 
<option> February</option> 
<option> March</option> 
<option> April</option> 
<option> May</option> 
<option> June</option> 
<option> July</option> 
<option> August</option> 
<option> September</option> 
<option> October</option> 
<option> November</option> 
<option> December</option> 
</select> 
<label> Date: <input name= "inputdate" size= "2" value= "1"> </label> 
<label> Year: <input name= "inputyear" size= "4" value= "2010"> </label> 
</fieldset> 

document.getElementsByName 的快捷方式

函数名称(s, n){ n= n || 0; 返回 document.getElementsByName(s)[n]; }

function getDateInput(){
    var day, y= parseInt(byName('inputyear').value),
    m= byName('monthselect').selectedIndex,
    d= parseInt(byName('inputdate').value);

    if(!y || y<1000 || y> 3000) throw 'Bad Year '+y;
    if((!d || d<1 || d> 32) throw 'Bad Date '+d;
    day= new Date(y,m,d);
    if(day.getDate()!= d) throw 'Bad Date '+d;
    value= day.format_mysql();
}

您可以预设字段以反映当前加载日期

onload= function(){
    var now= new Date();
    byName('inputyear').value= now.getFullYear();
    byName('monthselect').selectedIndex= now.getMonth();
    byName('inputdate').value= now.getDate();
}

【讨论】:

    【解决方案4】:

    Safari 中一般不支持 DD-MM-YYYY 格式。

    值 = 2010/06/21 ; //应该可以。

    (或)

    value = new Date('2010-06-21'.replace(/-/g, "/"));

    【讨论】:

    • 真的很有帮助; )
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    相关资源
    最近更新 更多