13

我已经使用下面的函数进行了计算,它以“X YEARS,Y MONTHS,Z DAYS”的格式给出了 o/p,并且对于某些日期,它给出了一些错误的 o/p。我想我做了一些公式中缺少的计算。

功能是,

/**
 * @param {Date} startdate
 * @param {Date} enddate
 * @return {String}
 */
function leasePeriodCalc(startDate,endDate)
{
  var sdate=startDate;
  var edate=endDate;
  edate.setDate( edate.getDate()+1);
  edate=new Date(edate);
  if(sdate.valueOf()>edate.valueOf()){
    return('0');
  }
  else{
    var years=((((edate.getDate()-sdate.getDate())<0 ? -1:0)+((edate.getMonth()+1)-(sdate.getMonth()+1)))< 0 ? -1 : 0)+(edate.getFullYear()-sdate.getFullYear());
    var months=((((edate.getDate()-sdate.getDate())<0 ? -1:0)+((edate.getMonth()+1)-(sdate.getMonth()+1)))< 0 ?12:0)+((edate.getDate()-sdate.getDate())<0 ? -1:0)+((edate.getMonth()+1)-(sdate.getMonth()+1));
    if((edate.getMonth()-1)!=1.0)
    {
      var days=((edate.getDate()-sdate.getDate())< 0 ?new Date(edate.getFullYear(), edate.getMonth(),0).getDate():0)+(edate.getDate()-sdate.getDate());
    }
    else
    {
      var days=((edate.getDate()-sdate.getDate())< 0 ?new Date(edate.getFullYear(), edate.getMonth()+1,0).getDate():0)+(edate.getDate()-sdate.getDate());
    }
    var day;
    var month;
    var year;
    if(years>1)year= years+ 'Years';
    else year=years+'Year';
    if(months>1) month= months+ 'Months';
    else month=months+'Month';
    if(days>1) day= days+ 'Days';
    else day=days+'Day';
    if(years==0&&months!=0&&days!=0) return(month+', '+day);
    else if(years!=0&&months==0&&days!=0) return(year+', '+day);
    else if(years!=0&&months!=0&&days==0) return(year+', '+month);
    else if(years==0&&months==0&&days!=0) return(day);
    else if(years==0&&months!=0&&days==0) return(month);
    else if(years!=0&&months==0&&days==0) return(year);
    else if(years==0&&months==0&&days==0) return(day);
    else if(years!=0&&months!=0&&days!=0) return(year+', '+month+', '+day);
  }
}

如果你给出如下的 i/p,它会返回错误的 o/p:

2013 年 2 月 28 日 - 2014 年 2 月 28 日

预期 o/p : 1 YEAR , 1 DAY

给定 o/p : 1 YEAR , 4 DAYS

但是,如果我选择 2013 年 2 月 28 日 - 2014 年 2 月 27 日的意思,它给出了正确的 o/p:

预期 o/p : 1 年

给定 o/p : 1 年

如果我做了任何事情,请建议纠正我的错误。

而且我必须告诉我,我并没有制定所有规则。一般来说,一个月是按照当月的天数计算的。

例如,如果我们从银行获得贷款,我们将仅每月支付利息,即使该月可能有 30 天或 29 天或 28 天或 31 天。

而且如果我们拿一个房间作为月租手段,我们就按月付房租吗?甚至可以是从 3 月 20 日到 4 月 19 日。即使它包含31天,据说也只有一个月。请帮我总结一下。

Tnx,CL。

4

7 回答 7

27

对于 JavaScript 中复杂的日期/时间操作,我发现Moment.js库确实可以提供帮助。我将它打包到一个 Apps 脚本库中,您可以使用项目密钥MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48将其包含在内。我用它来解决这个问题,尽管我可能错过了一些边缘情况。

// Load the library (key: MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48).
var moment = Moment.load();

function getDuration(startDate, endDate) {
  var start = moment(startDate);
  var end = moment(endDate);
  var units = ['years', 'months', 'days'];
  var parts = [];
  units.forEach(function(unit, i) {
    var diff = Math.floor(end.diff(start, unit, true));
    if (diff > 0 || i == units.length - 1) {
      end.subtract(unit, diff);
      parts.push(diff + ' ' + unit);
    }
  })
  return parts.join(', ');
}
于 2013-06-04T22:10:55.207 回答
4

您可以将moment.js其作为外部依赖项包含在内,并在 Google App Script 项目中使用。参考https://stackoverflow.com/a/45231921/5429123文章,你可以这样做。

eval(UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js').getContentText());
var date = moment().format("MMM Do YY");
Logger.log(date)

这将为您提供 moment.js 的最新版本(截至 2018/10/25 的 2.22.2),与可用作 GAS 库的旧 2.4.0 相比(如接受的答案所示)。

PS - 这行得通!

于 2018-07-20T09:07:29.623 回答
1

跟随代码为我工作确保你在执行之前将 moment.js 关联到脚本中

  var moment = Moment.load()

  var StartDate= new Date(StartDate1);
  var DD1 = StartDate.getDate();    
  var MM1 = StartDate.getMonth(); 
  var MM1=MM1+1                 //As Month Start with Zero
  var YYYY1 = StartDate.getYear();

  var EndDate= new Date(EndDate1);
  var DD = EndDate.getDate();    
  var MM = EndDate.getMonth(); 
  var MM=MM+1                 //As Month Start with Zero
  var YYYY = EndDate.getYear();



  var a = moment([YYYY, MM, DD]);
  var b = moment([YYYY1, MM1, DD1]);
  return a.diff(b, 'days')
  Logger.log(a.diff(b, 'days') )
于 2013-08-11T10:44:23.283 回答
0

Date.Diff 的其他替代方案。xDate 是 Date Javascript 对象的包装器:

//-----------------------------------------------------------------------------
// Date Wrapper
//-----------------------------------------------------------------------------
var kDate = function () {
    "use strict";
    var dat = NaN, that = this;
    switch (arguments.length) {
    case 0: dat = new Date(); break;
    case 1: dat = new Date(arguments[0]); break;
    default:
        dat = new Date( arguments[0] || null, arguments[1] || null, arguments[2] || null, arguments[3] || null, 
                        arguments[4] || null, arguments[5] || null,  arguments[6] || null);
    }
    Object.getOwnPropertyNames(Date.prototype).forEach(function(prop) {
        that[prop] = function () { 
            return dat[prop].apply(dat, arguments); 
        };
    });
    return this;
};
Object.getOwnPropertyNames(Date).forEach(function(prop) {
    if (["length", "name", "arguments", "caller", "prototype"].indexOf(prop) < 0) {
        kDate[prop] = Date[prop];
    }
});

kDate.MAXDATE = 8640000000000000;
kDate.MINDATE = -8640000000000000;
kDate.YEARZERO = -62167132800000;
kDate.YEAR = 31536000000;
kDate.MONTH = 2592000000;
kDate.DAY = 86400000;
kDate.HOUR = 3600000;
kDate.MINUTE = 60000;
kDate.SECOND = 1000;

//-----------------------------------------------------------------------------
// kDate.diff()
//-----------------------------------------------------------------------------
kDate.diff = function(date1, date2) {
    var d1, d2;
    d1 = kDate.MAXDATE + (typeof date1 === 'number' ? date1 : date1.getTime());
    d2 = kDate.MAXDATE + (typeof date2 === 'number' ? date2 : date2.getTime());
    diff = new kDate(NaN);
    diff.diffDate1 = new kDate(typeof date1 === 'number' ? date1 : date1.getTime());
    diff.diffDate2 = new kDate(typeof date2 === 'number' ? date2 : date2.getTime());
    diff.diffTotalMilliseconds = d2 < d1 ? d1 - d2 : d2 - d1;
    diff.setTime(kDate.YEARZERO + diff.diffTotalMilliseconds);
    diff.diffTotalSeconds = diff.diffTotalMilliseconds / kDate.SECOND;
    diff.diffTotalMinutes = diff.diffTotalMilliseconds / kDate.MINUTE;
    diff.diffTotalHours =   diff.diffTotalMilliseconds / kDate.HOUR;
    diff.diffTotalDates =   diff.diffTotalMilliseconds / kDate.DAY;
    diff.diffYears =        diff.diffDate1.getUTCFullYear() - diff.diffDate2.getUTCFullYear();
    diff.diffMonth =        diff.diffDate1.getUTCMonth() - diff.diffDate2.getUTCMonth();
    diff.diffDate =         diff.diffDate1.getUTCDate() - diff.diffDate2.getUTCDate();
    diff.diffHours =        diff.diffDate1.getUTCHours() - diff.diffDate2.getUTCHours();
    diff.diffMinutes =      diff.diffDate1.getUTCMinutes() - diff.diffDate2.getUTCMinutes();
    diff.diffSeconds =      diff.diffDate1.getUTCSeconds() - diff.diffDate2.getUTCSeconds();
    diff.diffMilliseconds = diff.diffDate1.getUTCMilliseconds() - diff.diffDate2.getUTCMilliseconds();
    return diff;
};
kDate.prototype.diff = function (date) {
    return kDate.diff(this, date);
};
于 2013-08-11T18:46:18.660 回答
0

第二次尝试:

function periodCalc(startDate, endDate) {

  var output = '';

  var sYear = startDate.getFullYear();
  var sMonth = startDate.getMonth();
  var sDay = startDate.getDate() - 1;
  var eYear = endDate.getFullYear();
  var eMonth = endDate.getMonth();
  var eDay = endDate.getDate();

  var tMonths = eYear * 12 + eMonth - sYear * 12 - sMonth;
  var days = eDay - sDay;

  if (days < 0) {
    tMonths--;
    var sDate = new Date(sYear, sMonth + tMonths, sDay);
    var eDate = new Date(eYear, eMonth, eDay);
    days = (eDate.getTime() - sDate.getTime()) / 86400000;
  }

  if (tMonths < 0) return '0';
  var months = tMonths % 12;
  var years = (tMonths - months) / 12;

  output += (years == 0 ? '' : (', ' + years + ' Year' + (years == 1 ? '' : 's')));
  output += (months == 0 ? '' : (', ' + months + ' Month' + (months == 1 ? '' : 's')));
  output += (days == 0 ? '' : (', ' + days + ' Day' + (days == 1 ? '' : 's')));

  return output.substr(2);
}

但是,当开始日期是一个月的第一天,而结束日期是一个月的最后一天时,问题仍然存在。例如,2013 年 1 月 1 日到 2013 年 3 月 31 日将返回 2 个月 31 天。这是想要的结果吗?


编辑:第一次尝试(这是有缺陷的,请参阅第一条评论):

我必须承认我的大脑在看代码时有点受伤,我敢肯定这只会在某个地方出现逻辑上的小错误。我认为如果我尝试从头开始重写它会更快,但我认为它需要一些进一步的测试(它适用于我迄今为止的有限测试):

function periodCalc(startDate, endDate) {
  var output = '';
  endDate.setFullYear(endDate.getFullYear(), endDate.getMonth(), endDate.getDate() + 1);
  var sYear = startDate.getFullYear();
  var sMonth = startDate.getMonth();
  var sDay = startDate.getDate();

  var eDay = endDate.getDate(); 
  var days = eDay - sDay;
  if (days < 0) {
    var eopm = new Date(endDate);
    eopm.setDate(0);
    days = eDay + eopm.getDate() - sDay;
    endDate.setDate(eDay - days);
  }

  var eMonth = endDate.getMonth();
  var months = eMonth - sMonth;
  if (months < 0) {
    months = eMonth + 12 - sMonth;
    endDate.setMonth(eMonth - months);
  }

  var eYear = endDate.getFullYear();
  var years = eYear - sYear;
  if (years < 0) return '0';

  output += (years == 0 ? '' : (', ' + years + ' Year' + (years == 1 ? '' : 's')));
  output += (months == 0 ? '' : (', ' + months + ' Month' + (months == 1 ? '' : 's')));
  output += (days == 0 ? '' : (', ' + days + ' Day' + (days == 1 ? '' : 's')));

  return output.substr(2);
}
于 2013-04-22T23:50:23.280 回答
0

这是我前段时间写的东西,它没有经过全面测试,但认为它应该做它应该做的事情

[更新]:修复了错误,但当低日期是 2 月 29 日并且差异超过一年时仍然表现得很有趣

function dateDiff(a,b){
    var low = (a>b)?b:a,
    heigh = (a>b)?a:b,
    diff = {
        years:0,
        months:0,
        days:0
    },
    tmpDate,
    tmpMonth;
    //if you'd like the diff to be including the the last day
    // of the end date you can do: lob.setDate(low.getDate()+1);
    if(low==heigh){return diff;}//a===b no difference
    diff.years=heigh.getFullYear()-low.getFullYear();
    tmpDate=new Date(low.getTime());
    tmpDate.setFullYear(low.getFullYear()+diff.years);
    if(tmpDate>heigh){
      diff.years--;
    }
    low.setFullYear(low.getFullYear()+diff.years);
    tmpMonth=heigh.getMonth()-low.getMonth();
    diff.months=(tmpMonth<0)?tmpMonth+12:tmpMonth;
    tmpDate=new Date(low.getTime());
    tmpDate.setMonth(low.getMonth()+diff.months);
    if(tmpDate>heigh){
      diff.months--;
    }
    low.setMonth(low.getMonth()+diff.months);
    while(low<heigh){
        low.setDate(low.getDate()+1);
        diff.days++;
        if(low>heigh){
          low.setDate(low.getDate()-1);
          diff.days--;
          break;
        }
    }
    return diff;
}


var a = new Date(2013,9,30);
var b = new Date(2014,1,26);
console.log(dateDiff(a,b));
//next one is a bit buggy, one might say it's
// 1 year and 1 day if considoring end of feb 2000
// to 1st of mar 2001
var a = new Date(2000,1,29);
var b = new Date(2001,2,1);
console.log(dateDiff(a,b));
于 2013-04-30T02:17:08.113 回答
-1

在此处查看示例:http: //ditio.net/2010/05/02/javascript-date-difference-calculation/

更简洁的代码,更易于阅读。(它有效!);-)

于 2013-04-24T01:11:51.897 回答