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

cho*_*cka 8 javascript datetime date 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你给i/p如下,则返回假o/p:

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

预计o/p:1年,1天

给定o/p:1年,4天

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

预计o/p:1年

给定o/p:1年

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

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

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

而且,如果我们采取月租房的方式,我们每个月只会支付租金吗?即便是从3月20日到4月19日.即使它包含31天,据说只有一个月.请帮我总结一下.

Tnx,CL.

Eri*_*eda 22

对于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(', ');
}
Run Code Online (Sandbox Code Playgroud)

  • 很棒,@ Eric.你是如何用GAS消费的? (5认同)
  • 我还想知道如何为Google Apps脚本包装JavaScript库. (3认同)
  • 该脚本将其ID更改为[15hgNOjKHUG4UtyZl9clqBbl23sDvWMS8pfDJOyIapZk5RBqwL3i-rlCo](https://script.google.com/home/projects/15hgNOjKHUG4UtyZl9clqBbl23sDvWMS8pfDJOyIapZk5RBqwL3i-rlCo/edit) (2认同)

Ada*_*amL 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);
}
Run Code Online (Sandbox Code Playgroud)

但是,当开始日期是该月的第一天而结束日期是该月的最后一天时,仍然存在问题。例如,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);
}
Run Code Online (Sandbox Code Playgroud)