我正在编写一个函数来计算输入日期(年,月和日)与现在日期之间的时间间隔。我需要能够记录过去或未来的输入日期,以计算闰年并将其全部返回数年,数月(幸运的是,我可以每月平均使用30天)和单个对象中的天数并且让它在一个更大的函数中工作,我可以在输入日期调用它。我花了这么多时间在这上面,基本上,我用UTC时间计算间隔,计算闰年,并为每个闰年增加天数,然后使用我的值创建字典但经过这么多工作,我觉得我还有不准确之处当我转换价值时,最终可能会出现问题。照顾几个月是不是> 12加上1年计数(我觉得如果是24个月或更高,我会遇到问题)。在过去的两天里我一直在努力工作。感觉我已经清理了很多我以前的问题,但它仍然不完全正确我感觉像&感觉我的计算中存在一些缺陷......这是我的代码:
var timeInterval = function(inputYear, inputMonth, inputDay) {
var intervalInDays = function(inputYear, inputMonth, inputDay) {
var now = new Date();
var then = new Date(inputYear, (inputMonth - 1), inputDay);
var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
var then_utc = new Date(then.getUTCFullYear(), then.getUTCMonth(), then.getUTCDate());
var intervalInMill = then_utc - now_utc;
var intervalInDays = (intervalInMill / (1000 * 60 * 60 * 24));
return Math.abs(Math.round(intervalInDays));
///return Math.round(intervalInMill / (1000 * 60 * 60 * 24));
};
var countLeapYears = function(inputYear, inputMonth, inputDay) {
var yearNow = new Date().getFullYear(),
yearThen = inputYear,
beginYear = 0,
endYear = 0,
leapYearCount = 0;
var isLeapYear = function(year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
};
if (yearNow < inputYear) {
beginYear = yearNow;
endYear = inputYear;
} else if (yearNow > inputYear) {
beginYear = inputYear;
endYear = yearNow;
} else if (yearNow == inputYear) {
beginYear = inputYear;
endYear = inputYear;
}
for (i = beginYear; i <= endYear; i++) {
if (isLeapYear(i)) {
leapYearCount++;
}
}
return leapYearCount;
};
var totalDays = intervalInDays(inputYear, inputMonth, inputDay);
var leapYearCount = countLeapYears(inputYear, inputMonth, inputDay);
var years = Math.abs(Math.trunc(totalDays / 365));
var months = Math.abs(Math.trunc((totalDays - ((years * 365) - leapYearCount)) / 30));
if (months >= 12) {
years += 1;
months = months - 12;
}
var days = Math.abs(totalDays - (years * 365) - (months * 30) - leapYearCount);
///Math.abs((totalDays - ((years * 365) - leapYearCount)) % 30);
var intervalDict = {
"years": years,
"months": months,
"days": days,
};
return intervalDict;
};
console.log(timeInterval(2014, 11, 3));
console.log(timeInterval(2016, 2, 5));
console.log(timeInterval(2015, 2, 5));
console.log(timeInterval(2005, 2, 5));
console.log(timeInterval(1982, 3, 10));
答案 0 :(得分:1)
简短的回答:您可以使用moment.js而不是重新发明轮子,而您的脚本将在一行中完成:
interval = moment().diff(moment([inputYear, inputMonth, inputDay]))
然后你可以通过interval.days(),interval.months(),interval.years()
访问日/月/年答案很长:你误解了javascript变量的声明。如果在函数或循环中声明var,它将仅在此上下文中可用。例如,您在years
内定义if (intervalInDays > 365)
,因此在结束}
之后,您的变量年份不可用。
在同一个寄存器中,您声明两次intervalInDays
,一次在普通函数中,一次在名为intervalInDays
的函数内。当你使用它来定义dict时,它实际上会引用函数,而不是它的结果,可能不是你想要的。
在您的第二个示例中,您尝试使用不存在的years
变量,因此它显然会失败。
结论:您的变量必须在需要可用的最高级别声明,否则您将无法访问它们。
答案 1 :(得分:0)
首先,我认为你误解了你的输入日期:
timeInterval(2016,2,5)等于2016年, 3月,5。 如果这就是你想要的东西,但我认为你的意思是2016年,二月,5这将是timeInterval(2016年,1,5)。
function timeInterval(inputYear, inputMonth, inputDay) {
var now = new Date();
var then = new Date(inputYear, inputMonth, inputDay);
var dayCount = 0;
while (now.setHours(1, 3, 3, 7) > then.setHours(1, 3, 3, 7)) {
then.setDate(then.getDate() + 1);
dayCount++;
}
while (now.setHours(1, 3, 3, 7) < then.setHours(1, 3, 3, 7)) {
now.setDate(now.getDate() + 1);
dayCount++;
}
var years = Math.floor(dayCount/365);
dayCount = dayCount - years*365;
var months = Math.floor(dayCount/30);
dayCount = dayCount - months*30;
var days = dayCount;
return { years, months, days };
}
// this is today: 4th february 2016
console.log(timeInterval(2016, 1, 4));
console.log(timeInterval(2014, 11, 3));
console.log(timeInterval(2016, 2, 5));
console.log(timeInterval(2015, 2, 5));
console.log(timeInterval(2005, 2, 5));
console.log(timeInterval(1982, 3, 10));
输出:
{ years: 0, months: 0, days: 0 }
{ years: 1, months: 2, days: 3 }
{ years: 0, months: 1, days: 0 }
{ years: 0, months: 11, days: 6 }
{ years: 10, months: 11, days: 8 }
{ years: 33, months: 10, days: 8 }
仍然不准确,但您声明可以每月30天使用平均值。毕竟它是一个功课,所以试着去理解和改进代码。
答案 2 :(得分:0)
这不是100%准确但非常接近
10