昨天在弄一个项目,我和同事分别负责不同的模块,但是我们有一个相似的功能,就是数据默认取最近一个月的数据。
虽然重复造轮子容易有坑,但是有时时间比较急的时候,这个也是比较难以避免的。
公共方法,此处可不细看,用于处理时间显示效果:
function formatDate (date, format) {
if (!date) return;
if (!format) format = "yyyy-MM-dd";
switch (typeof date) {
case "string":
date = new Date(date.replace(/-/, "/"));
break;
case "number":
date = new Date(date);
break;
}
if (!date instanceof Date) return;
var dict = {
"yyyy": date.getFullYear(),
"M": date.getMonth() + 1,
"d": date.getDate(),
"H": date.getHours(),
"m": date.getMinutes(),
"s": date.getSeconds(),
"MM": ("" + (date.getMonth() + 101)).substr(1),
"dd": ("" + (date.getDate() + 100)).substr(1),
"HH": ("" + (date.getHours() + 100)).substr(1),
"mm": ("" + (date.getMinutes() + 100)).substr(1),
"ss": ("" + (date.getSeconds() + 100)).substr(1)
};
return format.replace(/(yyyy|MM?|dd?|HH?|ss?|mm?)/g, function () {
return dict[arguments[0]];
});
}
以下是我取的最近一个月数据的实现方法,主要是应用了setMonth和getMonth来实现:
let date = "2018-11-16";
let startDate = new Date(date);
startDate = startDate.setMonth(startDate.getMonth() - 1);
var endDate = Date.parse(new Date(date));
var query = {
firOnSellTimeBegin:Date.parse(formatDate(parseInt(startDate)) + ' 0:00:00'),
firOnSellTimeEnd: Date.parse(formatDate(parseInt(endDate)) + ' 23:59:59')
}
而我的同事,则默认取了最近30天当作最近一个月,代码如下:
let d = new Data('2018-11-16');
let endDate = d.getTime();
let startDate = endDate - (30 * 24 * 60 * 60 * 1000);
this.query = Object.assign(this.query, {
firOnSellTimeBegin: Date.parse(ctrlFunc.formatDate(parseInt(startDate)) + ' 0:00:00'),
firOnSellTimeEnd: Date.parse(ctrlFunc.formatDate(parseInt(endDate)) + ' 23:59:59')
});
分析:
取最近30天肯定是有问题的,因为最近30天是最近一个月,那最近三个月呢?是最近90天?
当然不是这样理解,所以同事的代码被ko掉了,我的代码就对了?那最近一个月究竟要怎么取?
我们前端组得出一个结论,不管怎么取,前后端至少要统一。
然后我们又去找后端看看他们的最近一个月是怎么取的,
假设2018-11-16,后端取最近一个月,结果起始为2018-11-16
假设2018-10-31,后端取最近一个月,结果起始为2018-09-30
假设2018-03-31,后端取最近一个月,结果起始为2018-02-28
得出结论,后端最近一个月的结果为:月份减1,日期不变,若上个月没有该天,则取该月最后一天。
神坑:
重新检查我的代码,然后发现一个神坑,看如下图便可一下发现问题:

通过getMonth()和setMonth()方法,2018年3月31号的最近一个月既然是2018年3月3号?
原来该方法取最近一个月效果是:3月有31天,然后2月只有28天,则31减28等于3,然后日期自动往后推了3天,即结果为3月3日,这可和后端的结果相差可远呢。
解决办法:
由于我们当前开发的项目已引入monent.js, 估方法如下:
let moment = require('moment');
let date = ctrlFunc.formatDate(new Date(), 'yyyy-MM-dd');
let d = new Date(date);
let endDate = d.getTime();
let query = {
firOnSellTimeBegin: Date.parse(moment(date).subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss')),
firOnSellTimeEnd: Date.parse(ctrlFunc.formatDate(parseInt(endDate)) + ' 23:59:59'),
};
统一前后端最近一月数据获取
探讨了前端与后端在获取最近一个月数据时的差异及解决方案,分析了不同方法的优缺点,并最终采用moment.js实现了与后端一致的时间范围获取。
1540

被折叠的 条评论
为什么被折叠?



