@@ -2,7 +2,9 @@ package cc.smtweb.framework.core.util; | |||||
import org.apache.commons.lang3.time.DateUtils; | import org.apache.commons.lang3.time.DateUtils; | ||||
import java.sql.Timestamp; | |||||
import java.text.DateFormat; | import java.text.DateFormat; | ||||
import java.text.ParseException; | |||||
import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
import java.util.Calendar; | import java.util.Calendar; | ||||
import java.util.Date; | import java.util.Date; | ||||
@@ -23,12 +25,213 @@ public class DateUtil { | |||||
private static ThreadLocal<DateFormat> simpleDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd")); | private static ThreadLocal<DateFormat> simpleDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd")); | ||||
private static ThreadLocal<DateFormat> simpleDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss")); | private static ThreadLocal<DateFormat> simpleDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss")); | ||||
private static ThreadLocal<DateFormat> simpleLongDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmssSSS")); | private static ThreadLocal<DateFormat> simpleLongDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmssSSS")); | ||||
private static TimeZone mTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); | |||||
private static ThreadLocal<DateFormat> stdTimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("HH:mm:ss")); | |||||
private static ThreadLocal<DateFormat> stdLongDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")); | |||||
final static int[] m_seasonBeginTable = new int[]{ | |||||
Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY, | |||||
Calendar.APRIL, Calendar.APRIL, Calendar.APRIL, | |||||
Calendar.JULY, Calendar.JULY, Calendar.JULY, | |||||
Calendar.OCTOBER, Calendar.OCTOBER, Calendar.OCTOBER | |||||
}; | |||||
private static TimeZone mTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); | |||||
private DateUtil(){} | private DateUtil(){} | ||||
/** | |||||
* 取得系统今天的时间串 | |||||
* | |||||
* @return current datetime, pattern: "yyyy-MM-dd HH:mm:ss". | |||||
*/ | |||||
public static String nowStdDateTimeString() { | |||||
return stdDatetimeFormat.get().format(nowTimestamp()); | |||||
} | |||||
/** | |||||
* Return a Timestamp for right now | |||||
* | |||||
* @return Timestamp for right now | |||||
*/ | |||||
public static Timestamp nowTimestamp() { | |||||
return new Timestamp(System.currentTimeMillis()); | |||||
} | |||||
/** | |||||
* 得到如下格式字符串 "YYYY-MM-DD" | |||||
* | |||||
* @param d 时间戳 如果传入为null,则返回“”; | |||||
* @return 日期时间串 | |||||
*/ | |||||
public static String toStdDateString(Date d) { | |||||
if (d == null) return ""; | |||||
return stdDateFormat.get().format(d); | |||||
} | |||||
/** | |||||
* 比较两个日期是否相等 | |||||
*/ | |||||
public static int compareDate(Date a, Date b) { | |||||
// java.sql.Date date = new java.sql.Date(System.currentTimeMillis()); | |||||
// date中,会保留有时间秒数. | |||||
// java.sql.Date a = java.sql.Date.valueOf("2007-01-01"); | |||||
// a中,就没有时间秒数 | |||||
// 所以,在比较时就统一按字符串[yyyy-MM-dd]进行比较而不直接用a.compareTo(b) | |||||
String stra = toStdDateString(a); | |||||
String strb = toStdDateString(b); | |||||
return stra.compareTo(strb); | |||||
} | |||||
/** | |||||
* 获取当前时间数字串,例如20100909121359 标识2010年09月09日 12时13分59秒 | |||||
* | |||||
* @return Long | |||||
*/ | |||||
public static Long nowDateTimeNumber() { | |||||
return Long.valueOf(nowDateTimeString()); | |||||
} | |||||
/** | |||||
* 取得系统今天的时间串 | |||||
* | |||||
* @return current datetime, pattern:"yyyyMMddHHmmss" | |||||
*/ | |||||
public static String nowDateTimeString() { | |||||
return simpleDatetimeFormat.get().format(nowTimestamp()); | |||||
} | |||||
/** | |||||
* 将yyyyMMdd变为yyyy-mm-dd | |||||
* | |||||
* @param s 原日期串,默认用-进行分割 | |||||
* @return yyyy-mm-dd | |||||
*/ | |||||
public static String toStdDateString(String s) { | |||||
if (PubUtil.isEmptyId(s)) return ""; | |||||
if (s.contains("-")) return s; | |||||
return toStdDateString(s, "-", false); | |||||
} | |||||
/** | |||||
* 将yyyyMMdd日期串用分隔符进行分割 | |||||
* | |||||
* @param s 原日期串,默认用-进行分割 | |||||
* @param split 分隔符; | |||||
* @param returnEmptyIfErrDate 如果不是8位的日期串,则控制是反馈“”,还是返回原串; | |||||
* @return 用分隔符,如“-”,“.”进行分割后的日期串; | |||||
*/ | |||||
public static String toStdDateString(String s, String split, boolean returnEmptyIfErrDate) { | |||||
if (PubUtil.isEmptyId(s)) return ""; | |||||
try { | |||||
if (s == null || s.length() < 8) { | |||||
return returnEmptyIfErrDate ? "" : s; | |||||
} | |||||
return s.substring(0, 4) + split + s.substring(4, 6) + split + s.substring(6, 8); | |||||
} catch (Exception e) { | |||||
return ""; | |||||
} | |||||
} | |||||
/** | |||||
* 得到如下字符串 "YYYY-dd | |||||
* | |||||
* @param d String, 例如20110304131101 | |||||
* @return 日期时间串,如:2011-03 | |||||
*/ | |||||
public static String toStdYd(String d) { | |||||
if (d == null || d.length() <6) return ""; | |||||
return d.substring(0, 4)+"-"+d.substring(4,6); | |||||
} | |||||
/** | |||||
* @param datetime 时间戳,例如20110304131101; | |||||
* @return 毫秒数 | |||||
*/ | |||||
public static long getTimeInMillis(String datetime) { | |||||
if (datetime == null) return 0L; | |||||
try { | |||||
Calendar calendar = Calendar.getInstance(); | |||||
calendar.setTime(stdDatetimeFormat.get().parse(datetime)); | |||||
return calendar.getTimeInMillis(); | |||||
} catch (Exception e) { | |||||
return 0L; | |||||
} | |||||
} | |||||
/** | |||||
/** | |||||
* a是否小于当前日期 | |||||
*/ | |||||
public static boolean isLessThanCurrentDate(java.sql.Date a) { | |||||
int i = compareDate(a, new java.sql.Date(System.currentTimeMillis())); | |||||
return i < 0; | |||||
} | |||||
/** | |||||
* a是否小于b | |||||
*/ | |||||
public static boolean isLessThanCurrentDate(java.sql.Date a, java.sql.Date b) { | |||||
int i = compareDate(a, b); | |||||
return i < 0; | |||||
} | |||||
/** | |||||
* 检查beging + days 是否在end前[包括end];(如:招行开始日期与结束日期之差只能在100以内) | |||||
* | |||||
* @return false 大于了end | |||||
*/ | |||||
public synchronized static boolean isBeforeDate(Date beging, int days, Date end) { | |||||
GregorianCalendar gc = new GregorianCalendar(); | |||||
gc.setTimeZone(mTimeZone); | |||||
gc.setTime(beging); | |||||
gc.add(GregorianCalendar.DATE, days - 1); | |||||
Date addDate = gc.getTime(); | |||||
return (end.compareTo(addDate) <= 0); | |||||
} | |||||
/** | |||||
* 得到如下字符串 "YYYY-MM-DD HH:MM:SS" | |||||
* | |||||
* @param d 时间戳,如果传入为null,则返回“”; | |||||
* @return 日期时间串 | |||||
*/ | |||||
public static String toStdDateTimeString(Date d) { | |||||
if (d == null) return ""; | |||||
return stdDatetimeFormat.get().format(d); | |||||
} | |||||
/** | |||||
* 得到如下字符串 "YYYY-MM-DD HH:MM:SS" | |||||
* | |||||
* @param d long, 例如20110304131101 | |||||
* @return 日期时间串,如:2011-03-04 13:11:01 | |||||
*/ | |||||
public static String toStdDateTimeString(long d) { | |||||
return toStdDateTimeString(String.valueOf(d)); | |||||
} | |||||
/** | |||||
* 得到如下字符串 "YYYY-MM-DD HH:MM:SS" | |||||
* | |||||
* @param d String, 例如20110304131101 | |||||
* @return 日期时间串,如:2011-03-04 13:11:01 | |||||
*/ | |||||
public static String toStdDateTimeString(String d) { | |||||
if (d == null || d.length() != 14) return ""; | |||||
return toStdDateString(d.substring(0, 8)) + " " + d.substring(8, 10) + ":" + d.substring(10, 12) + ":" + d.substring(12); | |||||
} | |||||
/** | |||||
* 得到如下字符串 "MM-DD HH:MM" | |||||
* | |||||
* @param d String, 例如20110304131101 | |||||
* @return 日期时间串,如:03-04 13:11 | |||||
*/ | |||||
public static String toStdDateTime3String(String d) { | |||||
if (d == null || d.length() != 14) return ""; | |||||
return toStdDateString(d.substring(0, 8)).substring(5) + " " + d.substring(8, 10) + ":" + d.substring(10, 12); | |||||
} | |||||
/** | |||||
* 得到如下字符串 "YYYY-MM-DD HH:MM" | |||||
* | |||||
* @param d String, 例如20110304131101 | |||||
* @return 日期时间串,如:2011-03-04 13:11 | |||||
*/ | |||||
public static String toStdDateTime2String(String d) { | |||||
if (d == null || d.length() != 14) return ""; | |||||
return toStdDateString(d.substring(0, 8)) + " " + d.substring(8, 10) + ":" + d.substring(10, 12); | |||||
} | |||||
/** | |||||
* 获取星期几 | |||||
* | |||||
*/ | |||||
public static String getWeekOfDay() { | |||||
return simpleWeekFormat.get().format(nowTimestamp()); | |||||
} | |||||
/** | |||||
* 获取当前时间 | * 获取当前时间 | ||||
* @return | * @return | ||||
*/ | */ | ||||
@@ -436,6 +639,423 @@ public class DateUtil { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 取与指定日期间隔年的日期 | |||||
* | |||||
* @return String java.sql.Date.toString() | |||||
*/ | |||||
public synchronized static String getAfterYear(Date dt, int years) { | |||||
if (dt == null) return ""; | |||||
if (years == 0) return dt.toString(); | |||||
GregorianCalendar dy = new GregorianCalendar(); | |||||
dy.setTime(dt); | |||||
dy.add(GregorianCalendar.YEAR, years); | |||||
java.sql.Date ret = new java.sql.Date(dy.getTimeInMillis()); | |||||
return ret.toString(); | |||||
} | |||||
/** | |||||
* 取与指定日期间隔年的日期 | |||||
* | |||||
* @param dt (yyyy-mm-dd) | |||||
* @param years 间隔年 j | |||||
* @return java.sql.Date.toString() | |||||
*/ | |||||
public static String getAfterYear(String dt, int years) { | |||||
return getAfterYear(java.sql.Date.valueOf(dt), years); | |||||
} | |||||
/** | |||||
* get days between fromDate and thruDate | |||||
* | |||||
* @return the days between fromDate and thruDate | |||||
*/ | |||||
public static int getDifferDays(Date f, Date t) throws IllegalArgumentException { | |||||
return getDifferSeconds(f, t) / (24 * 60 * 60); | |||||
} | |||||
public static int getDifferMinutes(Date f, Date t) throws IllegalArgumentException { | |||||
return getDifferSeconds(f, t) / 60; | |||||
} | |||||
public static int getDifferMinutes(String f, String t) throws IllegalArgumentException { | |||||
return getDifferSeconds(Timestamp.valueOf(f), Timestamp.valueOf(t)) / 60; | |||||
} | |||||
public static int getDifferMinutes(long f, long t) throws IllegalArgumentException { | |||||
return getDifferSeconds(new Date(f), new Date(t)) / 60; | |||||
} | |||||
public static int getDifferSeconds(Date f, Date t) throws IllegalArgumentException { | |||||
if (f == null || t == null) return 0; | |||||
if (t.compareTo(f) < 0) { | |||||
String msg = "[" + t + "] 比" + "[" + f + "] 早, 应该相反!"; | |||||
throw new IllegalArgumentException(msg); | |||||
} | |||||
return (int) ((t.getTime() - f.getTime()) / 1000); | |||||
} | |||||
/** | |||||
* 判断strDate 是否是日期格式的字符串(支持如 yyyy-mm-dd)。 | |||||
* | |||||
* @param strDate 字符串,判断其是否为日期格式。 | |||||
* @return boolean 如果为日期格式则返回=true; | |||||
*/ | |||||
public static boolean isDateFormat(String strDate) { | |||||
return isDateFormat(strDate, "YYYY-MM-DD"); | |||||
} | |||||
/** | |||||
* 判断strDate 是否是日期格式的字符串。 | |||||
* | |||||
* @param strDate 字符串,判断其是否为日期格式。 | |||||
* @param format 字符串,YYYY-MM,YYYYMM,YYYYMMDD,YYYY-MM-DD,YYYY-MM-DD:HH, 空表示所有上述格式,非上述内容将默认为YYYY-MM-DD; | |||||
* @return boolean 如果为日期格式则返回=true; | |||||
*/ | |||||
public static boolean isDateFormat(String strDate, String format) { | |||||
if (PubUtil.isEmpty(strDate)) { | |||||
return false; | |||||
} | |||||
if (PubUtil.isEmpty(format)) { | |||||
format = "YYYY-MM-DD"; | |||||
} | |||||
switch (format) { | |||||
case "YYYY-MM": | |||||
return strDate.matches("\\d{4}-\\d{2}") && isDateValue(strDate.substring(0, 4), strDate.substring(5), "01"); | |||||
case "YYYYMM": | |||||
return strDate.matches("\\d{6}") && isDateValue(strDate.substring(0, 4), strDate.substring(4), "01"); | |||||
case "YYYYMMDD": | |||||
return strDate.matches("\\d{8}") && isDateValue(strDate.substring(0, 4), strDate.substring(4, 6), strDate.substring(6)); | |||||
case "YYYY-MM-DD": | |||||
return strDate.matches("\\d{4}-\\d{2}-\\d{2}") && isDateValue(strDate.substring(0, 4), strDate.substring(5, 7), strDate.substring(8)); | |||||
case "YYYY-MM-DD:HH": | |||||
return strDate.matches("\\d{4}-\\d{2}-\\d{2}:[0-5][0-9]") && isDateValue(strDate.substring(0, 4), strDate.substring(5, 7), strDate.substring(8, 10)); | |||||
case "HHmmss": | |||||
return strDate.matches("[0-5][0-9][0-5][0-9][0-5][0-9]") && isTimeValue(strDate.substring(0, 2), strDate.substring(2, 4), strDate.substring(4)); | |||||
default: | |||||
return false; | |||||
} | |||||
} | |||||
public static boolean isDateValue(String year, String month, String day) { | |||||
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd"); | |||||
s.setLenient(false);//这个的功能是不把1996-13-3 转换为1997-1-3 | |||||
try { | |||||
s.parse(year + "-" + month + "-" + day); | |||||
return true; | |||||
} catch (ParseException e) { | |||||
return false; | |||||
} | |||||
} | |||||
public static boolean isTimeValue(String hour, String min, String sec) { | |||||
SimpleDateFormat s = new SimpleDateFormat("HH:mm:ss"); | |||||
s.setLenient(false); | |||||
try { | |||||
s.parse(hour + ":" + min + ":" + sec); | |||||
return true; | |||||
} catch (ParseException e) { | |||||
return false; | |||||
} | |||||
} | |||||
/** | |||||
* 将日期变为"yyyyMMdd" | |||||
* | |||||
* @param date 日期 | |||||
* @return 字符串,如果传入参数为null,则返回当前日期; | |||||
*/ | |||||
public static String toDateString(Date date) { | |||||
if (date == null) date = new java.sql.Date(System.currentTimeMillis()); | |||||
return simpleDateFormat.get().format(date); | |||||
} | |||||
/** | |||||
* 得到如下字符串 "HHmmss" | |||||
* | |||||
* @param date 时间戳 如果传入为NULL,则返回当前日期; | |||||
* @return 时间串 | |||||
*/ | |||||
public static String toTimeString(Date date) { | |||||
if (date == null) new java.sql.Date(System.currentTimeMillis()); | |||||
synchronized (simpleTimeFormat) { | |||||
return simpleTimeFormat.get().format(date); | |||||
} | |||||
} | |||||
/** | |||||
* 得到长日期时间字符[yyyyMMddHHmmss] | |||||
* | |||||
* @param date 时间戳,如果传入为null,则返回当前日期 | |||||
* @return 日期时间串 | |||||
*/ | |||||
public static String toDateTimeString(Date date) { | |||||
if (date == null) date = new java.sql.Date(System.currentTimeMillis()); | |||||
return simpleDatetimeFormat.get().format(date); | |||||
} | |||||
public static java.sql.Date toDate(Timestamp datetime) { | |||||
if (datetime == null) return null; | |||||
return new java.sql.Date(datetime.getTime()); | |||||
} | |||||
/** | |||||
* 将字符串转换成Java.sql.Date,不能转换,这返回null | |||||
* | |||||
* @param src 源串 | |||||
* @return java.sql.Date | |||||
*/ | |||||
public static java.sql.Date toDate(String src) { | |||||
try { | |||||
if (PubUtil.isEmpty(src)) return null; | |||||
return java.sql.Date.valueOf(src); | |||||
} catch (Exception e) { | |||||
return null; | |||||
} | |||||
} | |||||
/** | |||||
* 得到长日期时间字符[yyyyMMddHHmmss] | |||||
* | |||||
* @param date yyyy-mm-dd hh:mm:ss格式 | |||||
* @return | |||||
*/ | |||||
public static String toDateTimeString(String date) { | |||||
return toDateTimeString(toDate(date)); | |||||
} | |||||
public static String toDateTimeString(Timestamp date) { | |||||
return toDateTimeString(toDate(date)); | |||||
} | |||||
/** | |||||
* 得到长日期时间字符[yyyyMMddHHmmss] | |||||
* | |||||
* @param date yyyy-mm-dd hh:mm:ss格式 | |||||
* @return | |||||
*/ | |||||
public static long toDateTimeLong(String date) { | |||||
return Long.parseLong(toDateTimeString(date)); | |||||
} | |||||
public static long toDateTimeLong(Timestamp date) { | |||||
return Long.parseLong(toDateTimeString(date)); | |||||
} | |||||
/** | |||||
* 得到长日期时间字符[yyyyMMddHHmmssS] | |||||
* | |||||
* @param date 时间戳,如果传入为null,则返回当前日期 | |||||
* @return 日期时间串,长 | |||||
*/ | |||||
public static String toLongDateTimeString(Date date) { | |||||
if (date == null) date = new java.sql.Date(System.currentTimeMillis()); | |||||
synchronized (simpleLongDatetimeFormat) { | |||||
return simpleLongDatetimeFormat.get().format(date); | |||||
} | |||||
} | |||||
// /** | |||||
// * 将字符串转换成Java.sql.Date,不能转换,这返回null | |||||
// * | |||||
// * @param src 源串 | |||||
// * @return java.sql.Date | |||||
// */ | |||||
// public static java.sql.Date toDate(String src) { | |||||
// try { | |||||
// if (PubUtil.isEmpty(src)) return null; | |||||
// return java.sql.Date.valueOf(src); | |||||
// } catch (Exception e) { | |||||
// return null; | |||||
// } | |||||
// } | |||||
/** | |||||
* 用中方格式化年月日 | |||||
* | |||||
* @param yearMonth YYYYMM | |||||
*/ | |||||
public static String fmtCNYearMonth(String yearMonth) { | |||||
if (PubUtil.getIntIgnoreErr(yearMonth) > 190000) | |||||
return String.format("%s年%s月", yearMonth.substring(0, 4), yearMonth.substring(4)); | |||||
return ""; | |||||
} | |||||
/** | |||||
* 用中方格式化年月日 | |||||
* | |||||
* @param yearMonth YYYYMMDD | |||||
*/ | |||||
public static String fmtCNYearMonthDay(String yearMonth) { | |||||
if (PubUtil.isEmptyId(yearMonth) || yearMonth.length() != 8) return yearMonth; | |||||
return String.format("%s年%s月%s日", yearMonth.substring(0, 4), yearMonth.substring(4, 6), yearMonth.substring(6)); | |||||
} | |||||
/** | |||||
* 用中方格式化年月日 | |||||
* | |||||
* @param stdYearMonthDay YYYY-MM-DD | |||||
*/ | |||||
public static String fmtZHCNYearMonthDay(String stdYearMonthDay) { | |||||
return String.format("%s年%s月%s日", stdYearMonthDay.substring(0, 4), stdYearMonthDay.substring(5, 7), stdYearMonthDay.substring(8)); | |||||
} | |||||
public synchronized static Date getSeasonBegin(Calendar now) { | |||||
int curYear = now.get(Calendar.YEAR); | |||||
int curMonth = now.get(Calendar.MONTH); | |||||
int seasonMonth = m_seasonBeginTable[curMonth]; | |||||
Calendar calendar = Calendar.getInstance(); | |||||
calendar.set(Calendar.YEAR, curYear); | |||||
calendar.set(Calendar.MONTH, seasonMonth); | |||||
calendar.set(Calendar.DAY_OF_MONTH, 1); | |||||
calendar.set(Calendar.HOUR_OF_DAY, 0); | |||||
calendar.set(Calendar.MINUTE, 0); | |||||
calendar.set(Calendar.SECOND, 0); | |||||
calendar.set(Calendar.MILLISECOND, 0); | |||||
calendar.set(Calendar.AM_PM, Calendar.AM); | |||||
return new Timestamp(calendar.getTime().getTime()); | |||||
} | |||||
//季度开始 | |||||
public synchronized static Date getSeasonBegin() { | |||||
Calendar calendar = Calendar.getInstance(); | |||||
calendar.setTime(new Date()); | |||||
return getSeasonBegin(calendar); | |||||
} | |||||
/** | |||||
* 得到本季度的第一天 | |||||
* | |||||
* @return | |||||
*/ | |||||
public static String getSeasonFirstDay() { | |||||
return toStdDateString(getSeasonBegin()); | |||||
} | |||||
public static String getYearFirstDay() { | |||||
return nowYear() + "-01-01"; | |||||
} | |||||
public static String getYearLastDay() { | |||||
return nowYear() + "-12-31"; | |||||
} | |||||
/** | |||||
* 取得当月最后一天YYYY-MM-DD | |||||
* | |||||
* @return 当前月最后一天的日期串; | |||||
*/ | |||||
public static String getMonthEnd() { | |||||
return getAfterDays(getAfterMonth(getMonthStart(), 1), -1); | |||||
} | |||||
/** | |||||
* 取得指定日期所在月最后一天YYYY-MM-DD | |||||
* | |||||
* @return 所在前月最后一天的日期串; | |||||
*/ | |||||
public static String getMonthEnd(Date d) { | |||||
return getAfterDays(getAfterMonth(getMonthStart(d), 1), -1); | |||||
} | |||||
/** | |||||
* 返回当前标准年月 | |||||
* | |||||
* @return YYYY-MM | |||||
*/ | |||||
public static String nowStdYearMonth() { | |||||
return nowStdDateString().substring(0, 7); | |||||
} | |||||
/** | |||||
* 取得当月第一天日期串YYYY-MM-DD | |||||
* | |||||
* @return 月第一天的标准日期串 | |||||
*/ | |||||
public static String getMonthStart() { | |||||
return nowStdYearMonth() + "-01"; | |||||
} | |||||
/** | |||||
* 取得指定日期所在月第一天日期串YYYY-MM-DD | |||||
* | |||||
* @return 月第一天的标准日期串 | |||||
*/ | |||||
public static String getMonthStart(Date d) { | |||||
if (d == null) return ""; | |||||
return toStdDateString(d).substring(0, 7) + "-01"; | |||||
} | |||||
/** | |||||
* 取得当月最后一天 | |||||
* | |||||
* @return String | |||||
*/ | |||||
public static String getMonthLastDay() { | |||||
return getAfterDays(getAfterMonth(getMonthFirstDay(), 1), -1); | |||||
} | |||||
/** | |||||
* 得到当前日期所在周次的星期一 | |||||
* | |||||
* @return 返回的时间戳 | |||||
*/ | |||||
public static Timestamp getWeekStart() { | |||||
return getWeekStart(new Timestamp(System.currentTimeMillis())); | |||||
} | |||||
/** | |||||
* 得到日期所在周次的星期一 | |||||
* | |||||
* @param stamp 参数时间戳,如果传入为null,则返回为null | |||||
* @return 返回时间戳 | |||||
*/ | |||||
public synchronized static Timestamp getWeekStart(Timestamp stamp) { | |||||
if (stamp == null) return null; | |||||
GregorianCalendar tempCal = new GregorianCalendar(mTimeZone); | |||||
tempCal.setTime(stamp); | |||||
tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); | |||||
if (tempCal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { | |||||
// AKzz fix bug: | |||||
// 如果今天是星期天, 天数再减1,找到上周(外国人的星期天是本周). | |||||
tempCal.add(Calendar.DATE, -1); // 再将天数减一 | |||||
} | |||||
tempCal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 设为星期一. | |||||
Timestamp retStamp = new Timestamp(tempCal.getTime().getTime()); | |||||
retStamp.setNanos(0); | |||||
return retStamp; | |||||
} | |||||
/** | |||||
* 当前日期的下周星期一 | |||||
*/ | |||||
public static Timestamp getNextWeekStart() { | |||||
return getNextWeekStart(new Timestamp(System.currentTimeMillis())); | |||||
} | |||||
/** | |||||
* 当前日期的下周星期一,如果传入null,则返回为null | |||||
* | |||||
* @param t 要计算的时间戳 | |||||
* @return 返回的时间戳 | |||||
*/ | |||||
public synchronized static Timestamp getNextWeekStart(Timestamp t) { | |||||
if (t == null) return null; | |||||
Calendar tempCal = new GregorianCalendar(mTimeZone); | |||||
tempCal.setTime(t); | |||||
tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DAY_OF_MONTH), | |||||
// 没有时,分,秒 | |||||
0, 0, 0); | |||||
tempCal.add(Calendar.WEEK_OF_MONTH, 1); // 周数加1 | |||||
tempCal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 设为星期一. | |||||
Timestamp retStamp = new Timestamp(tempCal.getTime().getTime()); | |||||
retStamp.setNanos(0); | |||||
return retStamp; | |||||
} | |||||
//获取年月,YYYYMM格式 | |||||
public static String getDateYm(Date dt) { | |||||
String s = simpleDateFormat.get().format(dt); | |||||
return s.substring(0, 6); | |||||
} | |||||
//获取年月,YYYY-MM-DD格式 | |||||
public static String getDateYm(String dt) { | |||||
if (dt == null || dt.length() < 6) return null; | |||||
if (dt.contains("-")) { | |||||
return dt.substring(0, 4) + dt.substring(5, 7); | |||||
} | |||||
return dt.substring(0, 6); | |||||
} | |||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
System.out.println(getTimesmorning()); | System.out.println(getTimesmorning()); | ||||
} | } | ||||
@@ -0,0 +1,779 @@ | |||||
package cc.smtweb.framework.core.util; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang3.ArrayUtils; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.UnsupportedEncodingException; | |||||
import java.sql.Date; | |||||
import java.sql.Timestamp; | |||||
import java.text.Collator; | |||||
import java.text.DecimalFormat; | |||||
import java.text.SimpleDateFormat; | |||||
import java.util.*; | |||||
import java.util.function.Function; | |||||
import java.util.regex.Matcher; | |||||
import java.util.regex.Pattern; | |||||
/** | |||||
* Created with IntelliJ IDEA. | |||||
* User: AKhh | |||||
* Date: 12-12-26 下午11:55 | |||||
* 基础工具类; | |||||
*/ | |||||
@SuppressWarnings("UnusedDeclaration") | |||||
@Slf4j | |||||
public class PubUtil { | |||||
private static SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||||
private static SimpleDateFormat tFormat = new SimpleDateFormat("HH:mm:ss"); | |||||
private static SimpleDateFormat dtFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
private static SimpleDateFormat dLFormat = new SimpleDateFormat("yyyyMMddHHmmss"); | |||||
private static SimpleDateFormat dLFormat2 = new SimpleDateFormat("yyyyMMdd"); | |||||
private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00"); | |||||
private static DecimalFormat df2 = new DecimalFormat("##############0.00"); | |||||
private static DecimalFormat df = new DecimalFormat("#.##"); | |||||
public static boolean isEmpty(String str) { | |||||
return str == null || str.trim().length() == 0; | |||||
} | |||||
//判断 是否支持GBK | |||||
public static boolean supportGBK(String str){ | |||||
if(str == null){ | |||||
return true; | |||||
} | |||||
try { | |||||
return str.equals ( new String (str.getBytes ("gbk"),"gbk") ); | |||||
}catch (Exception e){ | |||||
log.error ( "判断【"+str+"】是否支持GBK时出现异常:"+e.getMessage () ); | |||||
e.printStackTrace (); | |||||
return false; | |||||
} | |||||
} | |||||
public static boolean isEmpty(Collection collection) { | |||||
return collection == null || collection.size() == 0; | |||||
} | |||||
public static boolean isEmpty(Object[] o) { | |||||
return o == null || o.length == 0; | |||||
} | |||||
public static boolean isEmptyStr(String str) { | |||||
return str == null || str.trim().length() == 0 || "-".equals(str) || "-1".equals(str); | |||||
} | |||||
//判断Id是否为空id,有可能是"-","-1" | |||||
public static boolean isEmptyId(String id) { | |||||
return id == null || id.trim().length() == 0 || "-".equals(id) || "-1".equals(id) || "null".equals(id) || "(无)".equals(id); | |||||
} | |||||
public static boolean isNotEmpty(String str) { | |||||
return !isEmpty(str); | |||||
} | |||||
public static boolean isNotEmptyId(String str) { | |||||
return !isEmptyId(str); | |||||
} | |||||
public static boolean isNotEmptyStr(String str) { | |||||
return !isEmptyStr(str); | |||||
} | |||||
public static boolean isNotEmpty(Collection collection) { | |||||
return !isEmpty(collection); | |||||
} | |||||
public static boolean isNotEmpty(Object[] o) { | |||||
return !isEmpty(o); | |||||
} | |||||
/** | |||||
* 获取浮点数(有错误默认为0),可以识别金额中的逗号格式 | |||||
* | |||||
* @param str 带转换的字符串 | |||||
* @return 浮点数 | |||||
*/ | |||||
public static double getDoubleIgnoreErr(String str) { | |||||
if (str == null) | |||||
return 0.0; | |||||
str = str.trim(); | |||||
if (str.equals("")) | |||||
return 0.0; | |||||
str = str.replaceAll(",", "").replaceAll(",", ""); | |||||
try { | |||||
return Double.valueOf(str); | |||||
} catch (Exception e) { | |||||
return 0.0; | |||||
} | |||||
} | |||||
/** | |||||
* 得到int 获取转换的int值,有错返回0 | |||||
* | |||||
* @param str 带转换的字符串 | |||||
* @return int | |||||
*/ | |||||
public static int getIntIgnoreErr(String str) { | |||||
return getIntIgnoreErr(str, 0); | |||||
} | |||||
public static int getIntIgnoreErr(String str, int defValue) { | |||||
if (str == null) | |||||
return defValue; | |||||
str = str.trim(); | |||||
if (str.equals("")) | |||||
return defValue; | |||||
str = str.replaceAll(",", "").replaceAll(",", ""); | |||||
if (str.contains(".")) | |||||
str = str.substring(0, str.indexOf('.')); | |||||
try { | |||||
return Integer.valueOf(str); | |||||
} catch (Exception e) { | |||||
return defValue; | |||||
} | |||||
} | |||||
/** | |||||
* 得到Long 获取转换的Long值,有错返回0 | |||||
* | |||||
* @param str 带转换的字符串 | |||||
* @return long | |||||
*/ | |||||
public static long getLongIgnoreErr(String str) { | |||||
return getLongIgnoreErr(str, 0L); | |||||
} | |||||
public static long getLongIgnoreErr(String str, long defValue) { | |||||
if (str == null) | |||||
return defValue; | |||||
str = str.trim(); | |||||
if (str.equals("")) | |||||
return defValue; | |||||
str = str.replaceAll(",", "").replaceAll(",", ""); | |||||
try { | |||||
return Long.valueOf(str); | |||||
} catch (Exception e) { | |||||
return defValue; | |||||
} | |||||
} | |||||
public static String getDateStrIgnoreNull(Timestamp obj) { | |||||
if (obj == null) | |||||
return ""; | |||||
return dFormat.format(obj); | |||||
} | |||||
public static String getTimeStrIgnoreNull(Timestamp obj) { | |||||
if (obj == null) | |||||
return ""; | |||||
return tFormat.format(obj); | |||||
} | |||||
public static Date getCurDate() { | |||||
return new Date(System.currentTimeMillis()); | |||||
} | |||||
public static String getCurDateStr() { | |||||
return dFormat.format(new Date(System.currentTimeMillis())); | |||||
} | |||||
public static Timestamp getCurDatetime() { | |||||
return new Timestamp(System.currentTimeMillis()); | |||||
} | |||||
public static String getCurDatetimeStr() { | |||||
return dtFormat.format(new Timestamp(System.currentTimeMillis())); | |||||
} | |||||
public static String getCurDatetimeShortStr() { | |||||
return dLFormat.format(new Timestamp(System.currentTimeMillis())); | |||||
} | |||||
/** | |||||
* Func:为空,返回"" | |||||
* | |||||
* @param str 带检查的字符串 | |||||
* @return "" | |||||
*/ | |||||
public static String checkNull(String str) { | |||||
if (isEmpty(str)) | |||||
return ""; | |||||
return str.trim(); | |||||
} | |||||
/** | |||||
* 功能:null过滤,返回默认值 | |||||
* | |||||
* @param strValue 带检查的字符串 | |||||
* @param defaultValue 为空返回的字符串 | |||||
* @return str | |||||
*/ | |||||
public static String checkNull(String strValue, String defaultValue) { | |||||
return strValue == null ? defaultValue : strValue; | |||||
} | |||||
public static String checkNull(Integer n) { | |||||
return checkNull(n, true); | |||||
} | |||||
public static String checkNull(Integer n, boolean zeroToEmpty) { | |||||
int v; | |||||
if (n == null || n == 0) | |||||
v = 0; | |||||
else | |||||
v = n; | |||||
return v != 0 ? String.valueOf(v) : zeroToEmpty ? "" : "0"; | |||||
} | |||||
public static String checkNull(Long n) { | |||||
return checkNull(n, 0L); | |||||
} | |||||
public static String checkNull(Long n, long defValue) { | |||||
return n != null ? String.valueOf(n) : String.valueOf(defValue); | |||||
} | |||||
public static String checkNull(Double n) { | |||||
return checkNull(n, 0d); | |||||
} | |||||
public static String checkNull(Double n, boolean zeroToEmpty) { | |||||
double v; | |||||
if (n == null || n == 0) | |||||
v = 0; | |||||
else | |||||
v = n; | |||||
return v != 0 ? String.valueOf(v) : zeroToEmpty ? "" : "0"; | |||||
} | |||||
public static String checkNull(Double n, double defValue) { | |||||
double d = n != null ? n : defValue; | |||||
return getDoubleStr(d); | |||||
} | |||||
//字符串清洗 | |||||
public static String clearStr(String str) { | |||||
if (str == null) return ""; | |||||
else | |||||
str = str.replaceAll("\u3000", "").replaceAll("\n", "").replaceAll("\b", "").replaceAll("\r", "").replaceAll("\t", "").replaceAll("\\s", "").replaceAll(" ", "").trim(); | |||||
return str; | |||||
} | |||||
/** | |||||
* Func:取当前年 | |||||
* | |||||
* @return "" | |||||
*/ | |||||
public static String getThisYear() { | |||||
Calendar tlpDate = new GregorianCalendar(); | |||||
tlpDate.setTime(getCurDate()); | |||||
return String.valueOf(tlpDate.get(Calendar.YEAR)); | |||||
} | |||||
/** | |||||
* Func:取当前月 | |||||
* | |||||
* @return "" | |||||
*/ | |||||
public static String getThisMonth() { | |||||
Calendar tlpDate = new GregorianCalendar(); | |||||
tlpDate.setTime(getCurDate()); | |||||
return String.valueOf(tlpDate.get(Calendar.MONTH)); | |||||
} | |||||
/** | |||||
* 功能:空值过滤,返回默认值 | |||||
* | |||||
* @param strValue 待检查的字符串 | |||||
* @param defaultValue 为空返回的字符串 | |||||
* @return str | |||||
*/ | |||||
public static String checkEmpty(String strValue, String defaultValue) { | |||||
return isEmpty(strValue) ? defaultValue : strValue; | |||||
} | |||||
/** | |||||
* 功能:空值过滤,返回默认值 | |||||
* | |||||
* @param strValue 待检查的字符串 | |||||
* @return str | |||||
*/ | |||||
public static String checkEmptyId(String strValue, String defaultValue) { | |||||
return isEmptyId(strValue) ? defaultValue : strValue; | |||||
} | |||||
public static String checkEmptyId(String strValue) { | |||||
return isEmptyId(strValue) ? "" : strValue; | |||||
} | |||||
public static String getOrigMsg(Throwable e) { | |||||
String s = e.getMessage(); | |||||
Throwable t = e.getCause(); | |||||
while (t != null) { | |||||
s = t.getMessage(); | |||||
t = t.getCause(); | |||||
} | |||||
return s; | |||||
} | |||||
//计算一个字符串source的长度(英文和数字占一个长度,其他字符(中文和特殊符号等)占2个长度) | |||||
public static int strLength(String source) { | |||||
int totalLength = source.length();// 总长度 | |||||
String otherStr = source.replaceAll("\\d|\\w", "");// 去掉字符串中的数字和英文字符 | |||||
int otherLength = otherStr.length();// 占2个长度的字符 | |||||
return (totalLength - otherLength) + otherLength * 2; | |||||
} | |||||
/** | |||||
* 格式化最后修改时间 | |||||
* | |||||
* @param strTime YYYYMMDDhhmmss | |||||
* @return YYYY-MM-DD hh:mm:ss | |||||
*/ | |||||
public static String checkLastTime(String strTime) { | |||||
if (isEmpty(strTime)) | |||||
return ""; | |||||
return checkLastTime(getLongIgnoreErr(strTime)); | |||||
} | |||||
public static String checkLastTime(long lngTime) { | |||||
if (0 >= lngTime) | |||||
return ""; | |||||
String s1 = String.valueOf(lngTime + "").trim(); | |||||
if (s1.length() != 14) | |||||
return ""; | |||||
return s1.substring(0, 4).concat("-").concat(s1.substring(4, 6)).concat("-").concat(s1.substring(6, 8)).concat(" ").concat(s1.substring(8, 10)).concat(":").concat(s1.substring(10, 12)).concat(":").concat(s1.substring(12)); | |||||
} | |||||
/** | |||||
* 格式化最后修改时间 | |||||
* | |||||
* @param strTime YYYYMMDDhhmmss | |||||
* @return YYYY-MM-DD hh:mm:ss | |||||
*/ | |||||
public static String getTimeFormatValue(String strTime) { | |||||
if (isEmpty(strTime)) | |||||
return ""; | |||||
return getTimeFormatValue(getTimeDbValue(strTime)); | |||||
} | |||||
/** | |||||
* 日期格式化 YYYYMMDDHHMMSS 转 YYYY-MM-DD- HH:MM:SS | |||||
* | |||||
* @param lngTime | |||||
* @return | |||||
*/ | |||||
public static String getTimeFormatValue(long lngTime) { | |||||
if (lngTime <= 0L) return ""; | |||||
String s1 = String.valueOf(lngTime + "").trim(); | |||||
if (s1.length() == 8) {//日期 | |||||
return s1.substring(0, 4).concat("-").concat(s1.substring(4, 6)).concat("-").concat(s1.substring(6, 8)); | |||||
} | |||||
if (s1.length() == 6) {//时间 | |||||
return s1.substring(0, 2).concat(":").concat(s1.substring(2, 4)).concat(":").concat(s1.substring(4, 6)); | |||||
} | |||||
if (s1.length() == 14) {//日期 | |||||
return s1.substring(0, 4).concat("-").concat(s1.substring(4, 6)).concat("-").concat(s1.substring(6, 8)).concat(" ").concat(s1.substring(8, 10)).concat(":").concat(s1.substring(10, 12)).concat(":").concat(s1.substring(12)); | |||||
} | |||||
return ""; | |||||
} | |||||
/** | |||||
* 日期格式化 YYYY-MM-DD- HH:MM:SS 转 YYYYMMDDHHMMSS | |||||
* | |||||
* @param strTime | |||||
* @return | |||||
*/ | |||||
public static long getTimeDbValue(String strTime) { | |||||
if (isEmptyId(strTime)) return -1L; | |||||
return getLongIgnoreErr(strTime.replaceAll("-", "").replaceAll(":", "").replaceAll(" ", "")); | |||||
} | |||||
/** | |||||
* 取最后修改时间 | |||||
* | |||||
* @return Long | |||||
*/ | |||||
public static Long getLastTime() { | |||||
return DateUtil.nowDateTimeNumber(); | |||||
} | |||||
/** | |||||
* 取最后修改日期 | |||||
* | |||||
* @return | |||||
*/ | |||||
public static Long getLastDate() { | |||||
return Long.valueOf(dLFormat2.format(new Timestamp(System.currentTimeMillis()))); | |||||
} | |||||
public static String getAmountStr(double amount) { | |||||
return df2Format.format(amount); | |||||
} | |||||
public static String getAmountStrEx(double amount) { | |||||
return df.format(amount); | |||||
} | |||||
public static String getSingleAmountStr(double amount) { | |||||
return df2.format(amount); | |||||
} | |||||
public static String getIntStr(int d) { | |||||
if (d == 0) | |||||
return ""; | |||||
else | |||||
return String.valueOf(d); | |||||
} | |||||
/** | |||||
* 截取右边的0串 | |||||
* | |||||
* @param codeStr | |||||
* @return | |||||
*/ | |||||
public static String cutZero(String codeStr) { | |||||
int j = 0; | |||||
int len = codeStr.length() - 1; | |||||
for (int i = len; i > -1; i--) { | |||||
if ('0' == codeStr.charAt(i)) { | |||||
j++; | |||||
} else { | |||||
break; | |||||
} | |||||
} | |||||
return codeStr.substring(0, len - j + 1); | |||||
} | |||||
/** | |||||
* 右边补0串 | |||||
* | |||||
* @param codeLen | |||||
* @param cutedCode | |||||
* @return | |||||
*/ | |||||
public static String fillZero(int codeLen, String cutedCode) { | |||||
StringBuilder codeStr = new StringBuilder(20).append(cutedCode); | |||||
for (int len = cutedCode.length(), i = 0; i < codeLen - len; i++) { | |||||
codeStr.append("0"); | |||||
} | |||||
return codeStr.toString(); | |||||
} | |||||
/** | |||||
* 转换为boolean | |||||
*/ | |||||
public static boolean toBoolean(String v, boolean b) { | |||||
if (v == null) return b; | |||||
return "1".equals(v) || "true".equalsIgnoreCase(v) || "Y".equalsIgnoreCase(v) || "yes".equalsIgnoreCase(v); | |||||
} | |||||
public static String getDateStr(Object _dateTime) { //yyyymmddhhMMss | |||||
if (_dateTime == null) return ""; | |||||
String dateTime = String.valueOf(_dateTime); | |||||
if (PubUtil.isEmpty(dateTime) || dateTime.length() < 8) { | |||||
return ""; | |||||
} else { | |||||
String s1 = String.valueOf(dateTime); | |||||
return s1.substring(0, 4) + "-" + s1.substring(4, 6) + "-" + s1.substring(6, 8); | |||||
} | |||||
} | |||||
/** | |||||
* 日期转long | |||||
* | |||||
* @param dateStr YYYY-MM-DD | |||||
* @return YYYYmmDD | |||||
*/ | |||||
public static long getDateLong(String dateStr) { | |||||
if (PubUtil.isEmpty(dateStr) || dateStr.length() != 10) { | |||||
return -1L; | |||||
} | |||||
String _dateTime = dateStr.replaceAll("-", ""); | |||||
return getLongIgnoreErr(_dateTime); | |||||
} | |||||
/** | |||||
* 转日期时间long | |||||
* | |||||
* @param dateStr | |||||
* @return | |||||
*/ | |||||
public static long getDateTimeLong(String dateStr) { | |||||
if (PubUtil.isEmpty(dateStr)) { | |||||
return -1L; | |||||
} | |||||
String _dateTime = dateStr.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""); | |||||
_dateTime = StringUtil.getLeft(_dateTime + "00000000000000", 14); | |||||
return getLongIgnoreErr(_dateTime); | |||||
} | |||||
/** | |||||
* 转日期时间long | |||||
* | |||||
* @param dateStr | |||||
* @return | |||||
*/ | |||||
public static long getEndDateTimeLong(String dateStr) { | |||||
if (PubUtil.isEmpty(dateStr)) { | |||||
return -1L; | |||||
} | |||||
String _dateTime = dateStr.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""); | |||||
_dateTime = StringUtil.getLeft(_dateTime + "00000000", 8) + "235959"; | |||||
return getLongIgnoreErr(_dateTime); | |||||
} | |||||
public static String getDateTimeStr(Object _dateTime) { //yyyymmddhhMMss | |||||
String dateTime = String.valueOf(_dateTime); | |||||
if (PubUtil.isEmpty(dateTime) || dateTime.length() < 14) { | |||||
return ""; | |||||
} else { | |||||
String s1 = String.valueOf(dateTime); | |||||
return s1.substring(0, 4) + "-" + s1.substring(4, 6) + "-" + s1.substring(6, 8);// + " " + s1.substr(8, 10) + ":" + s1.substr(10, 12) + ":" + s1.substr(12); | |||||
} | |||||
} | |||||
//删除除 {"0","1","2","3","4","5","6","7","8","9",".","/","-"}以外的字符 | |||||
public static String remove(String str) { | |||||
if (isEmpty(str)) return ""; | |||||
char[] charArray = str.toCharArray(); | |||||
char[] strArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '/', '-'}; | |||||
for (char c : charArray) { | |||||
if (!ArrayUtils.contains(strArray, c)) { | |||||
str = StringUtils.remove(str, c); | |||||
} | |||||
} | |||||
return str; | |||||
} | |||||
//数字转字符串,如无小数,则去掉.00 | |||||
public static String getDoubleStr(double d) { | |||||
return getAmountStr(d).replaceAll(",", "").replaceAll("\\.00", ""); | |||||
} | |||||
//将List转为sql语句in后面的常量,'XXX','XXX'格式 | |||||
public static String getSqlInstr(List<String> list) { | |||||
if (PubUtil.isEmpty(list)) return ""; | |||||
StringBuilder sb = new StringBuilder(256); | |||||
for (String s : list) { | |||||
if (PubUtil.isEmptyId(s)) continue; | |||||
sb.append(",'").append(s).append("'"); | |||||
} | |||||
if (sb.length() == 0) return ""; | |||||
return sb.substring(1); | |||||
} | |||||
/** | |||||
* 将数组ID转为sql语句in后面的常量 | |||||
* | |||||
* @param ids ID数组 | |||||
* @return 返回格式:110,1002 | |||||
*/ | |||||
public static String getSqlInIds(String[] ids) { | |||||
if (null == ids || ids.length < 1) return ""; | |||||
StringBuilder s = new StringBuilder(128); | |||||
for (String id : ids) { | |||||
if (PubUtil.isEmptyId(id)) continue; | |||||
s.append(id.trim()).append(","); | |||||
} | |||||
if (s.length() == 0) return ""; | |||||
return s.substring(0, s.length() - 1); | |||||
} | |||||
public static String getSqlInIds(Collection<String> ids) { | |||||
if (null == ids || ids.size() < 1) return ""; | |||||
StringBuilder s = new StringBuilder(128); | |||||
for (String id : ids) { | |||||
if (PubUtil.isEmptyId(id)) continue; | |||||
s.append(id).append(","); | |||||
} | |||||
if (s.length() == 0) return ""; | |||||
return s.substring(0, s.length() - 1); | |||||
} | |||||
public static String getSqlInStrIds(Collection<String> ids) { | |||||
if (null == ids || ids.size() < 1) return ""; | |||||
StringBuilder s = new StringBuilder(128); | |||||
for (String id : ids) { | |||||
if (PubUtil.isEmptyId(id)) continue; | |||||
s.append("'" + id + "'").append(","); | |||||
} | |||||
if (s.length() == 0) return ""; | |||||
return s.substring(0, s.length() - 1); | |||||
} | |||||
public static List<String> buildSqlIds(Collection<String> ids, int size) { | |||||
List<String> l = new ArrayList<>(); | |||||
StringBuilder sb = new StringBuilder(); | |||||
int count = 0; | |||||
for (String id : ids) { | |||||
if (count >= size) { | |||||
l.add(sb.substring(1)); | |||||
sb.setLength(0); | |||||
count = 0; | |||||
} | |||||
sb.append(",").append(id); | |||||
count++; | |||||
} | |||||
if (sb.length() > 0) l.add(sb.substring(1)); | |||||
return l; | |||||
} | |||||
/** | |||||
* 判断字符串是否只包含unicode数字。 | |||||
* <p/> | |||||
* <p> | |||||
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 | |||||
* <code>true</code>。 | |||||
* </p> | |||||
* <p/> | |||||
* <p> | |||||
* <pre> | |||||
* StringUtil.isNumeric(null) = false | |||||
* StringUtil.isNumeric("") = true | |||||
* StringUtil.isNumeric(" ") = false | |||||
* StringUtil.isNumeric("123") = true | |||||
* StringUtil.isNumeric("12 3") = false | |||||
* StringUtil.isNumeric("ab2c") = false | |||||
* StringUtil.isNumeric("12-3") = false | |||||
* StringUtil.isNumeric("12.3") = false | |||||
* </pre> | |||||
* | |||||
* @param str 要检查的字符串 | |||||
* @return 如果字符串非<code>null</code>并且全由unicode数字组成,则返回<code>true</code> | |||||
*/ | |||||
public static boolean isNumeric(String str) { | |||||
if (PubUtil.isEmpty(str)) { | |||||
return false; | |||||
} | |||||
int length = str.length(); | |||||
for (int i = 0; i < length; i++) { | |||||
if (!Character.isDigit(str.charAt(i))) { | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
public static boolean isDouble(String str) { | |||||
if (null == str || "".equals(str)) { | |||||
return false; | |||||
} | |||||
Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$"); | |||||
return pattern.matcher(str).matches(); | |||||
} | |||||
/** | |||||
* 获得某个字符在 字符串中 出现第n次时的 下标 | |||||
* | |||||
* @param res | |||||
* @param _c | |||||
* @param index | |||||
* @return | |||||
*/ | |||||
public static int getIndexChar(String res, String _c, int index) { | |||||
Matcher mh = Pattern.compile(_c).matcher(res); | |||||
int i = 0; | |||||
while (mh.find()) { | |||||
i++; | |||||
if (i == index) { | |||||
break; | |||||
} | |||||
} | |||||
return mh.start(); | |||||
} | |||||
/** | |||||
* 将字符串转为指定字符集 | |||||
* @param str | |||||
* @param charSet | |||||
* @return | |||||
*/ | |||||
public static String changeStrCharSet(String str, String charSet) { | |||||
if (isEmptyId(str)) return str; | |||||
String newStr = str; | |||||
try { | |||||
newStr = new String(str.getBytes(charSet), charSet); | |||||
} catch (UnsupportedEncodingException e) { | |||||
return newStr; | |||||
} | |||||
return newStr; | |||||
} | |||||
/** | |||||
* 转布尔 | |||||
* | |||||
* @param o | |||||
* @return | |||||
*/ | |||||
public static boolean getBool(Object o) { | |||||
if (o == null) return false; | |||||
String v = o.toString(); | |||||
return "1".equals(v) || "t".equalsIgnoreCase(v) || "true".equalsIgnoreCase(v); | |||||
} | |||||
/** | |||||
* 返回当恰能操作系统是否为Linux | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static boolean osIsLinux() { | |||||
String s = System.getProperty("os.name"); | |||||
return s != null && s.equalsIgnoreCase("linux"); | |||||
} | |||||
public static boolean strAllEqual(String str) { | |||||
if (PubUtil.isEmptyId(str)) return true; | |||||
for (int i = 1; i < str.length(); i++) | |||||
if (str.charAt(i) != str.charAt(0)) return false; | |||||
return true; | |||||
} | |||||
/** | |||||
* 对中文字段 list排序 | |||||
* | |||||
* @param list | |||||
* @param fun 获取排序的值 | |||||
* @param desc 降序 | |||||
* @throws Exception | |||||
*/ | |||||
public static <T, R> void sortChineseStrList(List<T> list, Function<T, R> fun, boolean desc) { | |||||
list.sort((T o1, T o2) -> { | |||||
int rt = Collator.getInstance(Locale.CHINESE).compare(fun.apply(o1), fun.apply(o2)); | |||||
if (rt < 0) { | |||||
if (desc) { | |||||
return 1; | |||||
} | |||||
return -1; | |||||
} | |||||
if (rt > 0) { | |||||
if (desc) { | |||||
return -1; | |||||
} | |||||
return 1; | |||||
} | |||||
return 0; | |||||
}); | |||||
} | |||||
//遍历map | |||||
public static <K, V> void doForMap(Map<K, V> map, IMapEntryReader<K, V> reader) throws Exception { | |||||
if (map == null) return; | |||||
for (Map.Entry<K, V> entry : map.entrySet()) { | |||||
reader.readEntry(entry.getKey(), entry.getValue()); | |||||
} | |||||
} | |||||
public interface IMapEntryReader<K, V> { | |||||
void readEntry(K key, V value) throws Exception; | |||||
} | |||||
} |
@@ -0,0 +1,502 @@ | |||||
package cc.smtweb.framework.core.util; | |||||
import java.text.Collator; | |||||
import java.util.*; | |||||
/** | |||||
* Created with IntelliJ IDEA. | |||||
* User: AKhh | |||||
* Date: 12-12-24 下午5:09 | |||||
* To change this template use File | Settings | File Templates. | |||||
*/ | |||||
@SuppressWarnings("UnusedDeclaration") | |||||
public class StringUtil { | |||||
private static Collator chineseCollator = Collator.getInstance(Locale.CHINA); | |||||
/** | |||||
* strSrc中寻找第一个strSe并且返回以其分隔的Left部分,汉字长度也为1 | |||||
* | |||||
* @param strSrc 源字符串 | |||||
* @param strSe 分割字符 | |||||
* @return String 返回 | |||||
*/ | |||||
public static String getLeft(String strSrc, String strSe) { | |||||
if (PubUtil.isEmpty(strSrc)) | |||||
return ""; | |||||
if (PubUtil.isEmpty(strSe)) | |||||
strSe = " "; | |||||
String result = ""; | |||||
int pos = strSrc.indexOf(strSe); | |||||
if (pos >= 0) | |||||
result = strSrc.substring(0, pos); | |||||
return result; | |||||
} | |||||
/** | |||||
* 返回字符串的左边部分,汉字长度也为1 | |||||
* | |||||
* @param strSrc 源串,如果为空,则返回“”; | |||||
* @param count 要获取的右边字符串长度,负数将返回“”,如果count>字符串长度,则返回整个字符串; | |||||
* @return String return | |||||
*/ | |||||
public static String getLeft(String strSrc, int count) { | |||||
if (PubUtil.isEmpty(strSrc) || count <= 0) { | |||||
return ""; | |||||
} | |||||
if (strSrc.length() < count) { | |||||
return strSrc; | |||||
} else { | |||||
return strSrc.substring(0, count); | |||||
} | |||||
} | |||||
/** | |||||
* strSrc中寻找第一个strSe并且返回以其分隔的Right部分,汉字长度也为1 | |||||
* | |||||
* @param strSrc 源串 | |||||
* @param strSe 分隔符,一个字符 | |||||
* @return String right部分 | |||||
*/ | |||||
public static String getRight(String strSrc, String strSe) { | |||||
if (PubUtil.isEmpty(strSrc)) | |||||
return ""; | |||||
if (PubUtil.isEmpty(strSe)) | |||||
strSe = " "; | |||||
String result = strSrc; | |||||
int pos = strSrc.indexOf(strSe); | |||||
if (pos >= 0) | |||||
result = strSrc.substring(pos + strSe.length()); | |||||
return result; | |||||
} | |||||
/** | |||||
* 返回字符串的右边部分,汉字长度也为1 | |||||
* | |||||
* @param strSrc 源串 | |||||
* @param count 要获取的右边字符串长度,负数将返回“”,如果count>字符串长度,则返回整个字符串; | |||||
* @return String return | |||||
*/ | |||||
public static String getRight(String strSrc, int count) { | |||||
if (PubUtil.isEmpty(strSrc) || count <= 0) { | |||||
return ""; | |||||
} | |||||
int l = strSrc.length(); | |||||
if (l <= count) { | |||||
return strSrc; | |||||
} | |||||
return strSrc.substring(l - count); | |||||
} | |||||
/** | |||||
* 左边补齐字符 | |||||
* | |||||
* @param src 源串 | |||||
* @param pad 补齐字符 | |||||
* @param length 最终长度 | |||||
* @return 补齐后的字符串 | |||||
*/ | |||||
public static String padLeft(String src, String pad, int length) { | |||||
StringBuilder sb = new StringBuilder(repeatString(pad, length)); | |||||
sb.append(src); | |||||
return sb.substring(sb.length() - length); | |||||
} | |||||
public static String padLeft(long src, String pad, int length) { | |||||
StringBuilder sb = new StringBuilder(repeatString(pad, length)); | |||||
sb.append(src); | |||||
return sb.substring(sb.length() - length); | |||||
} | |||||
public static String padRight(String src, String pad, int length) { | |||||
StringBuilder sb = new StringBuilder(length * pad.length() + src.length()); | |||||
sb.append(src).append(repeatString(pad, length)); | |||||
return sb.substring(0, length); | |||||
} | |||||
public static String padRight(long src, String pad, int length) { | |||||
StringBuilder sb = new StringBuilder(length * pad.length()); | |||||
sb.append(src).append(repeatString(pad, length)); | |||||
return sb.substring(0, length); | |||||
} | |||||
/** | |||||
* 由于jdk1.3提供的replace函数不能满足替换要求,自己写一个 | |||||
* | |||||
* @param src 源串 | |||||
* @param oldS 将... | |||||
* @param newS 替换成... | |||||
* @return 替换后的字符串 | |||||
*/ | |||||
public static String replaceString(String src, String oldS, String newS) { | |||||
StringBuilder ret = new StringBuilder(64); | |||||
int pos = src.indexOf(oldS); | |||||
while (pos >= 0) { | |||||
ret.append(src.substring(0, pos)).append(newS); | |||||
src = src.substring(pos + oldS.length()); | |||||
pos = src.indexOf(oldS); | |||||
} | |||||
ret.append(src); | |||||
return ret.toString(); | |||||
} | |||||
/** | |||||
* 取得指定字符串左边的有效数字,首先去掉两边空格 | |||||
* | |||||
* @param s 源串 | |||||
* @return 串左边的有效数字 | |||||
*/ | |||||
public static String getStringLeftNumber(String s) { | |||||
String ret = ""; | |||||
int dotCount = 0; | |||||
s = s.trim(); | |||||
char[] carr = s.toCharArray(); | |||||
for (char aCarr : carr) { | |||||
if (Character.isDigit(aCarr)) { | |||||
ret += aCarr; | |||||
} else if (aCarr == '.' && dotCount == 0) { | |||||
ret += aCarr; | |||||
dotCount++; | |||||
} else { | |||||
break; | |||||
} | |||||
} | |||||
if (ret.endsWith(".")) { | |||||
ret = ret.substring(0, ret.length() - 1); | |||||
} | |||||
return ret; | |||||
} | |||||
/** | |||||
* 取得重复字串 | |||||
* | |||||
* @param repeatString 重复字串 | |||||
* @param count 重复次数 | |||||
* @return String | |||||
*/ | |||||
public static String repeatString(String repeatString, int count) { | |||||
if (count <= 0) return ""; | |||||
StringBuilder ret = new StringBuilder(repeatString.length() * count); | |||||
for (int i = 1; i <= count; i++) { | |||||
ret.append(repeatString); | |||||
} | |||||
return ret.toString(); | |||||
} | |||||
/** | |||||
* 去除字符串左边的指定字符串 | |||||
* | |||||
* @param src 源字符串 | |||||
* @param cut 要去掉的字符串; | |||||
* @return 处理结果 | |||||
*/ | |||||
public static String cutStringLeft(String src, String cut) { | |||||
if (PubUtil.isEmpty(src) || PubUtil.isEmpty(cut)) { | |||||
return ""; | |||||
} | |||||
if (src.startsWith(cut)) { | |||||
return cutStringLeft(src.substring(cut.length()), cut); | |||||
} else { | |||||
return src; | |||||
} | |||||
} | |||||
public static String cutStringRight(String src, String cut) { | |||||
if (PubUtil.isEmpty(src) || PubUtil.isEmpty(cut)) { | |||||
return ""; | |||||
} | |||||
while (src.endsWith(cut)) | |||||
src = src.substring(0, src.length() - cut.length()); | |||||
return src; | |||||
} | |||||
/** | |||||
* Removes all spaces from a string | |||||
* 可以替换大部分空白字符, 不限于空格,\s 可以匹配空格、制表符、换页符等空白字符的其中任意一个 | |||||
*/ | |||||
public static String removeSpaces(String str) { | |||||
return str.replaceAll("\\s*", ""); | |||||
} | |||||
/** | |||||
* Creates a single string from a List of strings seperated by a delimiter. | |||||
* | |||||
* @param list a list of strings to join | |||||
* @param delim the delimiter character(s) to use. (null value will join with no delimiter) | |||||
* @return a String of all values in the list seperated by the delimiter | |||||
*/ | |||||
public static String join(List<String> list, String delim) { | |||||
if (list == null || list.size() < 1) | |||||
return null; | |||||
StringBuffer buf = new StringBuffer(); | |||||
Iterator i = list.iterator(); | |||||
while (i.hasNext()) { | |||||
buf.append((String) i.next()); | |||||
if (i.hasNext()) | |||||
buf.append(delim); | |||||
} | |||||
return buf.toString(); | |||||
} | |||||
/** | |||||
* Splits a String on a delimiter into a List of Strings. | |||||
* | |||||
* @param str the String to split | |||||
* @param delim the delimiter character(s) to join on (null will split on whitespace) | |||||
* @return a list of Strings | |||||
*/ | |||||
public static List<String> split(String str, String delim) { | |||||
List<String> splitList = new ArrayList<>(); | |||||
StringTokenizer st; | |||||
if (str == null) | |||||
return splitList; | |||||
if (delim != null) | |||||
st = new StringTokenizer(str, delim); | |||||
else | |||||
st = new StringTokenizer(str); | |||||
while (st.hasMoreTokens()) { | |||||
splitList.add(st.nextToken()); | |||||
} | |||||
return splitList; | |||||
} | |||||
//是否为true,(1,y,true,yes) | |||||
public static boolean toBoolean(String v) { | |||||
return "1".equals(v) || "y".equalsIgnoreCase(v) || "true".equalsIgnoreCase(v) || "yes".equalsIgnoreCase(v); | |||||
} | |||||
public static int chineseCompare(String s1, String s2) { | |||||
return chineseCollator.compare(s1, s2); | |||||
} | |||||
/** | |||||
* 按照编码级次,得到类型的真实编码,主要用于like 'parentCode%' | |||||
* getSplitTypeCode('GF82000',2, 2, 1) == GF82 | |||||
* getSplitTypeCode('GF82100',3, 2, 1) == GF821 | |||||
* getSplitTypeCode('82100' ,3, 0, 1) == 821 | |||||
* | |||||
* @param curLevel 当前编码的所在层次 | |||||
* @param startIndex 数字编码的开始选项 | |||||
* @param perSize 每层的数字编码长度 | |||||
*/ | |||||
public static String getRealCode(String code, int curLevel, int startIndex, int perSize) { | |||||
StringBuilder sb = new StringBuilder(code.length()); | |||||
if (startIndex > 0) sb.append(code.substring(0, startIndex)); | |||||
for (int i = startIndex, l = 0; i < code.length(); i += perSize) { | |||||
if (l < curLevel) { | |||||
sb.append(code.substring(i, i + perSize)); | |||||
++l; | |||||
} else { | |||||
break; | |||||
} | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
//函数功能: 正整数 | |||||
public static boolean isPureNumber(String inputString) { | |||||
return inputString.matches("^[1-9]\\d*$"); | |||||
} | |||||
//函数功能: 整数 | |||||
public static boolean isNumber(String inputString) { | |||||
return inputString.matches("^[-+][0-9]\\d*$"); | |||||
} | |||||
//函数功能: 浮点数 | |||||
public static boolean isAmount(String inputString) { | |||||
return inputString.matches("^[-+]?[\\d,]+(\\.\\d+)?$"); | |||||
} | |||||
//函数功能: 带千分号的整数 | |||||
public static boolean isFormatNumber(String inputString) { | |||||
return inputString.matches("^[-+]?[\\d,]+(\\d+)?$"); | |||||
} | |||||
//首字母大写 | |||||
public static String upFirst(String s) { | |||||
return s.substring(0, 1).toUpperCase() + s.substring(1); | |||||
} | |||||
public static String padRightBytes(String src, String pad, int length) { | |||||
length -= src.replaceAll("[^\\x00-\\xff]", "**").length(); | |||||
return src + repeatString(pad, length); | |||||
} | |||||
//按字节数取子串,begin不是按字节的 | |||||
public static String substrByte(String src, int begin, int len) { | |||||
StringBuilder sb = new StringBuilder(32); | |||||
char c; | |||||
int tl = src.length(); | |||||
for (int i = begin; i < len + begin && i < tl; i++) { | |||||
c = src.charAt(i); | |||||
sb.append(c); | |||||
if (String.valueOf(c).replaceAll("[^\\x00-\\xff]", "**").length() > 1) { | |||||
// 遇到中文汉字,截取字节总数减1 | |||||
--len; | |||||
} | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
/** | |||||
* 通配符算法。 可以匹配"*"和"?" | |||||
* 如a*b?d可以匹配aAAAbcd | |||||
* | |||||
* @param pattern 匹配表达式 | |||||
* @param str 匹配的字符串 | |||||
* @return | |||||
*/ | |||||
public static boolean match(String pattern, String str) { | |||||
if (pattern == null || str == null) | |||||
return false; | |||||
boolean result = false; | |||||
char c; // 当前要匹配的字符串 | |||||
boolean beforeStar = false; // 是否遇到通配符* | |||||
int back_i = 0;// 回溯,当遇到通配符时,匹配不成功则回溯 | |||||
int back_j = 0; | |||||
int i, j; | |||||
for (i = 0, j = 0; i < str.length(); ) { | |||||
if (pattern.length() <= j) { | |||||
if (back_i != 0) {// 有通配符,但是匹配未成功,回溯 | |||||
beforeStar = true; | |||||
i = back_i; | |||||
j = back_j; | |||||
back_i = 0; | |||||
back_j = 0; | |||||
continue; | |||||
} | |||||
break; | |||||
} | |||||
if ((c = pattern.charAt(j)) == '*') { | |||||
if (j == pattern.length() - 1) {// 通配符已经在末尾,返回true | |||||
result = true; | |||||
break; | |||||
} | |||||
beforeStar = true; | |||||
j++; | |||||
continue; | |||||
} | |||||
if (beforeStar) { | |||||
if (str.charAt(i) == c) { | |||||
beforeStar = false; | |||||
back_i = i + 1; | |||||
back_j = j; | |||||
j++; | |||||
} | |||||
} else { | |||||
if (c != '?' && c != str.charAt(i)) { | |||||
result = false; | |||||
if (back_i != 0) {// 有通配符,但是匹配未成功,回溯 | |||||
beforeStar = true; | |||||
i = back_i; | |||||
j = back_j; | |||||
back_i = 0; | |||||
back_j = 0; | |||||
continue; | |||||
} | |||||
break; | |||||
} | |||||
j++; | |||||
} | |||||
i++; | |||||
} | |||||
if (i == str.length() && j == pattern.length())// 全部遍历完毕 | |||||
result = true; | |||||
return result; | |||||
} | |||||
//填充变量 | |||||
public static String myReplaceStrEx(String express, String b, String e, IStrHanlder hanlder) { | |||||
if (null == express) return express; | |||||
int keyBegin = 0, keyEnd = 0; | |||||
int lb = b.length(), le = e.length(); | |||||
String fn; | |||||
while (true) { | |||||
keyBegin = express.indexOf(b, keyBegin); | |||||
if (keyBegin < 0) break; | |||||
keyEnd = express.indexOf(e, keyBegin); | |||||
if (keyEnd <= keyBegin) break; | |||||
keyBegin++; | |||||
fn = express.substring(keyBegin + lb - 1, keyEnd); | |||||
fn = hanlder.work(fn); | |||||
if (fn != null) { | |||||
express = express.substring(0, keyBegin - 1) + fn + express.substring(keyEnd + le); | |||||
} | |||||
} | |||||
return express; | |||||
} | |||||
//填充变量 | |||||
public static String myReplaceStrEx(String express, String b, String e, final Map<String, String> mapVals) { | |||||
return myReplaceStrEx(express, b, e, new IStrHanlder() { | |||||
@Override | |||||
public String work(String src) { | |||||
return PubUtil.checkNull(mapVals.get(src)); | |||||
} | |||||
}); | |||||
} | |||||
/*Blob转String*/ | |||||
// public static String blob2Str(Blob blob) { | |||||
// if (blob == null) return ""; | |||||
// ByteArrayOutputStream outStream = null; | |||||
// try { | |||||
// long len = blob.length(); | |||||
// if (len == 0L) return ""; | |||||
// byte[] bytes; | |||||
// long i = 1L; | |||||
// outStream = new ByteArrayOutputStream(); | |||||
// while (i < len) { | |||||
// bytes = blob.getBytes(i, 1024); | |||||
// i += 1024L; | |||||
// outStream.write(bytes); | |||||
// } | |||||
// | |||||
// return UtilEncode.base64EncodeB(outStream.toByteArray()); | |||||
// } catch (Exception e) { | |||||
// e.printStackTrace(); | |||||
// return ""; | |||||
// } finally { | |||||
// IOUtils.closeQuietly(outStream); | |||||
// } | |||||
// } | |||||
public interface IStrHanlder { | |||||
String work(String src); | |||||
} | |||||
public static int[] splitStr(String src, String ch) { | |||||
String[] ss = src.split(ch); | |||||
int[] ret = new int[ss.length]; | |||||
for (int i = 0, len = ss.length; i < len; i++) { | |||||
ret[i] = PubUtil.getIntIgnoreErr(ss[i]); | |||||
} | |||||
return ret; | |||||
} | |||||
public static void main(String[] args) { | |||||
String s = "a[#[#123#]bcde[aaa]bcd"; | |||||
s = myReplaceStrEx(s, "[#", "#]", new IStrHanlder() { | |||||
@Override | |||||
public String work(String src) { | |||||
if (src.equals("123")) return "1"; | |||||
return null; | |||||
} | |||||
}); | |||||
System.out.println(s); | |||||
} | |||||
} |