package jef.database.routing.function; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.List; import jef.database.DbCfg; import jef.database.annotation.PartitionFunction; import jef.database.query.RegexpDimension; import jef.tools.Assert; import jef.tools.DateFormats; import jef.tools.DateUtils; import jef.tools.JefConfiguration; import jef.tools.StringUtils; /** * 抽象类,一般用于进行分表取特征值的日志处理函数 * * @author Administrator * */ public abstract class AbstractDateFunction implements PartitionFunction<Date> { static String span = JefConfiguration.get(DbCfg.PARTITION_DATE_SPAN, "-6,3"); protected int before; protected int after; private AbstractDateFunction() { String[] srange = StringUtils.split(span, ','); Assert.isTrue(srange.length == 2); before = StringUtils.toInt(srange[0], -6); after = StringUtils.toInt(srange[1], 3); } public boolean acceptRegexp() { return false; } public Collection<Date> iterator(RegexpDimension regexp) { throw new UnsupportedOperationException(); } // 四位数年 public static final AbstractDateFunction YEAR = new AbstractDateFunction() { public String eval(Date value) { return String.valueOf(DateUtils.getYear(value)); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.YEAR); while (gval.getTime().getTime() <= endSec) { ret.add(gval.getTime()); gval.add(Calendar.YEAR, 1); } return ret; } @Override public int getTimeLevel() { return 5; } @Override List<Date> iterateAll() { Date date1 = new Date(); Date date2 = new Date(); DateUtils.addMonth(date1, before); DateUtils.addMonth(date2, after); return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction YEAR_MONTH = new AbstractDateFunction() { public String eval(Date value) { return DateUtils.format(value, DateFormats.YAER_MONTH); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.MONTH); while (gval.getTime().getTime() <= endSec) { ret.add(gval.getTime()); gval.add(Calendar.MONTH, 1); } return ret; } @Override public int getTimeLevel() { return 4; } @Override List<Date> iterateAll() { Date date1 = new Date(); Date date2 = new Date(); DateUtils.addMonth(date1, before); DateUtils.addMonth(date2, after); return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction YEAR_MONTH_DAY = new AbstractDateFunction() { public String eval(Date value) { return DateUtils.format(value, DateFormats.DATE_SHORT); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.DATE); long date = gval.getTimeInMillis(); while (date <= endSec) { ret.add(new Date(date)); date = date + 86400000L;// 直接加一天的毫秒数.直接计算性能最好,之所以+1月要借助Calendar对象是因为加一个月太复杂了。 } return ret; } @Override public int getTimeLevel() { return 3; } @Override List<Date> iterateAll() { Date date1 = new Date(); Date date2 = new Date(); DateUtils.addDay(date1, before); DateUtils.addDay(date2, after); return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction MONTH = new AbstractDateFunction() { public String eval(Date value) { return String.valueOf(DateUtils.getMonth(value)); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.MONTH); while (gval.getTime().getTime() <= endSec) { ret.add(gval.getTime()); gval.add(Calendar.MONTH, 1); } return ret; } public int getTimeLevel() { return 4; } @Override List<Date> iterateAll() { Date date1 = DateUtils.get(1970, 1, 1); Date date2 = DateUtils.get(1970, 12, 1); return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction DAY = new AbstractDateFunction() { public String eval(Date value) { return String.valueOf(DateUtils.getDay(value)); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.DATE); long date = gval.getTimeInMillis(); while (date <= endSec) { ret.add(new Date(date)); date = date + 86400000L;// 直接加一天的毫秒数.直接计算性能最好,之所以+1月要借助Calendar对象是因为加一个月太复杂了。 } return ret; } @Override public int getTimeLevel() { return 3; } @Override List<Date> iterateAll() { Date tmp = new Date(); Date date1 = DateUtils.monthBegin(tmp); Date date2 = DateUtils.lastDayOfMonth(tmp); return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction WEEKDAY = new AbstractDateFunction() { public String eval(Date value) { return String.valueOf(DateUtils.getWeekDay(value)); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.DATE); long date = gval.getTimeInMillis(); while (date <= endSec) { ret.add(new Date(date)); date = date + 86400000L;// 直接加一天的毫秒数.直接计算性能最好,之所以+1月要借助Calendar对象是因为加一个月太复杂了。 } return ret; } @Override public int getTimeLevel() { return 3; } @Override List<Date> iterateAll() { Date date1 = new Date(); Date date2 = new Date(); DateUtils.addDay(date2, 7); return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction HH24 = new AbstractDateFunction() { public String eval(Date value) { return String.valueOf(DateUtils.getHour(value)); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.HOUR_OF_DAY); long date = gval.getTimeInMillis(); while (date <= endSec) { ret.add(new Date(date)); date = date + 3600000L;// 直接加一小时的毫秒数 } return ret; } @Override public int getTimeLevel() { return 2; } @Override List<Date> iterateAll() { Date date1 = new Date(); date1 = DateUtils.dayBegin(date1); Date date2 = DateUtils.dayEnd(date1); ; return innerIterator(date1, date2, true, true); } }; public static final AbstractDateFunction YEAR_LAST2 = new AbstractDateFunction() { public String eval(Date value) { return String.valueOf(DateUtils.getYear(value)).substring(2); } public List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { List<Date> ret = new ArrayList<Date>(); Calendar gval = Calendar.getInstance(); gval.setTime(sDate); long endSec = eDate.getTime(); if (!rightInclude) endSec--; DateUtils.truncate(gval, Calendar.MONTH); while (gval.getTime().getTime() <= endSec) { ret.add(gval.getTime()); gval.add(Calendar.MONTH, 1); } return ret; } @Override public int getTimeLevel() { return 5; } @Override List<Date> iterateAll() {// 从去年向后数10年 Date date1 = new Date(); Date date2 = new Date(); DateUtils.addMonth(date1, before); DateUtils.addMonth(date2, after); return innerIterator(date1, date2, true, false); } }; public List<Date> iterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude) { if (sDate == null && eDate == null) {// 表示全区间 return iterateAll(); } else if (sDate == null) {// 负无穷区间,直接报错 throw new UnsupportedOperationException("The min date of this query can not be detimed."); } else if (eDate == null) { eDate = new Date(); } return innerIterator(sDate, eDate, leftInclude, rightInclude); } /** * 得到时间段的范围:年5/月4/日3/小时2.这是为了当用户在一个字段上设置了多个分表维度时,取最小的单位来度量值的分布情况 * * @return */ abstract public int getTimeLevel(); abstract List<Date> iterateAll(); abstract protected List<Date> innerIterator(Date sDate, Date eDate, boolean leftInclude, boolean rightInclude); }