我使用下面的函数进行计算,它以“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。
答案 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/
更清晰的代码,更易于阅读。 (它有效!); - )