javascript 在谷歌应用程序脚本中计算日期之间的年、月、日
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16149760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calculating year, month, days between dates in google apps script
提问by chocka
I have calculated using the below function and it gives the o/p in the format of "X YEARS, Y MONTHS, Z DAYS" and for some dates its giving some wrong o/p. I think I did some calculation missing in the formulas.
我已经使用下面的函数进行了计算,它以“X YEARS, Y MONTHS, Z DAYS”的格式给出了 o/p,对于某些日期,它给出了一些错误的 o/p。我想我做了一些公式中缺少的计算。
The function is,
功能是,
/**
* @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);
}
}
if you gives the i/p as below it returning the false o/p:
如果你给出如下的 i/p,它会返回错误的 o/p:
28th feb 2013 - 28th feb 2014
2013年2月28日-2014年2月28日
Expected o/p : 1 YEAR , 1 DAY
预期 o/p : 1 年 1 天
Given o/p : 1 YEAR , 4 DAYS
鉴于 o/p : 1 年 , 4 天
But if I select 28th feb 2013 - 27th feb 2014 means, It gave the correct o/p:
但是,如果我选择 2013 年 2 月 28 日 - 2014 年 2 月 27 日意味着,它给出了正确的 o/p:
Expected o/p : 1 YEAR
预期 o/p : 1 年
Given o/p : 1 YEAR
给定 o/p : 1 年
Please advice to correct my fault if I did anything.
如果我做了什么,请建议纠正我的错误。
And also I have to tell that I'm not setting the rules n all. In general a month is calculating as per the days lying on the month.
而且我必须告诉我,我并没有制定所有规则。一般来说,一个月是根据该月的天数计算的。
For example, If we get a loan from a bank we ll pay the interest per month only even that month may have 30 days or 29 days or 28 days or 31 days.
例如,如果我们从银行获得贷款,即使该月可能有 30 天或 29 天或 28 天或 31 天,我们也只会支付每月的利息。
And also if we take a room for monthly rental means, We ll pay the rent per month only rite? even it can be from 20th March - 19th April. Even it contains 31 days it is said to be one month only. Please help me to conclude this.
而且,如果我们把一个房间每月出租意味着,我们会支付每月的租金吗?甚至可以是从 3 月 20 日到 4 月 19 日。即使它包含31天,据说也只有一个月。请帮我总结一下。
Tnx, CL.
Tnx,CL。
回答by Eric Koleda
For complex date/time manipulations in JavaScript I find that the Moment.jslibrary can really help. I wrapped it up into an Apps Script library, which you can include using the project key MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48. I used it to take a crack at this problem, although I may have missed some edge cases.
对于 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(', ');
}
回答by Ketan Patil
You can include moment.js
as an external dependancy and use it inside Google App Script project. Refering to https://stackoverflow.com/a/45231921/5429123article, you can do something like this.
您可以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)
This will get you the last version of moment.js (2.22.2 as of 2018/10/25), compared to the old 2.4.0 available as a GAS library (like the accepted answer suggests).
与作为 GAS 库提供的旧 2.4.0 相比,这将为您提供 moment.js 的最新版本(2018/10/25 的 2.22.2)(如已接受的答案所暗示的那样)。
PS - This works!
PS - 这有效!
回答by PulsarManiac
Following Code Work for me Make sure u associate moment.js in script before executing
以下代码对我来说有效确保在执行之前将 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') )
回答by pabloalmunia
Other alternative of Date.Diff. xDate is a wrapper over Date Javascript object:
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);
};
回答by AdamL
Second attempt:
第二次尝试:
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);
}
However an issue remains when the start date is the first day of a month, and the end date is the last day of the month. So for example, 1 Jan 2013 to 31 March 2013 will return 2 months, 31 days. Is this the desired result?
但是,当开始日期是一个月的第一天,而结束日期是该月的最后一天时,问题仍然存在。例如,2013 年 1 月 1 日至 2013 年 3 月 31 日将返回 2 个月零 31 天。这是想要的结果吗?
Edit: first attempt (which is flawed, see first comment):
编辑:第一次尝试(这是有缺陷的,见第一条评论):
I must admit my brain was hurting a bit looking at the code, which I'm sure would only have a minor error in logic somewhere. I thought it would be quicker if I tried re-writing it from scratch, but I think it would need some further testing (it works with my limited testing so far):
我必须承认我的大脑在看着代码时有点受伤,我确信这只会在某处逻辑上有一个小错误。我认为如果我尝试从头开始重写它会更快,但我认为它需要一些进一步的测试(它适用于我目前有限的测试):
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);
}
回答by HMR
Here is something I wrote a while ago, it's not fully tested but think it should do what it's supposed to do
这是我前一段时间写的东西,它没有经过全面测试,但认为它应该做它应该做的
[UPDATE]: fixed the bug but still acting funny when low date is feb 29 and diff is more than one year
[更新]:修复了错误,但当低日期为 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));
回答by miturbe
Check out the example here: http://ditio.net/2010/05/02/javascript-date-difference-calculation/
在此处查看示例:http: //ditio.net/2010/05/02/javascript-date-difference-calculation/
Much cleaner code and easier to read. (and it works!) ;-)
更简洁的代码和更容易阅读。(它有效!);-)