我在使用 Javascript 解析用户输入时遇到问题,无法让解析器正确接受 ddMMyyyy 中的日期。当有分隔符时,它会正确解析。
下面的示例使用的是 DateJS(新西兰本地化),我已经对较新的 MomentJs 进行了初步尝试(事实证明它不适合输入验证)。我对其他框架持开放态度,如果他们要充分处理输入情况。
我的测试用例:
// Parses correct value
var dateWithHyphens = Date.parse('01-06-2012');
// Parses incorrectly, using MMddyyy, instead of ddMMyyyy
var dateWithoutHyphens = Date.parse('01062012');
// Parses incorrectly, using MMddyyy, instead of ddMMyyyy
var dateWithFormat = Date.parse('01062012', { format: 'ddMMyyyy'});
我为此创建了一个JSFiddle:http://jsfiddle.net/ajwxs/1
测试用例应返回 6 月 1 日,但不正确的测试用例应返回 1 月 6 日。(这是输入解析 - 输出格式为时已晚)。
关于是否可以更好地推动JSDate使用正确的格式来解析这些日期的任何建议?
更新
在此应用程序中,我将验证许多可能的用户输入,包括:
01062012
01/06/2012
010612
这将使 parseExact-style 实现的实现有点冗长......
DateJS,但如果你发现它假设MMddyyyy
你想要ddMMyyyy
,那么你可以在解析之前对字符串进行快速替换以将其切换到 MMddyyyy
:
Date.parse( '01062012'.replace(/^(dd)(dd)(dddd)$/,"$2$1$3") );
或者做类似的替换来插入连字符并使其dd-MM-yyyy
:
Date.parse( '01062012'.replace(/^(dd)(dd)(dddd)$/,"$1-$2-$3") );
无论哪种方式,已经包含连字符的字符串都将保持不变,从而根据您的第一个(成功)测试用例进行分析。
你想使用 Date.parseExact 方法。由于某种原因,它可以工作,而正常的解析则不能。此外,您不需要传递包装在对象中的格式选项。
根据规范,Date.parse不应该采用格式选项,所以这可能是原因。
// Parses correctly
var dateWithFormat = Date.parseExact('01062012', 'ddMMyyyy');
我也更新了 jsfiddle 以确保。
更新
我认为问题在于解析器对一堆简单的格式进行硬编码,并且在某些情况下,这些格式会覆盖日期、月份和年份顺序的本地化设置。如果您在使用日期之前放置以下内容,它将解决您的问题。
Date.Grammar._formats = Date.Grammar.formats([
""yyyy-MM-ddTHH:mm:ssZ"",
"yyyy-MM-ddTHH:mm:ssZ",
"yyyy-MM-ddTHH:mm:ssz",
"yyyy-MM-ddTHH:mm:ss",
"yyyy-MM-ddTHH:mmZ",
"yyyy-MM-ddTHH:mmz",
"yyyy-MM-ddTHH:mm",
"ddd, MMM dd, yyyy H:mm:ss tt",
"ddd MMM d yyyy HH:mm:ss zzz",
"ddMMyyyy",
"MMddyyyy",
"ddMyyyy",
"Mddyyyy",
"dMyyyy",
"Mdyyyy",
"yyyy",
"dMyy",
"Mdyy",
"d"
]);
这并不漂亮,但它绝对比列出所有可能的选项要短,即使只是一点点。如果你能找到一个不那么古怪的日期库,那可能是一个更好的选择。