计算谷歌应用脚​​本中日期之间的年,月,日

时间:2013-04-22 14:34:47

标签: javascript date datetime google-apps-script

我使用下面的函数进行计算,它以“X年,Y个月,Z天”的格式给出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,则返回false o / p:

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

预计o / p:1年,1天

给定o / p:1年,4天

但是,如果我选择2013年第28届 - 2014年第27届年会意味着,它给出了正确的o / p:

预计o / p:1年

给定o / p:1年

如果我做了什么,请建议纠正我的错误。

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

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

而且,如果我们为每月租金提供一个房间,我们每个月只会支付租金吗?即便是从3月20日到4月19日。即使它包含31天,据说只有一个月。请帮我结束这个。

TNX, CL。

7 个答案:

答案 0 :(得分:20)

对于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(', ');
}

答案 1 :(得分:1)

您可以将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)

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

PS-可以!

答案 2 :(得分: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);
}

答案 3 :(得分: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));

答案 4 :(得分:0)

以下代码工作 确保在执行

之前在脚本中关联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') )

答案 5 :(得分: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);
};

答案 6 :(得分:-1)

点击此处的示例: http://ditio.net/2010/05/02/javascript-date-difference-calculation/

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