最近在用JS处理网页表单上的快速填充项,用户点击诸如“本周”,“上季度”的按钮即可把相应的时间段填充到文本域中,JS不像其他语言那么智能,相关的日期处理需要另外写轮子,网上有很多例子,都写得比较长,而且分开了很多函数来写,不太灵便,于是我按照我自己的想法和对JS的理解,琢磨出了下面的单个函数,可以简便地获取一个日期段的开始和结束日期,条理也清晰(时分秒的处理比较简单,可以调用函数后再处理,所以没有添加到函数里面)
本函数可以计算:
- n天前/后日期
- n个周期的周起始和周结束日(如本周起始结束、上周起始结束等)
- n个周期的月起始和月结束日(如本月起始结束、上月起始结束等)
- n个周期的季度起始和季度结束日(如本季度起始结束、上季度起始结束等)
使用了递归方法来缩减代码,本函数仅30行
//函数,计算某周期的起始日期和结束日期
//参数date,基准时间,请传入带毫秒的时间戳
//参数di,相隔周期,如本周期则设置为0
//参数type,周期类型,(d:天,w:周,m:月,s:季度,y:年)
//返回,如果type=d,返回目标日期,其他type,返回目标周期的起始和结束日数组,类型为时间戳
function DateSE(date,di,type) {
var fdata = new Date(date);
var y = fdata.getFullYear();
var m = fdata.getMonth();
switch (type) {
case "d":
return date + di * 86400000;
case "w":
var wd = fdata.getDay();
var ws = DateSE(fdata.getTime(), wd * -1, "d");
var SD = DateSE(ws, di * 7, "d");
var ED = DateSE(SD, 6, "d");
return [SD, ED];
case "m":
var newms = y * 12 + m + di;
var newmsp1 = y * 12 + m + di + 1;
var newy = parseInt(newms / 12);
var newm = newms % 12;
var newyp1 = parseInt(newmsp1 / 12);
var newmp1 = newmsp1 % 12;
return [new Date(newy, newm, 1).getTime(), new Date(newyp1, newmp1, 0).getTime()];
case "s":
var thisms = new Date(y, m, 1).getTime();
var pme = new Date(y, m, 0).getTime();
return [DateSE(thisms, di * 3 - 1, "m")[0], DateSE(pme, di * 3 + 2, "m")[1]];
case "y":
var thisys = new Date(y, 0, 1).getTime();
var pye = new Date(y, 0, 0).getTime();
return [DateSE(thisys, di * 12, "m")[0], DateSE(pye, di * 12 + 12, "m")[1]];
}
}
使用例子
function formatDate(D) {
var fdata = new Date(D);
console.log(D);
return fdata.getFullYear() + "-" + (fdata.getMonth() + 1) + "-" + fdata.getDate();
}
//点击按钮获取上季度起始和结束
$(document).on("click", ".btn-dps", function () {
var ds = DateSE(new Date().getTime(),-1,"s");
$("#st").val(formatDate(ds[0]));
$("#et").val(formatDate(ds[1]));
});
//点击按钮获取本月起始和结束
$(document).on("click", ".btn-ptm", function () {
var ds = DateSE(new Date(),0,"m");
$("#st").val(formatDate(ds[0]));
$("#et").val(formatDate(ds[1]));
});
注意:按照标准,每个星期从周日开始,以周六结束