【问题标题】:MomentJS issue handling Feb 29th when not a Leap yearMomentJS 问题处理 2 月 29 日不是闰年
【发布时间】:2014-01-23 21:03:32
【问题描述】:

我正在验证无效日期,例如 36/12/2013 (DD/MM/YYYY)、2/15/2013 (DD/MM/YYYY) 或以下特定情况:

29/02/2009 (DD/MM/YYYY) 无效,因为 2009 年不是闰年

代码是:

var momentAcceptedDateInputs = ['D/M/YY', 'DD/M/YY','D/MM/YY','DD/MM/YY'
, 'D/M/YYYY', 'DD/M/YYYY', 'D/MM/YYYY', 'DD/MM/YYYY',
'D MMM YY', 'DD MMM YY', 'D MMM YYYY', 'DD MMM YYYY'];

var parsedDate = moment(val, momentAcceptedDateInputs);
return parsedDate.isValid();

输入值:

29/02/2009

预期对象的返回值:

  1. parsedDate.isValid():
  2. 解析日期:时刻
    • _a:数组[7]
    • _d:2009 年 2 月 29 日星期日 00:00:00 GMT+1300(新西兰夏令时间)
    • _f: "D/M/YYYY"
    • _i:“29/02/2009”
    • _isUTC: 假
    • _isValid:

实际对象的返回值:

  1. parsedDate.isValid():
  2. 解析日期:时刻
    • _a:数组[7]
    • _d:1920 年 2 月 29 日星期日 00:00:00 GMT+1300(新西兰夏令时间)
    • _f: "D/M/YY"
    • _i:“29/02/2009”
    • _isUTC: 假
    • _isValid:

知道如何解决这个问题吗?

我正在使用moment.js的自定义版本:2.4.0

我自定义的唯一规则是这个,所以我怀疑它会导致上面报告的错误:

datePartArray[YEAR] = toInt(input) + 
(toInt(input) > (moment(moment()).format("YY")) ? 1900 : 2000);

【问题讨论】:

  • 所以你自定义了第三方库?这不是很可维护。如果这个是一个错误并且会在未来的版本中修复;那你打算怎么更新呢?
  • 您是否尝试过使用未修改版本的 moment.js 的代码,只是为了消除您的自定义可能负责的可能性?
  • 我更新了库,然后用我的自定义规则替换了默认规则。由于这个值 (68) 被硬编码到库 datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000); 我还有什么其他选择
  • 我相信这段代码根据最后两位数字计算了一整年。我看到两个选项:a)始终使用数字表示年份; b) 编写一个函数助手,在传递给 Moment 之前将两位数转换为 for-digit 符号。您也可以尝试在他们的 bugtracker 中打开一个问题。修改 3rd-library 源代码是您应该做的最后一件事。
  • Pavlo,我同意,我有这个任务。要求指定 2 位和 4 位数字年份,因此第一个选项是不可能的。辅助函数将包含来自 moment 库的许多解析规则和方法。如果他们在将这个问题放在他们的错误跟踪器上之后没有解决它,我最终将不得不这样做。

标签: javascript momentjs


【解决方案1】:

Moment 的解析器默认是非常宽容的。

例如:

moment("29/02/2009",'D/M/YY').isValid()  // true, because it uses year "20"

你可以通过传递一个布尔值来改变它

moment("29/02/2009",'D/M/YY', true).isValid() // false, due to the year digits

This is in the documentation.

【讨论】:

  • 问题不在于 .isValid() 方法。问题是解析器首先错误地解析了这个。查看返回的 moment 对象:var parsedDate = moment(val, momentAcceptedDateInputs);
  • 我只是以isValid 为例。使用 moment() 函数解析时,布尔值作为参数传递。
  • 所以你会使用var parsedDate = moment(val, momentAcceptedDateInputs, true);
  • 这似乎返回了正确的时刻对象和年份。再次感谢马特。
【解决方案2】:

至于moment-2.10.6,

 moment("29/02/2009", "DD/MM/YYYY").isValid();

现在即使没有严格解析标志也会返回 false

此外,documentation 表示自定义两位数年份的解析可以通过“替换 moment.parseTwoDigitYear 方法”来完成。

类似:

var moment = require("moment");

var myMoment = module.exports = moment;

moment.parseTwoDigitYear = function(year) {
    return ((year > 20)? 1000:2000) + parseInt(year);
}

然后

myMoment = require('./myMoment');

date = myMoment("28/02/67", "DD/MM/YYYY");
console.log(date.year());

返回 1067(不是 2067)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2022-06-30
    • 2016-06-12
    • 1970-01-01
    • 2016-03-26
    • 2020-01-03
    • 1970-01-01
    相关资源
    最近更新 更多