有时需要按周统计信息,或者将没有数据的日期补齐返给前端形成统计图:条形图、饼图等
一、java方式
获取当前日期上一个自然周内数据,注意默认的是星期六到星期一,如果想让星期一是第一天~星期日,就要获取本周的星期日,上周的星期一,再通过sql传入计算的开始时间截止时间:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public static final String DATE_PATTERN = "yyyy-MM-dd";
public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* 获取星期的第一天,最后一天
* n为推迟的周数,1本周,-1向前推迟一周,2下周,依次类推
* m为星期几
*/
public static String getWeek(int n, int m) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, n * 7);
cal.set(Calendar.DAY_OF_WEEK, m);
return new SimpleDateFormat(DateUtil.DATE_PATTERN).format(cal.getTime());
}
/**
* 获取两个日期(含时分秒)相差的天数,包含今天
*
* @param startDate
* @param endDate
* @return
* @throws ParseException
*/
public static int dateBetweenIncludeToday(Date startDate, Date endDate) throws ParseException {
return dateBetween(startDate, endDate) + 1;
}
public static int dateBetween(Date startDate, Date endDate) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
startDate = sdf.parse(sdf.format(startDate));
endDate = sdf.parse(sdf.format(endDate));
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
long time1 = cal.getTimeInMillis();
cal.setTime(endDate);
long time2 = cal.getTimeInMillis();
long between_days = (time2 - time1) / (1000 * 3600 * 24);
return Integer.parseInt(String.valueOf(between_days));
}
/**
* 将秒值转换为时分秒工具类
*
* @param second
* @return
*/
public static String secToTime(int second) {
int hour = second / 3600;
int minite = second % 3600 / 60;
int sec = second % 60;
String timeStr = "";
if (hour > 0) {
timeStr += hour + "小时";
}
if (minite > 0) {
timeStr += minite + "分";
}
if (sec > 0) {
timeStr += sec + "秒";
}
return timeStr;
}
public static void main(String[] args) {
String startTime = DateUtil.getWeek(-1, Calendar.MONDAY);
String endTime= DateUtil.getWeek(0, Calendar.SUNDAY);
}
}
二、数据库方式
统计上一周的每天用户注册数量,没有数量的补齐日期,mysql为例:
SELECT
t1.timeDay as date,ifnull(t2.num,0) num
FROM (
SELECT
date_format(lastWeek.`timeDay`,'%m-%d') as 'timeDay'
FROM (
select DATE_SUB(NOW(),interval 13 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 12 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 11 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 10 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 9 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 8 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 7 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 6 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 5 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 4 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 3 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 2 day) as 'timeDay'
UNION ALL
select DATE_SUB(NOW(),interval 1 day) as 'timeDay'
) as lastWeek
WHERE YEARWEEK(lastWeek.`timeDay`,1) = YEARWEEK(NOW(),1)-1
) as t1
LEFT JOIN (
SELECT
count( DISTINCT user_id ) num,
DATE_FORMAT( a.create_time, "%m-%d" ) date
FROM
user_info a
GROUP BY
DATE_FORMAT (a.create_time,"%Y-%m-%d")
) as t2 ON t1.timeDay = t2.date
ORDER BY t1.timeDay