package com.taobao.tddl.rule.impl.groovy; import java.util.Calendar; import java.util.Date; import com.taobao.tddl.common.utils.thread.ThreadLocalMap; /** * 可直接用于groovy规则中的便捷方法 * * @author shenxun * @author linxuan */ public class GroovyStaticMethod { public static final String GROOVY_STATIC_METHOD_CALENDAR = "GROOVY_STATIC_METHOD_CALENDAR"; private final static long[] pow10 = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000L, 100000000000L, 1000000000000L, 10000000000000L, 100000000000000L, 1000000000000000L, 10000000000000000L, 100000000000000000L, 1000000000000000000L }; /** * @return 返回4位年份 */ public static int yyyy(Date date) { Calendar cal = getCalendar(date); return cal.get(Calendar.YEAR); } public static int yyyy(Calendar cal) { return cal.get(Calendar.YEAR); } /** * @return 返回2位年份(年份的后两位) */ public static int yy(Date date) { Calendar cal = getCalendar(date); return cal.get(Calendar.YEAR) % 100; } public static int yy(Calendar cal) { return cal.get(Calendar.YEAR) % 100; } /** * @return 返回月份数字,注意:从1开始:1-12(返回 Calendar.MONTH对应的值加1) */ public static int month(Date date) { Calendar cal = getCalendar(date); return cal.get(Calendar.MONTH) + 1; } public static int month(Calendar cal) { return cal.get(Calendar.MONTH) + 1; } /** * @return 返回2位的月份字串,从01开始:01-12(Calendar.MONTH对应的值加1) */ public static String mm(Date date) { Calendar cal = getCalendar(date); int m = cal.get(Calendar.MONTH) + 1; return m < 10 ? "0" + m : String.valueOf(m); } public static String mm(Calendar cal) { int m = cal.get(Calendar.MONTH) + 1; return m < 10 ? "0" + m : String.valueOf(m); } /** * @return 返回 Calendar.DAY_OF_WEEK 对应的值 */ public static int week(Date date) { Calendar cal = getCalendar(date); return cal.get(Calendar.DAY_OF_WEEK); } public static int week(Calendar cal) { return cal.get(Calendar.DAY_OF_WEEK); } /** * 旧规则默认的dayofweek : 如果offset = 0;那么为默认 SUNDAY=1; MONDAY=2; TUESDAY=3; * WEDNESDAY=4; THURSDAY=5; FRIDAY=6; SATURDAY=7; */ public static int dayofweek(Date date, int offset) { Calendar cal = getCalendar(date); return cal.get(Calendar.DAY_OF_WEEK) + offset; } public static int dayofweek(Calendar cal, int offset) { return cal.get(Calendar.DAY_OF_WEEK) + offset; } /** * 旧规则的dayofweek.因为旧规则计算结果为数组下标,尤其表规则结果是库内表数组下标,必须从0开始, 因此必须让day of week从0 * 开始。通过直接offset = -1 解决:星期日=0,星期一=1,...星期六=6 */ public static int dayofweek(Date date) { return dayofweek(date, -1); } public static int dayofweek(Calendar cal) { return dayofweek(cal, -1); } /** * @return 返回4位年份和2位月份的字串,月份从01开始:01-12 */ public static String yyyymm(Date date) { Calendar cal = getCalendar(date); return yyyy(cal) + mm(cal); } public static String yyyymm(Calendar cal) { return yyyy(cal) + mm(cal); } /** * @return 返回 4位年份_2位月份 的字串,月份从01开始:01-12 */ public static String yyyy_mm(Date date) { Calendar cal = getCalendar(date); return yyyy(cal) + "_" + mm(cal); } public static String yyyy_mm(Calendar cal) { return yyyy(cal) + "_" + mm(cal); } /** * @return 返回2位年份和2位月份的字串,月份从01开始:01-12 */ public static String yymm(Date date) { Calendar cal = getCalendar(date); return yy(cal) + mm(cal); } public static String yymm(Calendar cal) { return yy(cal) + mm(cal); } /** * @return 返回 2位年份_2位月份 的字串,月份从01开始:01-12 */ public static String yy_mm(Date date) { Calendar cal = getCalendar(date); return yy(cal) + "_" + mm(cal); } public static String yy_mm(Calendar cal) { return yy(cal) + "_" + mm(cal); } /** * @return 返回 Calendar.DATE 对应的值。每月的1号值为1, 2号值为2... */ public static int date(Date date) { Calendar cal = getCalendar(date); return cal.get(Calendar.DATE); } public static int date(Calendar cal) { return cal.get(Calendar.DATE); } @SuppressWarnings("unused") private static Calendar getCalendar(Calendar c) { return c; } private static Calendar getCalendar(Date date) { Calendar cal = (Calendar) ThreadLocalMap.get(GROOVY_STATIC_METHOD_CALENDAR); if (cal == null) { cal = Calendar.getInstance(); ThreadLocalMap.put(GROOVY_STATIC_METHOD_CALENDAR, cal); } cal.setTime(date); return cal; } /** * @param bit 补齐后的长度 * @param table 数值 * @return 返回前面补0达到bit长度的字符串。如果table长度大于bit,则返回table的原始值 */ public static String placeHolder(int bit, long table) { if (bit > 18) { throw new IllegalArgumentException("截取的位数不能大于18位"); } if (table == 0) { // bugfix 被0除 return String.valueOf(pow10[bit]).substring(1); } if (table >= pow10[bit - 1]) { // 当数值的width >= 要求的补齐位数时,应该直接返回原始数值 return String.valueOf(table); } long max = pow10[bit]; long placedNumber = max + table; return String.valueOf(placedNumber).substring(1); } @SuppressWarnings("unused") private static long getModRight(long targetID, int size, int bitNumber) { if (bitNumber < size) { throw new IllegalArgumentException("输入的位数比要求的size还小"); } return (size == 0 ? 0 : targetID / pow10[bitNumber - size]); } /** * 从左开始,取指定多的位数。默认是一个long形长度的数据,也就是bitNumber= 19 * * @param targetID 目标id,也就是等待被decode的数据 * @param st 从哪儿开始取,如果想取最左边的一位那么可以输入st = 0;ed =1; * @param ed 取到哪儿,如果想取最左边的两位,那么可以输入st = 0;ed = 2; * @return */ // public static long leftBetween(long targetID,int st,int ed){ // int sizeAll = st + ed - 1; // if(sizeAll >= 19||sizeAll <= 0){ // throw new IllegalArgumentException("截取19位请直接使用元数据。"); // } // if(targetID / pow10[sizeAll] < 1){ // throw new IllegalArgumentException(targetID+",小于"+(st+ed)+"位,不能进行计算"); // } // long end = getModRight(targetID, ed,19); // return end % pow10[(ed-st)]; // } public static int quarter(Date date) { Calendar cal = getCalendar(date); int month = cal.get(Calendar.MONTH); return quarter(month); } public static int quarter(long month) { return quarter((int) month); } public static int halfayear(long month) { return halfayear((int) month); } public static int quarter(int month) { if (month > 11 || month < 0) { throw new IllegalArgumentException("month range is 1~12"); } return month / 3 + 1; } public static int halfayear(Date date) { Calendar cal = getCalendar(date); int month = cal.get(Calendar.MONTH); return halfayear(month); } public static int halfayear(int month) { if (month > 11 || month < 0) { throw new IllegalArgumentException("month range is 1~12,current value is " + month); } return month / 6 + 1; } /** * 从右开始,取指定多的位数。 假如参数是1234567.那么rightBetwen(1234567,2,3) 返回的数据是 345 * rightBetween(10000234,2,2) 返回的数据是2 rightBetween(10000234,3,2) 返回的数据是0 * * @param targetID 目标id,也就是等待被decode的数据 * @param closeFrom 从哪儿开始取,如果想取最右边的一位那么可以输入st = 0;ed =1; * @param openTo 取到哪儿,如果想取最右边的两位,那么可以输入st = 0;ed = 2; * @throws IllegalArgumentException 如果st+ed -1 >= 19,这时候对long来说不需要截取。 * 如果targetId小于st+ed, * @return */ public static long rightCut(long targetID, int closeFrom, int openTo) { int sizeAll = closeFrom + openTo - 1; if (sizeAll >= 19 || sizeAll < 0) { throw new IllegalArgumentException("截取19位请直接使用元数据。"); } long right = targetID / pow10[(closeFrom)]; right = right % pow10[openTo]; return right; } public static long right(long targetID, int size) { if (size >= 19 || size < 0) { throw new IllegalArgumentException("截取19位请直接使用元数据。"); } return targetID % pow10[size]; } public static void validate(long targetID, int size) { if (targetID / pow10[size - 1] < 1) { throw new IllegalArgumentException(targetID + ",小于" + (size) + "位,不能进行计算"); } } public static String right(String right, int rightLength) { int length = right.length(); int start = length - rightLength; return right.substring(start < 0 ? 0 : start); } }