├── .gitignore
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── org
│ └── hswebframework
│ └── utils
│ ├── ClassUtils.java
│ ├── DateTimeUtils.java
│ ├── ListUtils.java
│ ├── MapUtils.java
│ ├── PinyinUtils.java
│ ├── RandomUtil.java
│ ├── StringUtils.java
│ ├── file
│ ├── BytesEncodingDetect.java
│ ├── ClassLoaderWrapper.java
│ ├── Encoding.java
│ ├── EncodingDetect.java
│ ├── FileUtils.java
│ ├── Resources.java
│ └── callback
│ │ ├── AbstractScanCallBack.java
│ │ ├── CanExitCallBack.java
│ │ ├── ReadCallBack.java
│ │ ├── ReadStringCallBack.java
│ │ └── ScanCallBack.java
│ └── time
│ ├── DateFormatter.java
│ ├── SmartDateFormatter.java
│ └── Utils.java
└── test
└── java
└── org
└── hswebframework
└── utils
└── time
├── TimeTests.java
└── UtilsTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /upload
2 | **/target/
3 | **/out/
4 | bin/
5 | *.class
6 | # Mobile Tools for Java (J2ME)
7 | .mtj.tmp/
8 | .idea/
9 | /nbproject
10 | *.ipr
11 | *.iws
12 | *.iml
13 | *.db
14 | # Package Files #
15 | *.jar
16 | *.war
17 | *.ear
18 |
19 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
20 | hs_err_pid*
21 | pom.xml.versionsBackup
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # hsweb-utils
2 | 常用工具类
3 |
4 | [](http://search.maven.org/#search%7Cga%7C1%7Chsweb-utils)
5 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.hswebframework
8 | hsweb-utils
9 | 3.0.5-SNAPSHOT
10 |
11 | ${project.groupId}:${project.artifactId}
12 | hsweb utils
13 | https://github.com/hs-web/hsweb-utils
14 |
15 |
16 |
17 | The Apache License, Version 2.0
18 | https://www.apache.org/licenses/LICENSE-2.0.txt
19 |
20 |
21 |
22 |
23 |
24 | zhouhao
25 | i@hsweb.me
26 |
27 | Owner
28 |
29 | +8
30 | https://github.com/zhou-hao
31 |
32 |
33 |
34 |
35 | scm:git:https://github.com/hs-web/hsweb-utils.git
36 | scm:git:https://github.com/hs-web/hsweb-utils.git
37 | https://github.com/hs-web/hsweb-utils
38 | ${project.version}
39 |
40 |
41 |
42 |
43 | UTF-8
44 | zh_CN
45 | 1.8
46 | 4.11
47 |
48 |
49 |
50 |
51 | release
52 |
53 |
54 |
55 | org.sonatype.plugins
56 | nexus-staging-maven-plugin
57 | 1.6.3
58 | true
59 |
60 | sonatype-releases
61 | https://oss.sonatype.org/
62 | true
63 |
64 |
65 |
66 | org.apache.maven.plugins
67 | maven-release-plugin
68 |
69 | true
70 | false
71 | release
72 | deploy
73 |
74 |
75 |
76 | org.apache.maven.plugins
77 | maven-gpg-plugin
78 | 1.5
79 |
80 |
81 | sign-artifacts
82 | verify
83 |
84 | sign
85 |
86 |
87 |
88 |
89 |
90 | org.apache.maven.plugins
91 | maven-javadoc-plugin
92 | 2.9.1
93 |
94 | -Xdoclint:none
95 |
96 |
97 |
98 | attach-javadocs
99 |
100 | jar
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | org.apache.maven.plugins
114 | maven-scm-plugin
115 | 1.8.1
116 |
117 | connection
118 |
119 |
120 |
121 |
122 | maven-source-plugin
123 | 2.4
124 |
125 | true
126 |
127 |
128 |
129 | compile
130 |
131 | jar
132 |
133 |
134 |
135 |
136 |
137 |
138 | org.apache.maven.plugins
139 | maven-compiler-plugin
140 | 3.1
141 |
142 | ${project.build.jdk}
143 | ${project.build.jdk}
144 | ${project.build.sourceEncoding}
145 |
146 |
147 |
148 |
149 | org.apache.maven.plugins
150 | maven-surefire-plugin
151 | 2.17
152 |
153 |
154 |
155 | **/org/hswebframework/**/*Tests.java
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | junit
166 | junit
167 | 4.13.2
168 | test
169 |
170 |
171 |
172 | joda-time
173 | joda-time
174 | 2.7
175 |
176 |
177 |
178 |
179 | com.belerweb
180 | pinyin4j
181 | 2.5.0
182 | true
183 |
184 |
185 |
186 |
187 | hsweb-nexus
188 | Nexus Release Repository
189 | https://nexus.jetlinks.cn/content/groups/public/
190 |
191 | true
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | sonatype-releases
211 | sonatype repository
212 | https://oss.sonatype.org/service/local/staging/deploy/maven2
213 |
214 |
215 | sonatype-snapshots
216 | Nexus Snapshot Repository
217 | https://oss.sonatype.org/content/repositories/snapshots
218 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/src/main/java/org/hswebframework/utils/ClassUtils.java:
--------------------------------------------------------------------------------
1 | package org.hswebframework.utils;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.lang.reflect.Method;
5 | import java.lang.reflect.ParameterizedType;
6 | import java.lang.reflect.Type;
7 | import java.util.*;
8 |
9 | public class ClassUtils {
10 |
11 | /**
12 | * 获取一个类的注解,如果未获取到则获取父类
13 | *
14 | * @param clazz 要获取的类
15 | * @param annotation 注解类型
16 | * @param 注解类型泛型
17 | * @return 注解
18 | */
19 | public static T getAnnotation(Class> clazz, Class annotation) {
20 | T ann = clazz.getAnnotation(annotation);
21 | if (ann != null) {
22 | return ann;
23 | } else {
24 | if (clazz.getSuperclass() != Object.class) {
25 | //尝试获取父类
26 | return getAnnotation(clazz.getSuperclass(), annotation);
27 | }
28 | }
29 | return ann;
30 | }
31 |
32 | /**
33 | * 获取一个方法的注解,如果未获取则获取父类方法
34 | *
35 | * @param method 要获取的方法
36 | * @param annotation 注解类型
37 | * @param 注解类型泛型
38 | * @return
39 | */
40 | public static T getAnnotation(Method method, Class annotation) {
41 | T ann = method.getAnnotation(annotation);
42 | if (ann != null) {
43 | return ann;
44 | } else {
45 | Class clazz = method.getDeclaringClass();
46 | Class superClass = clazz.getSuperclass();
47 | if (superClass != Object.class) {
48 | try {
49 | //父类方法
50 | Method suMethod = superClass.getMethod(method.getName(), method.getParameterTypes());
51 | return getAnnotation(suMethod, annotation);
52 | } catch (NoSuchMethodException e) {
53 | return null;
54 | }
55 | }
56 | }
57 | return ann;
58 | }
59 |
60 | public static Class> getGenericTypeByType(ParameterizedType genType, int index) {
61 | Type[] params = genType.getActualTypeArguments();
62 | if (index >= params.length || index < 0) {
63 | return null;
64 | }
65 | Object res = params[index];
66 | if (res instanceof Class) {
67 | return ((Class) res);
68 | }
69 | if (res instanceof ParameterizedType) {
70 | return (Class>) ((ParameterizedType) res).getRawType();
71 | }
72 | return null;
73 | }
74 |
75 | /**
76 | * 获取一个类的泛型类型,如果未获取到返回Object.class
77 | *
78 | * @param clazz 要获取的类
79 | * @param index 泛型索引
80 | * @return 泛型
81 | */
82 | public static Class> getGenericType(Class clazz, int index) {
83 | List arrys = new ArrayList<>();
84 | arrys.add(clazz.getGenericSuperclass());
85 | arrys.addAll(Arrays.asList(clazz.getGenericInterfaces()));
86 | return arrys.stream()
87 | .filter(Objects::nonNull)
88 | .map(type -> {
89 | if (clazz != Object.class && !(type instanceof ParameterizedType)) {
90 | return getGenericType(clazz.getSuperclass(), index);
91 | }
92 | return getGenericTypeByType(((ParameterizedType) type), index);
93 | })
94 | .filter(Objects::nonNull)
95 | .filter(res -> res != Object.class)
96 | .findFirst()
97 | .orElse((Class) Object.class);
98 | }
99 |
100 | /**
101 | * 获取一个类的第一个泛型的类型
102 | *
103 | * @param clazz 要获取的类
104 | * @return 泛型
105 | */
106 | public static Class> getGenericType(Class clazz) {
107 | return getGenericType(clazz, 0);
108 | }
109 |
110 |
111 | public static boolean instanceOf(Class clazz, Class target) {
112 | if (clazz == null) return false;
113 | if (clazz == target) return true;
114 | if (target.isInterface()) {
115 | for (Class aClass : clazz.getInterfaces()) {
116 | if (aClass == target) return true;
117 | }
118 | }
119 | if (clazz.getSuperclass() == target) return true;
120 | else {
121 | if (clazz.isInterface()) {
122 | for (Class aClass : clazz.getInterfaces()) {
123 | if (instanceOf(aClass, target)) return true;
124 | }
125 | }
126 | return instanceOf(clazz.getSuperclass(), target);
127 | }
128 | }
129 |
130 | /**
131 | * 将对象转为指定的类型
132 | *
133 | * 支持日期,数字,boolean类型转换
134 | *
135 | * @param value 需要转换的值
136 | * @param type 目标类型
137 | * @return 转换后的值
138 | */
139 | public static final T cast(Object value, Class type) {
140 | if (value == null) return null;
141 | Object newVal = null;
142 | if (ClassUtils.instanceOf(value.getClass(), type)) {
143 | newVal = value;
144 | } else if (type == Integer.class || type == int.class) {
145 | newVal = StringUtils.toInt(value);
146 | } else if (type == Double.class || type == double.class || type == Float.class || type == float.class) {
147 | newVal = StringUtils.toDouble(value);
148 | } else if (type == Long.class || type == long.class) {
149 | newVal = StringUtils.toLong(value);
150 | } else if (type == Boolean.class || type == boolean.class) {
151 | newVal = StringUtils.isTrue(value);
152 | } else if (type == Date.class) {
153 | newVal = DateTimeUtils.formatUnknownString2Date(value.toString());
154 | } else if (type == String.class) {
155 | if (value instanceof Date) {
156 | newVal = DateTimeUtils.format(((Date) value), DateTimeUtils.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
157 | } else
158 | newVal = String.valueOf(value);
159 | }
160 | return (T) newVal;
161 | }
162 |
163 | public static final Set basicClass = new HashSet<>();
164 |
165 | static {
166 | basicClass.add(int.class);
167 | basicClass.add(double.class);
168 | basicClass.add(float.class);
169 | basicClass.add(byte.class);
170 | basicClass.add(short.class);
171 | basicClass.add(char.class);
172 | basicClass.add(String.class);
173 | }
174 |
175 | public static boolean isBasicClass(Class clazz) {
176 | return basicClass.contains(clazz);
177 | }
178 |
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/src/main/java/org/hswebframework/utils/DateTimeUtils.java:
--------------------------------------------------------------------------------
1 | package org.hswebframework.utils;
2 |
3 | import org.joda.time.DateTime;
4 | import org.joda.time.Days;
5 | import org.joda.time.format.DateTimeFormat;
6 | import org.joda.time.format.DateTimeFormatter;
7 |
8 | import java.util.Date;
9 |
10 | /**
11 | * 日期时间工具类
12 | */
13 | @Deprecated
14 | public final class DateTimeUtils {
15 |
16 | /**
17 | * 年(yyyy)
18 | */
19 | public static final String YEAR = "yyyy";
20 |
21 | /**
22 | * 年-月(yyyy-MM)
23 | */
24 | public static final String YEAR_MONTH = "yyyy-MM";
25 |
26 | /**
27 | * 年-月-日(yyyy-MM-dd)
28 | */
29 | public static final String YEAR_MONTH_DAY = "yyyy-MM-dd";
30 |
31 | /**
32 | * 年月日(yyyyMMdd)
33 | */
34 | public static final String YEAR_MONTH_DAY_SIMPLE = "yyyyMMdd";
35 |
36 | /**
37 | * 年-月-日 小时(yyyy-MM-dd HH)
38 | */
39 | public static final String YEAR_MONTH_DAY_HOUR = "yyyy-MM-dd HH";
40 |
41 | /**
42 | * 年-月-日 小时(yyyy-MM-dd HH)中文输出
43 | */
44 | public static final String YEAR_MONTH_DAY_HOUR_CN = "yyyy年MM月dd日HH时";
45 |
46 | /**
47 | * 年-月-日 小时:分钟(yyyy-MM-dd HH:mm)
48 | */
49 | public static final String YEAR_MONTH_DAY_HOUR_MINUTE = "yyyy-MM-dd HH:mm";
50 |
51 | /**
52 | * 年-月-日 小时:分钟:秒钟(yyyy-MM-dd HH:mm:ss)
53 | */
54 | public static final String YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
55 |
56 | /**
57 | * 年月日小时分钟秒钟(yyyyMMddHHmmss)
58 | */
59 | public static final String YEAR_MONTH_DAY_HOUR_MINUTE_SECOND_SIMPLE = "yyyyMMddHHmmss";
60 |
61 | /**
62 | * 小时:分钟:秒钟(HH:mm:ss)
63 | */
64 | public static final String HOUR_MINUTE_SECOND = "HH:mm:ss";
65 |
66 | /**
67 | * 小时:分钟(HH:mm)
68 | */
69 | public static final String HOUR_MINUTE = "HH:mm";
70 |
71 | /**
72 | * 月.日(M.d)
73 | */
74 | public static final String MONTH_DAY = "M.d";
75 |
76 | /**
77 | * 一天的秒数
78 | */
79 | private static final int DAY_SECOND = 24 * 60 * 60;
80 |
81 | /**
82 | * 一小时的秒数
83 | */
84 | private static final int HOUR_SECOND = 60 * 60;
85 |
86 | /**
87 | * 一分钟的秒数
88 | */
89 | private static final int MINUTE_SECOND = 60;
90 |
91 | /**
92 | * 格式化日期时间
93 | *
94 | * @param date Date对象
95 | * @param pattern 模式
96 | * @return 格式化后的日期时间字符串
97 | */
98 | public static String format(Date date, String pattern) {
99 | if (date == null)
100 | return "";
101 | return new DateTime(date).toString(pattern);
102 | }
103 |
104 | /**
105 | * 格式化日期时间字符串
106 | *
107 | * @param dateString 日期时间字符串
108 | * @param pattern 模式
109 | * @return Date对象
110 | */
111 | public static Date formatDateString(String dateString, String pattern) {
112 | try {
113 | DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(pattern);
114 | return dateTimeFormatter.parseDateTime(dateString).toDate();
115 | } catch (Exception e) {
116 | return null;
117 | }
118 | }
119 |
120 | /**
121 | * 根据秒数获得x天x小时x分钟x秒字符串
122 | *
123 | * @param second 秒数
124 | * @return x天x小时x分钟x秒字符串
125 | */
126 | public static String getDayHourMinuteSecond(int second) {
127 | if (second == 0) {
128 | return "0秒";
129 | }
130 | StringBuilder sb = new StringBuilder();
131 | int days = second / DAY_SECOND;
132 | if (days > 0) {
133 | sb.append(days);
134 | sb.append("天");
135 | second -= days * DAY_SECOND;
136 | }
137 |
138 | int hours = second / HOUR_SECOND;
139 | if (hours > 0) {
140 | sb.append(hours);
141 | sb.append("小时");
142 | second -= hours * HOUR_SECOND;
143 | }
144 |
145 | int minutes = second / MINUTE_SECOND;
146 | if (minutes > 0) {
147 | sb.append(minutes);
148 | sb.append("分钟");
149 | second -= minutes * MINUTE_SECOND;
150 | }
151 | if (second > 0) {
152 | sb.append(second);
153 | sb.append("秒");
154 | }
155 | return sb.toString();
156 | }
157 |
158 |
159 | /**
160 | * 根据秒数获得x天x小时x分钟字符串
161 | *
162 | * @param second 秒数
163 | * @return x天x小时x分钟字符串
164 | */
165 | public static String getDayHourMinute(int second) {
166 | if (second == 0) {
167 | return "0分钟";
168 | }
169 | StringBuilder sb = new StringBuilder();
170 | int days = second / DAY_SECOND;
171 | if (days > 0) {
172 | sb.append(days);
173 | sb.append("天");
174 | second -= days * DAY_SECOND;
175 | }
176 |
177 | int hours = second / HOUR_SECOND;
178 | if (hours > 0) {
179 | sb.append(hours);
180 | sb.append("小时");
181 | second -= hours * HOUR_SECOND;
182 | }
183 | int minutes = second / MINUTE_SECOND;
184 | if (minutes > 0) {
185 | sb.append(minutes);
186 | sb.append("分钟");
187 | }
188 | return sb.toString();
189 | }
190 |
191 | /**
192 | * 获取只含有年月日的DateTime对象
193 | *
194 | * @param dateTime DateTime对象
195 | * @return 只含有年月日的DateTime对象
196 | */
197 | public static DateTime getDateOnly(DateTime dateTime) {
198 | return new DateTime(dateTime.toString(YEAR_MONTH_DAY));
199 | }
200 |
201 | /**
202 | * 获取当前周的周一和下周一
203 | *
204 | * @return 日期数组(索引0为周一,索引1为下周一)
205 | */
206 | public static Date[] getMondayAndNextMonday() {
207 | DateTime dateTime = getDateOnly(new DateTime());
208 | DateTime monday = dateTime.dayOfWeek().withMinimumValue();
209 | DateTime nextMonday = monday.plusDays(7);
210 | return new Date[]{monday.toDate(), nextMonday.toDate()};
211 | }
212 |
213 | /**
214 | * 获取指定时间的周一和周日
215 | *
216 | * @param dateTime DateTime对象
217 | * @return 日期数组(索引0为周一,索引1为周日)
218 | */
219 | public static Date[] getMondayAndSunday(DateTime dateTime) {
220 | dateTime = getDateOnly(dateTime);
221 | DateTime monday = dateTime.dayOfWeek().withMinimumValue();
222 | DateTime sunday = monday.plusDays(6);
223 | return new Date[]{monday.toDate(), sunday.toDate()};
224 | }
225 |
226 | /**
227 | * 和当前时间相比的天数差(正数为大于天数,负数为小于天数,零为同一天)
228 | *
229 | * @param date Date对象
230 | * @return 和当前时间相比的天数差
231 | */
232 | public static int compareDaysWithNow(Date date) {
233 | return Days.daysBetween(new DateTime(), new DateTime(date)).getDays();
234 | }
235 |
236 | /**
237 | * 和今天相比的天数差(正数为大于天数,负数为小于天数,零为同一天)
238 | *
239 | * @param date Date对象
240 | * @return 和今天相比的天数差
241 | */
242 | public static int compareDaysWithToday(Date date) {
243 | DateTime today = new DateTime();
244 | today = new DateTime(today.getYear(), today.getMonthOfYear(), today.getDayOfMonth(), 0, 0, 0, 0);
245 | DateTime compareDay = new DateTime(date);
246 | compareDay = new DateTime(compareDay.getYear(), compareDay.getMonthOfYear(), compareDay.getDayOfMonth(), 0, 0, 0, 0);
247 | return Days.daysBetween(today, compareDay).getDays();
248 | }
249 |
250 | /**
251 | * 比较时间a到时间b的天数差
252 | *
253 | * @param a 时间a
254 | * @param b 时间b
255 | * @return 相差天数
256 | */
257 | public static int compareDaysWithDay(Date a, Date b) {
258 | DateTime today = new DateTime(b);
259 | today = new DateTime(today.getYear(), today.getMonthOfYear(), today.getDayOfMonth(), 0, 0, 0, 0);
260 | DateTime compareDay = new DateTime(a);
261 | compareDay = new DateTime(compareDay.getYear(), compareDay.getMonthOfYear(), compareDay.getDayOfMonth(), 0, 0, 0, 0);
262 | return Days.daysBetween(today, compareDay).getDays();
263 | }
264 |
265 | /**
266 | * 比较两个时间是否相等(省略毫秒)
267 | *
268 | * @param date Date对象
269 | * @param compareDate 比较Date对象
270 | * @return 是否相等
271 | */
272 | public static boolean compareDateIgnoreMillisecond(Date date, Date compareDate) {
273 | if (date == null && compareDate == null) {
274 | return true;
275 | } else if (date == null && compareDate != null) {
276 | return false;
277 | } else if (date != null && compareDate == null) {
278 | return false;
279 | }
280 |
281 | return (date.getTime() / 1000 == compareDate.getTime() / 1000);
282 | }
283 |
284 | /**
285 | * 根据秒数获取天数
286 | *
287 | * @param second 秒数
288 | * @return 天数
289 | */
290 | public static int getDay(int second) {
291 | return second / DAY_SECOND;
292 | }
293 |
294 | /**
295 | * 获取和今天相比的日期字符串
296 | *
297 | * @param date Date对象
298 | * @return 和今天相比的日期字符串
299 | */
300 | public static String getCompareWithTodayDateString(Date date) {
301 | int days = Math.abs(DateTimeUtils.compareDaysWithToday(date));
302 | String dateString = "";
303 | if (days == 0) {
304 | dateString = "今天";
305 | } else if (days == 1) {
306 | dateString = "昨天";
307 | } else if (days == 2) {
308 | dateString = "2天前";
309 | } else if (days == 3) {
310 | dateString = "3天前";
311 | } else if (days == 4) {
312 | dateString = "4天前";
313 | } else if (days == 5) {
314 | dateString = "5天前";
315 | } else if (days == 6) {
316 | dateString = "6天前";
317 | } else if (days > 6 && days <= 14) {
318 | dateString = "1周前";
319 | } else if (days > 14 && days <= 21) {
320 | dateString = "2周前";
321 | } else if (days > 21 && days <= 30) {
322 | dateString = "3周前";
323 | } else if (days > 30) {
324 | dateString = "1月前";
325 | } else if (days > 365) {
326 | dateString = "1年前";
327 | } else if (days > 365 * 3) {
328 | dateString = "3年前";
329 | }
330 | return dateString;
331 | }
332 |
333 | /**
334 | * 比较两个时间相差分钟数
335 | *
336 | * @param now 当前时间
337 | * @param compareDate 比较时间
338 | * @return 相差分钟数
339 | */
340 | public static int compareMinutes(Date now, Date compareDate) {
341 | return (int) (now.getTime() - compareDate.getTime()) / 60000;
342 | }
343 |
344 | /**
345 | * 比较时间是本月的第几天
346 | *
347 | * @param date
348 | * @return
349 | */
350 | public static int getDayOfMonth(Date date) {
351 | DateTime dateTime = new DateTime(date);
352 | return dateTime.getDayOfMonth();
353 | }
354 |
355 | /**
356 | * 计算当月有几天
357 | *
358 | * @param date
359 | * @return
360 | */
361 | public static int getDateOfMonth(Date date) {
362 | DateTime dateTime = new DateTime(date);
363 | return dateTime.dayOfMonth().getMaximumValue();
364 | }
365 |
366 | /**
367 | * 指定时间,判断该时间到现在时间的年数
368 | *
369 | * @param date 指定时间
370 | * @return 到现在时间的年数
371 | */
372 | public static int compareYear(Date date) {
373 | DateTime btd = new DateTime(date);
374 | DateTime nowDate = new DateTime();
375 | int year = 0;
376 | if (nowDate.getMonthOfYear() > btd.getMonthOfYear()) {
377 | year = nowDate.getYear() - btd.getYear();
378 | } else if (nowDate.getMonthOfYear() < btd.getMonthOfYear()) {
379 | year = nowDate.getYear() - btd.getYear() - 1;
380 | } else if (nowDate.getMonthOfYear() == btd.getMonthOfYear()) {
381 | if (nowDate.getDayOfMonth() >= btd.getDayOfMonth()) {
382 | year = nowDate.getYear() - btd.getYear();
383 | } else {
384 | year = nowDate.getYear() - btd.getYear() - 1;
385 | }
386 | }
387 | return year;
388 | }
389 |
390 | /**
391 | * 判断2个时间的时间差 返回字符串形式
392 | *
393 | * @param date 要对比的字符串
394 | * @param date2 要对比的字符串
395 | * @return 字符串形式 如1小时 ,2天2小时
396 | */
397 | public static String compareDaysWithDate(Date date, Date date2) {
398 | StringBuilder msg = new StringBuilder();
399 | int minutes = (int) Math.abs((date.getTime() - date2.getTime()) / 60000);
400 | if (minutes / 60 > 0 && minutes / 60 / 24 <= 0) {
401 | msg.append(minutes / 60 + "小时");
402 | }
403 | if (minutes / 60 / 24 > 0) {
404 | msg.append(minutes / 60 / 24 + "天");
405 | msg.append(minutes / 60 % 24 + "小时");
406 | }
407 | return msg.toString();
408 | }
409 |
410 | public static final String REG_EXP_DATE = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
411 |
412 | /**
413 | * 自动解析多种格式的时间字符串为时间对象
414 | * 支持格式为:yyyy-MM-dd HH:mm:ss 支持多种分隔符,以及多种日期精度。 如yyyy年MM月。 HH时mm分ss秒
415 | *
416 | * @param dateString 时间字符串
417 | * @return 格式正确则返回对应的java.util.Date对象 格式错误返回null
418 | */
419 | public static Date formatUnknownString2Date(String dateString) {
420 | try {
421 | if (StringUtils.isNullOrEmpty(dateString)) {
422 | return null;
423 | }
424 | dateString = dateString.replace("T", " ");
425 | String hms = "00:00:00";
426 | dateString = dateString.trim();
427 | if (dateString.contains(" ")) {
428 | // 截取时分秒
429 | hms = dateString.substring(dateString.indexOf(" ") + 1, dateString.length());
430 | // 重置日期
431 | dateString = dateString.substring(0, dateString.indexOf(" "));
432 | // 多中分隔符的支持
433 | hms = hms.replace(":", ":");
434 | hms = hms.replace("时", ":");
435 | hms = hms.replace("分", ":");
436 | hms = hms.replace("秒", ":");
437 | hms = hms.replace("-", ":");
438 | hms = hms.replace("-", ":");
439 | // 时间不同精确度的支持
440 | if (hms.endsWith(":")) {
441 | hms = hms.substring(0, hms.length() - 1);
442 | }
443 | if (hms.split(":").length == 1) {
444 | hms += ":00:00";
445 | }
446 | if (hms.split(":").length == 2) {
447 | hms += ":00";
448 | }
449 | }
450 | String[] hmsarr = hms.split(":");
451 | // 不同日期分隔符的支持
452 | dateString = dateString.replace(".", "-");
453 | dateString = dateString.replace("/", "-");
454 | dateString = dateString.replace("-", "-");
455 | dateString = dateString.replace("年", "-");
456 | dateString = dateString.replace("月", "-");
457 | dateString = dateString.replace("日", "");
458 | // 切割年月日
459 | String yearStr, monthStr, dateStr;
460 | // 截取日期
461 | String[] ymd = dateString.split("-");
462 | // 判断日期精确度
463 | yearStr = ymd[0];
464 | monthStr = ymd.length > 1 ? ymd[1] : "";
465 | dateStr = ymd.length > 2 ? ymd[2] : "";
466 | monthStr = monthStr == "" ? Integer.toString(1) : monthStr;
467 | dateStr = dateStr == "" ? Integer.toString(1) : dateStr;
468 | String dtr = (yearStr + "-" + monthStr + "-" + dateStr + " " + hms);
469 | if (!dtr.matches(REG_EXP_DATE))
470 | return null;
471 | // 返回日期
472 | return new DateTime(Integer.parseInt(yearStr.trim()), Integer.parseInt(monthStr.trim()), Integer.parseInt(dateStr.trim()), Integer.parseInt(hmsarr[0].trim()), Integer.parseInt(hmsarr[1].trim()), Integer.parseInt(hmsarr[2].trim()), 0).toDate();
473 | } catch (Exception e) {
474 | return null;
475 | }
476 | }
477 |
478 | /**
479 | * 解析多个时间,指定时间之间的分隔符和时间的格式符 分隔符不能与格式符相同
480 | *
481 | * @param dateString 传入一个时间段字符串
482 | * @param spaceChar 指定格式符
483 | * @param splitChar 指定分隔符
484 | * @return 格式正确返回分割后的时间对象数组 格式错误返回null
485 | * 指定了格式符为. 分隔符为- 返回值为 时间长度为2的Date类型数组
486 | * 时间转换的方式详见 {@link DateTimeUtils#formatUnknownString2Date(String dateString)}
487 | */
488 | public static Date[] formatDatesByString(String dateString, String spaceChar, String splitChar) {
489 | if (spaceChar.equals(splitChar)) {
490 | return null;
491 | }
492 | String[] dateStrs = dateString.split(splitChar);
493 | Date[] dates = new Date[dateStrs.length];
494 | for (int i = 0, size = dateStrs.length; i < size; i++) {
495 | dates[i] = formatUnknownString2Date(dateStrs[i]);
496 | }
497 | return dates;
498 | }
499 |
500 | /**
501 | * 身份证号转生日
502 | *
503 | * @param identityCard 身份证
504 | * @return 生日
505 | */
506 | public static Date identityCard2Date(String identityCard) {
507 | try {
508 | String dateStr;
509 | if (identityCard.length() == 18) {
510 | dateStr = identityCard.substring(6, 14);// 截取18位身份证身份证中生日部分
511 | return formatDateString(dateStr, "yyyyMMdd");
512 | }
513 | if (identityCard.length() == 15) {
514 | dateStr = identityCard.substring(6, 12);// 截取15位身份证中生日部分
515 | return formatDateString(dateStr, "yyMMdd");
516 | }
517 | return null;
518 | } catch (Exception e) {
519 | return null;
520 | }
521 | }
522 |
523 | public static boolean validDate(String str) {
524 | try {
525 | Date date = formatUnknownString2Date(str);
526 | return date != null;
527 | } catch (Exception e) {
528 | return false;
529 | }
530 | }
531 | }
532 |
--------------------------------------------------------------------------------
/src/main/java/org/hswebframework/utils/ListUtils.java:
--------------------------------------------------------------------------------
1 | package org.hswebframework.utils;
2 |
3 |
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.function.Supplier;
7 |
8 | @Deprecated
9 | public class ListUtils {
10 | public static boolean isNullOrEmpty(List list) {
11 | return list == null || list.isEmpty();
12 | }
13 |
14 | public static String toString(Object... objs) {
15 | StringBuffer buffer = new StringBuffer();
16 | for (int i = 0; i < objs.length; i++) {
17 | if (i != 0)
18 | buffer.append(",");
19 | buffer.append(objs[i]);
20 | }
21 | return buffer.toString();
22 | }
23 |
24 | public static Integer[] stringArr2intArr(String[] arr) {
25 | Integer[] i = new Integer[arr.length];
26 | int index = 0;
27 | for (String str : arr) {
28 | if (StringUtils.isInt(str)) {
29 | i[index++] = Integer.parseInt(str);
30 | }
31 | }
32 | return i;
33 | }
34 |
35 | public static List merge(List list, List... lists) {
36 | return merge(new ArrayList<>(), list, lists);
37 | }
38 |
39 | public static List merge(List target, List list, List... lists) {
40 | target.addAll(list);
41 | for (int i = 0; i < lists.length; i++) {
42 | target.addAll(lists[i]);
43 | }
44 | return target;
45 | }
46 |
47 | public static List merge(Supplier> supplier, List list, List... lists) {
48 | return merge(supplier.get(), list, lists);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/hswebframework/utils/MapUtils.java:
--------------------------------------------------------------------------------
1 | package org.hswebframework.utils;
2 |
3 |
4 | import java.util.*;
5 | import java.util.function.Supplier;
6 |
7 | @Deprecated
8 | public class MapUtils {
9 |
10 | public static boolean isNullOrEmpty(Map map) {
11 | return map == null || map.isEmpty();
12 | }
13 |
14 | public static Map removeEmptyValue(Map map) {
15 | Map newMap = new HashMap<>();
16 | if (map == null)
17 | return newMap;
18 | map.entrySet().stream().filter(entry -> !StringUtils.isNullOrEmpty(entry.getValue())).forEach(entry -> {
19 | newMap.put(entry.getKey(), entry.getValue());
20 | });
21 | return newMap;
22 | }
23 |
24 | public static Map sortMapByKey(Map data) {
25 | Map data_ = new LinkedHashMap<>();
26 | List list = new LinkedList<>(data.keySet());
27 | Collections.sort(list);
28 | for (K k : list) {
29 | data_.put(k, data.get(k));
30 | }
31 | return data_;
32 | }
33 |
34 | public static Map merge(Map map, Map maps) {
35 | return merge(new HashMap<>(), map, maps);
36 | }
37 |
38 | public static Map merge(Map target, Map map, Map... maps) {
39 | target.putAll(map);
40 | for (int i = 0; i < maps.length; i++) {
41 | target.putAll(maps[i]);
42 | }
43 | return target;
44 | }
45 |
46 | public static Map merge(Supplier