如何使此功能不 return 负日期差异?
How to make this function not return a negative date diffence?
该函数正在尝试为日期之间的差异提供资金,但如果日期超过某个点,我正在努力不 return 一个负数。我已经尝试了一些解决方法,比如使用 ABS,但它可能会在未来的领域引起问题。
var DateCalc = {};
DateCalc.totalDaysLeft = 0;
DateCalc.calculate = function(dateToParse) {
DateCalc.init(dateToParse);
return DateCalc.stringify(DateCalc.years(), DateCalc.months(), DateCalc.days());
};
DateCalc.init = function(dateToParse) {
var date = DateCalc.parseDate(dateToParse);
var today = Date.now();
var oneDay = 24 * 60 * 60 * 1000;
DateCalc.totalDaysLeft = Math.floor((date - today) / oneDay);
};
DateCalc.parseDate = function(dateToParse) {
var dateVars = dateToParse.split(',').map(Number);
return new Date(dateVars[0], dateVars[1] - 1, dateVars[2]);
};
DateCalc.years = function() {
var years = Math.floor(DateCalc.totalDaysLeft / 365);
DateCalc.totalDaysLeft -= Math.floor(years * 365);
return years;
};
DateCalc.months = function() {
var months = Math.floor(DateCalc.totalDaysLeft / 30);
DateCalc.totalDaysLeft -= Math.floor(months * 30);
return months;
};
DateCalc.days = function() {
return Math.floor(DateCalc.totalDaysLeft / 24);
};
DateCalc.stringify = function(years, months, days) {
var dateString = "";
if (years !== 0)
dateString += years + " years, ";
if (months !== 0)
dateString += months + " months, ";
dateString += days + " day(s).";
return dateString;
};
//here is the .abs() code.
function age(year, month, day) {
var yearDifference = Math.abs(new Date().getFullYear() - year);
var monthDifference = Math.abs(new Date().getMonth() - month + 1);
var dayDifference = Math.abs(new Date().getDate() - day);
var differences = {
year: yearDifference,
month: monthDifference,
day: dayDifference
};
var final = [];
for (var time in differences) {
if (differences[time] > 0) {
var addString = differences[time] + " " + time;
if (differences[time] > 1) {
addString += "s"
}
final.push(addString);
}
}
return final.join(" ");
};
console.log(age(2017, 11, 17));
console.log(age(2016, 1, 2));
//如果你在 12 月时尝试查找明年 1 月还有多远,它会告诉你现在是 1 年 11 个月,而不是 1 个月。这是因为它增加了 11 个月而不是减去 it.I 我试图找到一个解决方案,因为这个函数更简洁但另一个更通用。上面的函数,我用 .abs() 将值向下舍入替换了 .floor() 希望它只使用给定操作的绝对值,但是,情况并非如此。
问题是您以不恰当的方式使用了 .abs() 函数。大多数数学函数不遵守分配规则,而 .abs() 函数属于这些。为了更容易理解,让我们暂时忘记您当前的问题,让我们检查一个简单的简化示例:
假设您想知道 -10 的绝对值。显然,正确的结果是+10.
另一方面,-10 可以写成 (-20 + 10)。但是,尽管如此,您可以 not 使用该知识计算 abs(-10):
abs(-20 + 10) = 10,但是
绝对值(-20) + 绝对值(+10) = 30
将这些知识应用于您的问题,我们发现 abs(Y 年 + M 个月 + D 天) 通常不等于 (abs(Y 年) + abs(M 个月) + abs(D 天)) .
关于这个问题,还有一个额外的奇怪之处,即结果的每个项都有另一个单位,并且这些项相互依赖(例如,不能有像“13 个月”这样的项,因为那会是“1年加1个月”),但我不会在这里进一步详细说明。
有一个简单的解决方法:
1) 确定您的结果所需的分辨率(即您的结果是否应该精确到秒、阿秒、天或其他)。
2) 将两个日期转换为步骤 1) 中确定的单位,使用随机选择但固定的时间点作为共同起点。
3) 现在您可以减去两个(转换后的)日期并毫无问题地使用 .abs() 函数。
4) 将结果转换回人类可读的形式。
你在实践中是怎么做到的?那么,步骤 1)、3) 和 4) 很简单,但是步骤 2) 呢?
我所知道的几乎所有 OS(因此,几乎所有编程语言)都会为您完成步骤 2) 中所需的转换。通常,固定时间点是 1970-01-01 00:00:00,并且 OS/ 编程语言提供了将任何日期/时间转换为秒数(或其他一些单位)的例程) 自此固定点以来已经过去。
例如,在 JavaScript 中,myDate.getTime() 函数 returns 自 1970-01 以来经过的 毫秒 的数量-01 直到我的日期。
因此将两个日期都转换为 "milliseconds since 1970-01-01" 并减去它们。对结果使用 .abs() 函数。然后您将所需的时间跨度作为正毫秒值。将其转换回人类可读的形式,即年、月和日(这没问题,是吗?)
第二个简单的解决方案(只是为了避免负面结果):
我希望你同意我的看法比较两个日期比计算它们之间的差异要容易得多(首先比较年份;如果年份不同,你无疑已经发现"greater" 日期;如果年份相等,则对月份执行相同的操作,依此类推)。然后如有必要交换这两个日期。这样,您始终可以确保从 "greater" 日期中减去 "smaller" 日期并且结果始终为正值。
但请注意,即使这样做,在实际减去日期时,部分计算仍然会出现负结果,因此您在使用 .abs() 函数时会遇到完全相同的问题。
更复杂的解法:
您也可以自己做减法,但是 .abs() 函数对您的帮助不大。我能想到的一种算法可以像手工完成的减法一样工作(我的意思是你在学校学到的正常数字的减法):
从最不重要的单位(例如天)开始。减去天数;如果结果为负数,则加上 28、29、30 或 31(取决于月份)并进位到月份,否则保留结果;然后对月份做同样的事情,依此类推。但正如我在评论中已经写到的那样,这样做有很多陷阱(闰年、月份有不同的天数等等),而 .abs() 函数在这里对你没有帮助。
结论:
就个人而言,我更喜欢我给出的第一个(简单的)解决方案。它简单易懂且面向未来。
//initial variables
var today = new Date();
var day = today.getDate();
var month = today.getMonth() + 1;
var year = today.getFullYear();
var otherDate = new Date();
var day2 = 0;
var month2 = 0;
var year2 = 0;
if (day < 10) {
day = '0' + day;
}
if (month < 10) {
month = '0' + month;
}
function age(day2, month2, year2) {
dayConv = day2;
monthConv = month2;
yearConv = year2;
newDate = day - dayConv;
newMonth = month - monthConv;
newYear = year - yearConv;
}
function mathDate() {
if (newYear >= 1) {
if (newMonth >= 1) {
if (newDate >= 1) {
console.log(newYear + " years and " + newMonth + " months and " + newDate + " days.");
return newYear + " years and " + newMonth + " months and " + newDate + " days.";
} else if (newDate <= 0) {
console.log(newYear + " years and " + newMonth + " months.");
return newYear + " years and " + newMonth + " months.";
}
} else if (newMonth <= 0) {
console.log(newYear + " years and " + newDate + " days.");
return newYear + " years and " + newDate + " days.";
}
} else if (newYear <= 1) {
if (newMonth >= 1) {
console.log(newMonth + " months and " + newDate + " days.");
return newMonth + " months and " + newDate + " days.";
} else if (newDate <= 0) {
console.log(newMonth + " months.");
return newMonth + " months.";
} else if (newMonth <= 0) {
console.log(newDate + " days.");
return newDate + " days.";
}
}
}
age(13, 4, 2016);
mathDate();
这是我能够创建的答案。
该函数正在尝试为日期之间的差异提供资金,但如果日期超过某个点,我正在努力不 return 一个负数。我已经尝试了一些解决方法,比如使用 ABS,但它可能会在未来的领域引起问题。
var DateCalc = {};
DateCalc.totalDaysLeft = 0;
DateCalc.calculate = function(dateToParse) {
DateCalc.init(dateToParse);
return DateCalc.stringify(DateCalc.years(), DateCalc.months(), DateCalc.days());
};
DateCalc.init = function(dateToParse) {
var date = DateCalc.parseDate(dateToParse);
var today = Date.now();
var oneDay = 24 * 60 * 60 * 1000;
DateCalc.totalDaysLeft = Math.floor((date - today) / oneDay);
};
DateCalc.parseDate = function(dateToParse) {
var dateVars = dateToParse.split(',').map(Number);
return new Date(dateVars[0], dateVars[1] - 1, dateVars[2]);
};
DateCalc.years = function() {
var years = Math.floor(DateCalc.totalDaysLeft / 365);
DateCalc.totalDaysLeft -= Math.floor(years * 365);
return years;
};
DateCalc.months = function() {
var months = Math.floor(DateCalc.totalDaysLeft / 30);
DateCalc.totalDaysLeft -= Math.floor(months * 30);
return months;
};
DateCalc.days = function() {
return Math.floor(DateCalc.totalDaysLeft / 24);
};
DateCalc.stringify = function(years, months, days) {
var dateString = "";
if (years !== 0)
dateString += years + " years, ";
if (months !== 0)
dateString += months + " months, ";
dateString += days + " day(s).";
return dateString;
};
//here is the .abs() code.
function age(year, month, day) {
var yearDifference = Math.abs(new Date().getFullYear() - year);
var monthDifference = Math.abs(new Date().getMonth() - month + 1);
var dayDifference = Math.abs(new Date().getDate() - day);
var differences = {
year: yearDifference,
month: monthDifference,
day: dayDifference
};
var final = [];
for (var time in differences) {
if (differences[time] > 0) {
var addString = differences[time] + " " + time;
if (differences[time] > 1) {
addString += "s"
}
final.push(addString);
}
}
return final.join(" ");
};
console.log(age(2017, 11, 17));
console.log(age(2016, 1, 2));
//如果你在 12 月时尝试查找明年 1 月还有多远,它会告诉你现在是 1 年 11 个月,而不是 1 个月。这是因为它增加了 11 个月而不是减去 it.I 我试图找到一个解决方案,因为这个函数更简洁但另一个更通用。上面的函数,我用 .abs() 将值向下舍入替换了 .floor() 希望它只使用给定操作的绝对值,但是,情况并非如此。
问题是您以不恰当的方式使用了 .abs() 函数。大多数数学函数不遵守分配规则,而 .abs() 函数属于这些。为了更容易理解,让我们暂时忘记您当前的问题,让我们检查一个简单的简化示例:
假设您想知道 -10 的绝对值。显然,正确的结果是+10.
另一方面,-10 可以写成 (-20 + 10)。但是,尽管如此,您可以 not 使用该知识计算 abs(-10):
abs(-20 + 10) = 10,但是 绝对值(-20) + 绝对值(+10) = 30
将这些知识应用于您的问题,我们发现 abs(Y 年 + M 个月 + D 天) 通常不等于 (abs(Y 年) + abs(M 个月) + abs(D 天)) .
关于这个问题,还有一个额外的奇怪之处,即结果的每个项都有另一个单位,并且这些项相互依赖(例如,不能有像“13 个月”这样的项,因为那会是“1年加1个月”),但我不会在这里进一步详细说明。
有一个简单的解决方法:
1) 确定您的结果所需的分辨率(即您的结果是否应该精确到秒、阿秒、天或其他)。
2) 将两个日期转换为步骤 1) 中确定的单位,使用随机选择但固定的时间点作为共同起点。
3) 现在您可以减去两个(转换后的)日期并毫无问题地使用 .abs() 函数。
4) 将结果转换回人类可读的形式。
你在实践中是怎么做到的?那么,步骤 1)、3) 和 4) 很简单,但是步骤 2) 呢?
我所知道的几乎所有 OS(因此,几乎所有编程语言)都会为您完成步骤 2) 中所需的转换。通常,固定时间点是 1970-01-01 00:00:00,并且 OS/ 编程语言提供了将任何日期/时间转换为秒数(或其他一些单位)的例程) 自此固定点以来已经过去。
例如,在 JavaScript 中,myDate.getTime() 函数 returns 自 1970-01 以来经过的 毫秒 的数量-01 直到我的日期。
因此将两个日期都转换为 "milliseconds since 1970-01-01" 并减去它们。对结果使用 .abs() 函数。然后您将所需的时间跨度作为正毫秒值。将其转换回人类可读的形式,即年、月和日(这没问题,是吗?)
第二个简单的解决方案(只是为了避免负面结果):
我希望你同意我的看法比较两个日期比计算它们之间的差异要容易得多(首先比较年份;如果年份不同,你无疑已经发现"greater" 日期;如果年份相等,则对月份执行相同的操作,依此类推)。然后如有必要交换这两个日期。这样,您始终可以确保从 "greater" 日期中减去 "smaller" 日期并且结果始终为正值。
但请注意,即使这样做,在实际减去日期时,部分计算仍然会出现负结果,因此您在使用 .abs() 函数时会遇到完全相同的问题。
更复杂的解法:
您也可以自己做减法,但是 .abs() 函数对您的帮助不大。我能想到的一种算法可以像手工完成的减法一样工作(我的意思是你在学校学到的正常数字的减法):
从最不重要的单位(例如天)开始。减去天数;如果结果为负数,则加上 28、29、30 或 31(取决于月份)并进位到月份,否则保留结果;然后对月份做同样的事情,依此类推。但正如我在评论中已经写到的那样,这样做有很多陷阱(闰年、月份有不同的天数等等),而 .abs() 函数在这里对你没有帮助。
结论:
就个人而言,我更喜欢我给出的第一个(简单的)解决方案。它简单易懂且面向未来。
//initial variables
var today = new Date();
var day = today.getDate();
var month = today.getMonth() + 1;
var year = today.getFullYear();
var otherDate = new Date();
var day2 = 0;
var month2 = 0;
var year2 = 0;
if (day < 10) {
day = '0' + day;
}
if (month < 10) {
month = '0' + month;
}
function age(day2, month2, year2) {
dayConv = day2;
monthConv = month2;
yearConv = year2;
newDate = day - dayConv;
newMonth = month - monthConv;
newYear = year - yearConv;
}
function mathDate() {
if (newYear >= 1) {
if (newMonth >= 1) {
if (newDate >= 1) {
console.log(newYear + " years and " + newMonth + " months and " + newDate + " days.");
return newYear + " years and " + newMonth + " months and " + newDate + " days.";
} else if (newDate <= 0) {
console.log(newYear + " years and " + newMonth + " months.");
return newYear + " years and " + newMonth + " months.";
}
} else if (newMonth <= 0) {
console.log(newYear + " years and " + newDate + " days.");
return newYear + " years and " + newDate + " days.";
}
} else if (newYear <= 1) {
if (newMonth >= 1) {
console.log(newMonth + " months and " + newDate + " days.");
return newMonth + " months and " + newDate + " days.";
} else if (newDate <= 0) {
console.log(newMonth + " months.");
return newMonth + " months.";
} else if (newMonth <= 0) {
console.log(newDate + " days.");
return newDate + " days.";
}
}
}
age(13, 4, 2016);
mathDate();
这是我能够创建的答案。