【问题标题】:How to get difference between 2 Dates in Years, Months and days using moment.js如何使用moment.js获取年、月和日的2个日期之间的差异
【发布时间】:2014-09-26 16:12:42
【问题描述】:

如何使用 moment.js 获取年、月和日中 2 个日期之间的差异? 例如 4/5/20142/22/2013 之间的差异应计算为 1 年 1 个月 14 天

【问题讨论】:

  • 其实不是重复的。 dup涵盖小时,分钟,秒的差异。当您谈论日历月时,这是一个不同的问题。
  • @Nawaf - 您的问题中的年份是否正确?他们都是 2013 年。
  • 你是对的,马特。我确实确定了日期。

标签: javascript momentjs


【解决方案1】:

Moment.js 无法直接处理这种情况。它确实允许您获取两个时刻之间的差异,但结果是经过的持续时间(以毫秒为单位)。 Moment 确实有一个 Duration 对象,但它将一个月定义为 30 天的固定单位 - 我们知道并非总是如此。

幸运的是,现在已经创建了一个名为"Precise Range" 的插件,它做了正确的事情。查看the source,它的作用类似于torazaburo's answer - 但它正确地考虑了一个月中调整的天数。

在你的项目中同时包含 moment.js 和这个插件(可读范围.js)后,你可以简单地这样调用它:

var m1 = moment('2/22/2013','M/D/YYYY');
var m2 = moment('4/5/2014','M/D/YYYY');
var diff = moment.preciseDiff(m1, m2);
console.log(diff);

输出为“1年1月14天”

【讨论】:

  • 请问如何将“精确范围”添加到 moment.js?
  • 这只是另一个 javascript 文件。在包含 moment.js 之后包含它。
  • 这真是太棒了.. 目前它显示 12 年 10 个月 17 天 7 小时 9 分 23 秒 但是如果我只想显示年份和月?我不想过日子!!
  • @TrimantraSoftwareSolution 在这里提问:github.com/codebox/moment-precise-range/issues。或者,在您致电 preciseDiff 之前使用 startOf('month')
  • 其实这是一个愚蠢的问题,我通过修改moment-precise-range.js得到了这个。返回对象正在构建一个字符串,我只是根据需要调整了字符串并完成了。 :-)
【解决方案2】:

你几乎不需要时间。

d1 = new Date(2014, 3, 5);                // April 5, 2014
d2 = new Date(2013, 1, 22);               // February 22, 2013
diff = new Date(
    d1.getFullYear()-d2.getFullYear(), 
    d1.getMonth()-d2.getMonth(), 
    d1.getDate()-d2.getDate()
);

这利用了Date 构造函数对负值的智能这一事实。例如,如果月数为负数,它将考虑到这一点并回溯当年。

console.log(diff.getYear(), "Year(s),", 
    diff.getMonth(), "Month(s), and", 
    diff.getDate(), "Days.");

>> 1 Year(s), 1 Month(s), and 11 Days. 

您的计算是错误的 - 不是 14 天,而是 2 月的剩余 6 天和 4 月的前 5 天,所以是 11 天,因为计算机计算正确。

第二次尝试

考虑到@MattJohnson 的评论,这可能会更好:

dy = d1.getYear()  - d2.getYear();
dm = d1.getMonth() - d2.getMonth();
dd = d1.getDate()  - d2.getDate();

if (dd < 0) { dm -= 1; dd += 30; }
if (dm < 0) { dy -= 1; dm += 12; }

console.log(dy, "Year(s),", dm, "Month(s), and", dd, "Days.");

【讨论】:

  • 很好地考虑重用Date 对象走出范围的能力。然而,他的方法存在一些问题。 1) Date 对象具有本地时区的 DST 行为,这可能会扭曲某些结果,以及 2) 它不能很好地处理整个月。考虑 1 月 1 日 - 7 月 1 日。它返回的不是“6 个月”,而是“5 个月零 30 天”。 3)即使那样,它也不适用于闰年。 1 月 1 日 - 3 月 1 日总是返回“1 个月零 28 天”,即使是在闰年 - 从技术上讲,它应该是“1 个月零 29 天”。
  • 1 月 1 日到 3 月 1 日不应该总是“两个月”吗?
  • 理想情况下,是的。我只是指出,您第一次通过返回的值在闰年方面并不准确。
  • 第二次尝试代码假定所有月份都是 30 天,这是不正确的。相信我,这个问题比看起来更难。 :) 对日历数学的良好理解已经涵盖了这一点。确实有纯JS的方案,但是不简单。
  • 实际上...当我浏览时刻文档时,我意识到时刻没有涵盖此操作...我将进行更多研究并发布稍后回答。谢谢。
【解决方案3】:

这对我有用。使用年龄计算器验证。

function calculateAge(){
    ageText = jQuery("#dob").closest(".form-group").find(".age-text");
    ageText.text("");
    level2.dob = jQuery("#dob").val();
    if(!level2.dob) return;
    level2.mdob= moment(level2.dob, 'DD-MM-YYYY');
    if(!level2.mdob.isValid()){
        alert("Invalid date format");
        return;
    }
    level2.targetDate = moment();//TODO: Fill in the target date
    level2.months = level2.targetDate.diff(level2.mdob, 'months'); // Calculate the months
    let years = parseInt(level2.months/12); // A year has 12 months irrespective or leap year or not
    let balanceMonths = level2.months%12; // The balance gives the number of months 
    let days;
    if(!balanceMonths){ // If no balance months, then the date selected lies in the same month
        months = 0; // so months = 0
        days = level2.targetDate.diff(level2.mdob, 'days'); // only the days difference
    }else{
    months = balanceMonths;
    dob_date = level2.mdob.date();
    target_month = level2.targetDate.month();
    construct_date = moment().month(target_month).date(dob_date);
    days = level2.targetDate.diff(construct_date, 'days')+1; // There might be one day missed out. Not sure on UTC
}

ageText = years +" years " + months+ " months " + days +" days";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多