如何使此功能不返回负日期差异?

时间:2016-02-14 07:42:11

标签: javascript javascript-objects

该功能试图为日期之间的差异提供资金,但如果日期超过某一点,我很难不返回负数。我尝试了一些类似于使用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个月而不是减去它。我正在尝试找到一个解决方案,因为这个功能更加精简,但另一个更通用。上面的函数,我替换了.floor(),用.abs()将值向下舍入,希望它只使用给定操作的绝对值,但事实并非如此。

2 个答案:

答案 0 :(得分:1)

问题是您以不恰当的方式使用.abs()函数。大多数数学函数都不遵守分配规则,而.abs()函数属于这些。为了便于理解,让我们暂时忘记您当前的问题,让我们来看一个简单的简化示例:

假设你想知道-10的绝对值。显然,正确的结果是+10。

另一方面,-10可写为(-20 + 10)。但是,你可以使用这些知识计算abs(-10):

abs(-20 + 10)= 10,但是 abs(-20)+ abs(+10)= 30

将这些知识运用到你的问题中,我们看到abs(Y年+ M个月+ D天)通常不等于(abs(Y年)+ abs(M个月)+ abs(D天))。< / p>

关于这个问题,还有一个奇怪的结果:每个结果的条款都有另一个单位,并且这些术语相互依赖(例如,可能没有像“13个月”这样的术语,因为那将是“ 1年加1个月“),但我不会在这里详细说明。

有一个简单的解决方案:

1)确定所需的结果分辨率(即,您的结果应该精确到秒,阿秒,天或其他)。

2)将两个日期转换为步骤1)中确定的单位,使用随机选择但固定的时间点作为公共起点。

3)现在你可以减去两个(转换的)日期并使用.abs()函数而不会出现问题。

4)将结果转换回人类可读形式。

你在实践中如何做到这一点?那么,步骤1),3)和4)很容易,但步骤2)呢?

我知道的几乎所有操作系统(因此几乎每种编程语言)都会为您完成步骤2)中所需的转换。通常,固定时间点是1970-01-01 00:00:00,OS /编程语言提供了将任何日期/时间转换为已经过的秒数(或其他一些单位)的例程从这个固定点开始。

例如,在JavaScript中,myDate.getTime()函数返回自1970-01-01以来已经传递到myDate的毫秒的数量。

因此将两个日期转换为“自1970-01-01以来的毫秒数”并减去它们。在结果上使用.abs()函数。然后,您将所需的时间跨度作为正毫秒的值。将其转换回人类可读的形式,即年,月和日(这没有问题,是吗?)

第二个简单的解决方案(仅用于避免否定结果):

我希望你同意我的意见比较两个日期比计算它们之间的差异要容易得多(首先比较一年;如果年份不同,你无疑会发现“更大”的日期;如果年份相同,则按月计算,依此类推)。然后在必要时交换两个日期。这样,您始终可以确保从“更大”日期中减去“较小”日期,并且结果始终为正。

但是请注意,即使这样做,在实际减去日期时,部分计算仍会有负面结果,因此在使用.abs()函数时会遇到完全相同的问题。

更复杂的解决方案:

你也可以自己做减法,但是.abs()函数对你没有多大帮助。我能想到的其中一个算法可以像手工完成的减法一样(我的意思是减去你在学校学到的正常数字):

从最不重要的单位开始(例如日期)。减去日子;如果结果是否定的,那么加上28,29,30或31(取决于月份)并按月计算,否则保留结果;然后用月份做同样的事情,依此类推。但正如我在评论中已经写过的那样,这样做有很多陷阱(闰年,几个月有不同的天数等等),而.abs()函数对你没有帮助。

<强>结论:

就个人而言,我更喜欢我给出的第一个(简单)解决方案。这很容易理解且面向未来。

答案 1 :(得分:0)

&#13;
&#13;
//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();
&#13;
&#13;
&#13;

以下是我能够创建的答案。