【问题标题】:JSDate - Parse a ddMMyyyy format date correctlyJSDate - 正确解析 ddMMyyyy 格式的日期
【发布时间】:2012-05-23 00:04:19
【问题描述】:

我在使用 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 样式的实现有点冗长...

【问题讨论】:

    标签: javascript parsing date


    【解决方案1】:

    我不了解 DateJS,但如果您发现它假设 MMddyyyy 是您想要的 ddMMyyyy,那么您可以在解析之前快速替换您的字符串以将其切换为 MMddyyyy

    Date.parse( '01062012'.replace(/^(\d\d)(\d\d)(\d\d\d\d)$/,"$2$1$3") );
    

    或者进行类似的替换以插入连字符并使其成为dd-MM-yyyy

    Date.parse( '01062012'.replace(/^(\d\d)(\d\d)(\d\d\d\d)$/,"$1-$2-$3") );
    

    无论哪种方式,其中已经包含连字符的字符串都将保持不变,因此将根据您的第一个(成功)测试用例进行解析。

    【讨论】:

    • 模块的其余部分设置为使用 dmy 格式。正则表达式是一个滑坡,必须测试日期模块已经知道的所有情况 - 1-2 位数的日期 + 月份,以及 2 或 4 位数的年份......
    • 是的,这并不理想,但是如果没有分隔符,1 位数的日期或月份的混合将根本不起作用,因为例如,什么日期是 111972 - 1/1/1972 或 11 /19/72?如果您假设一个没有分隔符的字符串必须采用 ddMMyyyy 格式,那么我的答案中的正则表达式应该可以解决问题,因为它不会更改带有分隔符的字符串,并且您已经说过带有分隔符的字符串可以正常工作你要。 (我希望其他人发布更好的答案,但如果不是,至少这会起作用......)
    【解决方案2】:

    您想使用Date.parseExact 方法。出于某种原因,它可以正常工作,而普通解析则不能。此外,您不需要传递包装在对象中的格式选项。

    根据规范 Date.parse 不应该采用格式选项,所以这可能就是原因。

    // Parses correctly
    var dateWithFormat = Date.parseExact('01062012', 'ddMMyyyy');
    

    我还更新了jsfiddle 以确保。

    更新

    我认为问题在于解析器hard-codes 有一堆简单的格式,并且在某些情况下会覆盖日期、月份和年份顺序的本地化设置。如果您将以下内容放在使用 Date 的位置之前,它将解决您的问题。

    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"
    ]);
    

    这不是很漂亮,但它肯定比列出所有可能的选项要短,即使只是一点点。如果你能找到一个不那么古怪的 Date 库,那可能是一个更好的选择。

    【讨论】:

    • 更新了问题以包含更广泛的预期用户输入。我会考虑实施您的解决方案。
    猜你喜欢
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多