Commit 60237a90 authored by yanzg's avatar yanzg

GIT工具类

parent 609ffc62
...@@ -18,6 +18,12 @@ ...@@ -18,6 +18,12 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring依赖 --> <!-- Spring依赖 -->
<!-- 1.Spring核心依赖 --> <!-- 1.Spring核心依赖 -->
...@@ -54,6 +60,12 @@ ...@@ -54,6 +60,12 @@
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
<version>${fastjson.version}</version> <version>${fastjson.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
......
//package com.yanzuoguang.util.cache; package com.yanzuoguang.util.cache;
//
//import com.tourbida.sys.core.util.StringHelper; import com.yanzuoguang.util.helper.StringHelper;
//
//import java.util.Date; import java.util.Date;
//import java.util.Hashtable; import java.util.Hashtable;
//
///** /**
// * 内存缓存 * 内存缓存
// * *
// * @param <T> * @param <T>
// */ */
//public class MemoryCache<T> { public class MemoryCache<T> {
//
// /** /**
// * 缓存的对象 * 缓存的对象
// */ */
// private Hashtable<String, MemoryCacheItem<T>> cache = new Hashtable<String, MemoryCacheItem<T>>(); private Hashtable<String, MemoryCacheItem<T>> cache = new Hashtable<String, MemoryCacheItem<T>>();
//
// /** /**
// * 清除时间 * 清除时间
// */ */
// private int clearSecond; private int clearSecond;
//
// /** /**
// * 是否自动清除缓存 * 是否自动清除缓存
// */ */
// private boolean isAutoClear; private boolean isAutoClear;
//
// /** /**
// * 读取时是否激活 * 读取时是否激活
// */ */
// private boolean isGetActive; private boolean isGetActive;
//
// /** /**
// * 构造函数,不会自动清除对象 * 构造函数,不会自动清除对象
// */ */
// public MemoryCache() { public MemoryCache() {
// this(false, 0); this(false, 0);
// } }
//
// /** /**
// * 构造函数 * 构造函数
// * *
// * @param clearSecond 清除缓存的时间 * @param clearSecond 清除缓存的时间
// */ */
// public MemoryCache(int clearSecond) { public MemoryCache(int clearSecond) {
// this(true, clearSecond); this(true, clearSecond);
// } }
//
// /** /**
// * 构造函数 * 构造函数
// * *
// * @param isAutoClear 是否自动清除 * @param isAutoClear 是否自动清除
// * @param clearSecond 清除缓存的时间 * @param clearSecond 清除缓存的时间
// */ */
// public MemoryCache(boolean isAutoClear, int clearSecond) { public MemoryCache(boolean isAutoClear, int clearSecond) {
// this.isAutoClear = isAutoClear; this.isAutoClear = isAutoClear;
// this.clearSecond = clearSecond; this.clearSecond = clearSecond;
// this.isGetActive = false; this.isGetActive = false;
// if (isAutoClear) { if (isAutoClear) {
// MemoryCacheCenter.CLEAR_LIST.add(this); MemoryCacheCenter.CLEAR_LIST.add(this);
// } }
// } }
//
// public boolean isGetActive() { public boolean isGetActive() {
// return isGetActive; return isGetActive;
// } }
//
// public void setGetActive(boolean getActive) { public void setGetActive(boolean getActive) {
// isGetActive = getActive; isGetActive = getActive;
// } }
//
// public int getClearSecond() { public int getClearSecond() {
// return clearSecond; return clearSecond;
// } }
//
// public void setClearSecond(int clearSecond) { public void setClearSecond(int clearSecond) {
// this.clearSecond = clearSecond; this.clearSecond = clearSecond;
// } }
//
// /** /**
// * 写入数据 * 写入数据
// * *
// * @param key 关键字 * @param key 关键字
// * @param data 数据 * @param data 数据
// */ */
// public synchronized T put(String key, T data) { public synchronized T put(String key, T data) {
// if (this.isAutoClear && this.clearSecond < 1) { if (this.isAutoClear && this.clearSecond < 1) {
// return data; return data;
// } }
// MemoryCacheItem<T> item = cache.getOrDefault(key, new MemoryCacheItem<T>()); MemoryCacheItem<T> item = cache.getOrDefault(key, new MemoryCacheItem<T>());
// item.setData(data); item.setData(data);
// if (StringHelper.IsEmpty(item.getName())) { if (StringHelper.isEmpty(item.getName())) {
// item.setName(key); item.setName(key);
// cache.put(key, item); cache.put(key, item);
// } }
// return item.getData(); return item.getData();
// } }
//
// /** /**
// * 读取数据 * 读取数据
// * *
// * @param key 关键字 * @param key 关键字
// */ */
// public synchronized T get(String key) { public synchronized T get(String key) {
// if (this.isAutoClear && this.clearSecond < 1) { if (this.isAutoClear && this.clearSecond < 1) {
// return null; return null;
// } }
// MemoryCacheItem<T> item = cache.get(key); MemoryCacheItem<T> item = cache.get(key);
// if (item == null) { if (item == null) {
// return null; return null;
// } }
// this.getActive(item); this.getActive(item);
// return item.getData(); return item.getData();
// } }
//
// /** /**
// * 读取数据 * 读取数据
// * *
// * @param key 关键字 * @param key 关键字
// * @param defData 默认数据 * @param defData 默认数据
// * @return * @return
// */ */
// public synchronized T get(String key, T defData) { public synchronized T get(String key, T defData) {
// if (this.isAutoClear && this.clearSecond < 1) { if (this.isAutoClear && this.clearSecond < 1) {
// return defData; return defData;
// } }
// MemoryCacheItem<T> item = cache.getOrDefault(key, new MemoryCacheItem<T>()); MemoryCacheItem<T> item = cache.getOrDefault(key, new MemoryCacheItem<T>());
// if (StringHelper.IsEmpty(item.getName())) { if (StringHelper.isEmpty(item.getName())) {
// item.setName(key); item.setName(key);
// item.setData(defData); item.setData(defData);
// cache.put(key, item); cache.put(key, item);
// } else { } else {
// if (defData instanceof MemoryCache) { if (defData instanceof MemoryCache) {
// ((MemoryCache) defData).close(); ((MemoryCache) defData).close();
// } }
// } }
// this.getActive(item); this.getActive(item);
// return item.getData(); return item.getData();
// } }
//
// /** /**
// * 在获取时重新激活数据 * 在获取时重新激活数据
// */ */
// private void getActive(MemoryCacheItem<T> item) { private void getActive(MemoryCacheItem<T> item) {
// if (isGetActive) { if (isGetActive) {
// item.active(); item.active();
// } }
// } }
//
// /** /**
// * 删除一个数据 * 删除一个数据
// * *
// * @param key 关键字 * @param key 关键字
// */ */
// public synchronized T remove(String key) { public synchronized T remove(String key) {
// MemoryCacheItem<T> item = cache.remove(key); MemoryCacheItem<T> item = cache.remove(key);
// if (item == null) { if (item == null) {
// return null; return null;
// } }
// T data = item.getData(); T data = item.getData();
// if (data instanceof MemoryCache) { if (data instanceof MemoryCache) {
// ((MemoryCache) data).close(); ((MemoryCache) data).close();
// } }
// return data; return data;
// } }
//
// /** /**
// * 清除所有的缓存 * 清除所有的缓存
// */ */
// public synchronized void clear() { public synchronized void clear() {
// Object[] keys = cache.keySet().toArray(); Object[] keys = cache.keySet().toArray();
// for (Object keyObject : keys) { for (Object keyObject : keys) {
// // 关键字 // 关键字
// String key = keyObject.toString(); String key = keyObject.toString();
// this.remove(key); this.remove(key);
// } }
// } }
//
// /** /**
// * 清除超时的数据 * 清除超时的数据
// */ */
// public synchronized void clearTimeout() { public synchronized void clearTimeout() {
// if (this.clearSecond < 0) { if (this.clearSecond < 0) {
// return; return;
// } }
// Object[] keys = cache.keySet().toArray(); Object[] keys = cache.keySet().toArray();
// Date now = new Date(); Date now = new Date();
// for (Object keyObject : keys) { for (Object keyObject : keys) {
// // 关键字 // 关键字
// String key = keyObject.toString(); String key = keyObject.toString();
// // 获取到数据 // 获取到数据
// MemoryCacheItem<T> itemValue = this.cache.get(key); MemoryCacheItem<T> itemValue = this.cache.get(key);
// if (itemValue == null) { if (itemValue == null) {
// continue; continue;
// } }
// // 判断是否过期 // 判断是否过期
// if (now.getTime() - itemValue.getDate().getTime() > this.clearSecond * 1000) { if (now.getTime() - itemValue.getDate().getTime() > this.clearSecond * 1000) {
// this.remove(key); this.remove(key);
// } }
// } }
// } }
//
// /** /**
// * 将缓存对象从缓存对象中清除 * 将缓存对象从缓存对象中清除
// */ */
// public synchronized void close() { public synchronized void close() {
// this.clear(); this.clear();
// MemoryCacheCenter.CLEAR_LIST.remove(this); MemoryCacheCenter.CLEAR_LIST.remove(this);
// } }
//
// /** /**
// * 获取所有的关键字 * 获取所有的关键字
// * *
// * @return * @return
// */ */
// public synchronized String[] getKeys() { public synchronized String[] getKeys() {
// String[] items = new String[this.cache.size()]; String[] items = new String[this.cache.size()];
// return this.cache.keySet().toArray(items); return this.cache.keySet().toArray(items);
// } }
//
// /** /**
// * 析构函数 * 析构函数
// * *
// * @throws Throwable * @throws Throwable
// */ */
// @Override @Override
// protected void finalize() throws Throwable { protected void finalize() throws Throwable {
// this.close(); this.close();
// } }
//} }
//package com.yanzuoguang.util.cache; package com.yanzuoguang.util.cache;
//
//import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
//
//import java.util.List; import java.util.List;
//import java.util.Vector; import java.util.Vector;
//
//@Component @Component
//public class MemoryCacheCenter { public class MemoryCacheCenter {
//
// /** /**
// * 缓存的对象 * 缓存的对象
// */ */
// public static List<MemoryCache> CLEAR_LIST = new Vector<MemoryCache>(); public static List<MemoryCache> CLEAR_LIST = new Vector<MemoryCache>();
//
// /** /**
// * 间隔5秒执行 * 间隔5秒执行
// */ */
// @Scheduled(cron = "0/5 * * * * ? ") @Scheduled(cron = "0/5 * * * * ? ")
// public void clear(){ public void clear(){
// // 死循环处理
// todo: 需要修改
// 死循环处理
// ThreadList<MemoryCache> threadList = new ThreadList<MemoryCache>(1) { // ThreadList<MemoryCache> threadList = new ThreadList<MemoryCache>(1) {
// @Override // @Override
// public void Execute(MemoryCache item) { // public void Execute(MemoryCache item) {
...@@ -29,5 +31,5 @@ ...@@ -29,5 +31,5 @@
// threadList.setPrint(false); // threadList.setPrint(false);
// threadList.add(CLEAR_LIST); // threadList.add(CLEAR_LIST);
// threadList.waitSucccess(true); // threadList.waitSucccess(true);
// } }
//} }
package com.yanzuoguang.util.base; package com.yanzuoguang.util.helper;
import com.yanzuoguang.util.exception.CodeException;
/** /**
* 通信格式转换 * 通信格式转换
* <p> * <p>
* Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换 高、低字节之间的转换 * Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换 高、低字节之间的转换
* windows的字节序为低字节开头 linux,unix的字节序为高字节开头 java则无论平台变化,都是高字节开头 * windows的字节序为低字节开头 linux,unix的字节序为高字节开头 java则无论平台变化,都是高字节开头
*/ */
public class ByteConvertHelper { public class ByteHelper {
// --------------------------------------- toLH ------------------------------------- // --------------------------------------- toLH -------------------------------------
...@@ -16,7 +18,7 @@ public class ByteConvertHelper { ...@@ -16,7 +18,7 @@ public class ByteConvertHelper {
* *
* @param n 需要转换的值 * @param n 需要转换的值
* @param max 字节最大长度 * @param max 字节最大长度
* @return * @return 转换后的数据
*/ */
public static byte[] toLH(long n, int max) { public static byte[] toLH(long n, int max) {
byte[] b = new byte[max]; byte[] b = new byte[max];
...@@ -31,7 +33,7 @@ public class ByteConvertHelper { ...@@ -31,7 +33,7 @@ public class ByteConvertHelper {
* 将 long 值转成低字节在前,高字节在后的byte数组 * 将 long 值转成低字节在前,高字节在后的byte数组
* *
* @param n 需要转换的值 * @param n 需要转换的值
* @return * @return 转换后的数据
*/ */
public static byte[] toLH(long n) { public static byte[] toLH(long n) {
return toLH(n, 8); return toLH(n, 8);
...@@ -40,8 +42,8 @@ public class ByteConvertHelper { ...@@ -40,8 +42,8 @@ public class ByteConvertHelper {
/** /**
* 将int转为低字节在前,高字节在后的byte数组 * 将int转为低字节在前,高字节在后的byte数组
* *
* @param n int * @param n 需要转换的数据
* @return byte[] * @return 转换后的数据
*/ */
public static byte[] toLH(int n) { public static byte[] toLH(int n) {
return toLH(n, 4); return toLH(n, 4);
...@@ -50,8 +52,8 @@ public class ByteConvertHelper { ...@@ -50,8 +52,8 @@ public class ByteConvertHelper {
/** /**
* 将short转为低字节在前,高字节在后的byte数组 * 将short转为低字节在前,高字节在后的byte数组
* *
* @param n short * @param n 需要转换的数据
* @return byte[] * @return 转换后的数据
*/ */
public static byte[] toLH(short n) { public static byte[] toLH(short n) {
return toLH(n, 2); return toLH(n, 2);
...@@ -59,6 +61,9 @@ public class ByteConvertHelper { ...@@ -59,6 +61,9 @@ public class ByteConvertHelper {
/** /**
* 将float转为低字节在前,高字节在后的byte数组 * 将float转为低字节在前,高字节在后的byte数组
*
* @param f 需要转换的数据
* @return 转换后的数据
*/ */
public static byte[] toLH(float f) { public static byte[] toLH(float f) {
return toLH(Float.floatToRawIntBits(f)); return toLH(Float.floatToRawIntBits(f));
...@@ -71,7 +76,7 @@ public class ByteConvertHelper { ...@@ -71,7 +76,7 @@ public class ByteConvertHelper {
* *
* @param n 需要转换的值 * @param n 需要转换的值
* @param max 字节最大长度 * @param max 字节最大长度
* @return * @return 转换后的数据
*/ */
public static byte[] toHL(long n, int max) { public static byte[] toHL(long n, int max) {
byte[] b = new byte[max]; byte[] b = new byte[max];
...@@ -86,7 +91,7 @@ public class ByteConvertHelper { ...@@ -86,7 +91,7 @@ public class ByteConvertHelper {
* 将 long 值转成高字节在前,低字节在后的byte数组 * 将 long 值转成高字节在前,低字节在后的byte数组
* *
* @param n 需要转换的值 * @param n 需要转换的值
* @return * @return 转换后的数据
*/ */
public static byte[] toHL(long n) { public static byte[] toHL(long n) {
return toHL(n, 8); return toHL(n, 8);
...@@ -95,8 +100,8 @@ public class ByteConvertHelper { ...@@ -95,8 +100,8 @@ public class ByteConvertHelper {
/** /**
* 将int转为高字节在前,低字节在后的byte数组 * 将int转为高字节在前,低字节在后的byte数组
* *
* @param n int * @param n 需要转换的值
* @return byte[] * @return 转换后的数据
*/ */
public static byte[] toHL(int n) { public static byte[] toHL(int n) {
return toHL(n, 4); return toHL(n, 4);
...@@ -105,8 +110,8 @@ public class ByteConvertHelper { ...@@ -105,8 +110,8 @@ public class ByteConvertHelper {
/** /**
* 将short转为高字节在前,低字节在后的byte数组 * 将short转为高字节在前,低字节在后的byte数组
* *
* @param n short * @param n 需要转换的值
* @return byte[] * @return 转换后的数据
*/ */
public static byte[] toHL(short n) { public static byte[] toHL(short n) {
return toHL(n, 2); return toHL(n, 2);
...@@ -114,12 +119,14 @@ public class ByteConvertHelper { ...@@ -114,12 +119,14 @@ public class ByteConvertHelper {
/** /**
* 将float转为高字节在前,低字节在后的byte数组 * 将float转为高字节在前,低字节在后的byte数组
*
* @param f 需要转换的值
* @return 转换后的数据
*/ */
public static byte[] toHL(float f) { public static byte[] toHL(float f) {
return toHL(Float.floatToRawIntBits(f)); return toHL(Float.floatToRawIntBits(f));
} }
// --------------------------------------- byLH ------------------------------------- // --------------------------------------- byLH -------------------------------------
/** /**
...@@ -128,7 +135,7 @@ public class ByteConvertHelper { ...@@ -128,7 +135,7 @@ public class ByteConvertHelper {
* @param bytes 字节 * @param bytes 字节
* @param off 开始位置 * @param off 开始位置
* @param max 最大位置 * @param max 最大位置
* @return * @return 转换后的结果
*/ */
public static long toLongByLH(byte[] bytes, int off, int max) { public static long toLongByLH(byte[] bytes, int off, int max) {
long ret = 0; long ret = 0;
...@@ -143,8 +150,8 @@ public class ByteConvertHelper { ...@@ -143,8 +150,8 @@ public class ByteConvertHelper {
/** /**
* 将低字节数组转换为long * 将低字节数组转换为long
* *
* @param b byte[] * @param b 需要转换的值
* @return long * @return 转换后的数据
*/ */
public static long toLongByLH(byte[] b) { public static long toLongByLH(byte[] b) {
return toLongByLH(b, 0); return toLongByLH(b, 0);
...@@ -153,9 +160,9 @@ public class ByteConvertHelper { ...@@ -153,9 +160,9 @@ public class ByteConvertHelper {
/** /**
* 将低字节数组转换为long * 将低字节数组转换为long
* *
* @param b * @param b 需要转换的值
* @param off * @param off 偏移位置
* @return * @return 转换后的数据
*/ */
public static long toLongByLH(byte[] b, int off) { public static long toLongByLH(byte[] b, int off) {
return toLongByLH(b, off, 8); return toLongByLH(b, off, 8);
...@@ -164,8 +171,8 @@ public class ByteConvertHelper { ...@@ -164,8 +171,8 @@ public class ByteConvertHelper {
/** /**
* 将低字节数组转换为int * 将低字节数组转换为int
* *
* @param b byte[] * @param b 需要转换的值
* @return int * @return 转换后的数据
*/ */
public static int toIntByLH(byte[] b) { public static int toIntByLH(byte[] b) {
return toIntByLH(b, 0); return toIntByLH(b, 0);
...@@ -174,9 +181,9 @@ public class ByteConvertHelper { ...@@ -174,9 +181,9 @@ public class ByteConvertHelper {
/** /**
* 将低字节数组转换为int * 将低字节数组转换为int
* *
* @param b * @param b 需要转换的值
* @param off * @param off 偏移位置
* @return * @return 转换后的数据
*/ */
public static int toIntByLH(byte[] b, int off) { public static int toIntByLH(byte[] b, int off) {
return (int) toLongByLH(b, off, 4); return (int) toLongByLH(b, off, 4);
...@@ -185,8 +192,8 @@ public class ByteConvertHelper { ...@@ -185,8 +192,8 @@ public class ByteConvertHelper {
/** /**
* 低字节数组到short的转换 * 低字节数组到short的转换
* *
* @param b * @param b 需要转换的值
* @return * @return 转换后的数据
*/ */
public static short toShortByLH(byte[] b) { public static short toShortByLH(byte[] b) {
return toShortByLH(b, 0); return toShortByLH(b, 0);
...@@ -195,9 +202,9 @@ public class ByteConvertHelper { ...@@ -195,9 +202,9 @@ public class ByteConvertHelper {
/** /**
* 低字节数组到short的转换 * 低字节数组到short的转换
* *
* @param b * @param b 需要转换的值
* @param off * @param off 偏移位置
* @return * @return 转换后的数据
*/ */
public static short toShortByLH(byte[] b, int off) { public static short toShortByLH(byte[] b, int off) {
return (short) toLongByLH(b, off, 2); return (short) toLongByLH(b, off, 2);
...@@ -206,12 +213,11 @@ public class ByteConvertHelper { ...@@ -206,12 +213,11 @@ public class ByteConvertHelper {
/** /**
* 低字节数组转换为float * 低字节数组转换为float
* *
* @param b byte[] * @param b 需要转换的值
* @return float * @return 转换后的数据
*/ */
public static float toFloatByLH(byte[] b) { public static float toFloatByLH(byte[] b) {
int i = toIntByLH(b); return Float.intBitsToFloat(toIntByLH(b));
return Float.intBitsToFloat(i);
} }
...@@ -223,7 +229,7 @@ public class ByteConvertHelper { ...@@ -223,7 +229,7 @@ public class ByteConvertHelper {
* @param bytes 字节 * @param bytes 字节
* @param off 开始位置 * @param off 开始位置
* @param max 最大位置 * @param max 最大位置
* @return * @return 转换后的数据
*/ */
public static long toLongByHL(byte[] bytes, int off, int max) { public static long toLongByHL(byte[] bytes, int off, int max) {
long ret = 0; long ret = 0;
...@@ -238,8 +244,8 @@ public class ByteConvertHelper { ...@@ -238,8 +244,8 @@ public class ByteConvertHelper {
/** /**
* 将高字节数组转换为long * 将高字节数组转换为long
* *
* @param b * @param b 需要转换的值
* @return * @return 转换后的数据
*/ */
public static long toLongByHL(byte[] b) { public static long toLongByHL(byte[] b) {
return toLongByHL(b, 0); return toLongByHL(b, 0);
...@@ -248,9 +254,9 @@ public class ByteConvertHelper { ...@@ -248,9 +254,9 @@ public class ByteConvertHelper {
/** /**
* 将高字节数组转换为long * 将高字节数组转换为long
* *
* @param b byte[] * @param b 字节
* @param off long * @param off 开始位置
* @return long * @return 转换后的数据
*/ */
public static long toLongByHL(byte[] b, int off) { public static long toLongByHL(byte[] b, int off) {
return toLongByHL(b, off, 8); return toLongByHL(b, off, 8);
...@@ -260,8 +266,8 @@ public class ByteConvertHelper { ...@@ -260,8 +266,8 @@ public class ByteConvertHelper {
/** /**
* 将高字节数组转换为int * 将高字节数组转换为int
* *
* @param b * @param b 字节
* @return * @return 转换后的数据
*/ */
public static int toIntByHL(byte[] b) { public static int toIntByHL(byte[] b) {
return toIntByHL(b, 0); return toIntByHL(b, 0);
...@@ -270,9 +276,9 @@ public class ByteConvertHelper { ...@@ -270,9 +276,9 @@ public class ByteConvertHelper {
/** /**
* 将高字节数组转换为int * 将高字节数组转换为int
* *
* @param b byte[] * @param b 字节
* @param off int * @param off 开始位置
* @return int * @return 转换后的数据
*/ */
public static int toIntByHL(byte[] b, int off) { public static int toIntByHL(byte[] b, int off) {
return (int) toLongByHL(b, off, 4); return (int) toLongByHL(b, off, 4);
...@@ -282,8 +288,8 @@ public class ByteConvertHelper { ...@@ -282,8 +288,8 @@ public class ByteConvertHelper {
/** /**
* 高字节数组到short的转换 * 高字节数组到short的转换
* *
* @param b * @param b 字节
* @return * @return 转换后的数据
*/ */
public static short toShortByHL(byte[] b) { public static short toShortByHL(byte[] b) {
return toShortByHL(b, 0); return toShortByHL(b, 0);
...@@ -292,9 +298,9 @@ public class ByteConvertHelper { ...@@ -292,9 +298,9 @@ public class ByteConvertHelper {
/** /**
* 高字节数组到short的转换 * 高字节数组到short的转换
* *
* @param b * @param b 字节
* @param off * @param off 开始位置
* @return * @return 转换后的数据
*/ */
public static short toShortByHL(byte[] b, int off) { public static short toShortByHL(byte[] b, int off) {
return (short) toLongByHL(b, off, 2); return (short) toLongByHL(b, off, 2);
...@@ -304,8 +310,8 @@ public class ByteConvertHelper { ...@@ -304,8 +310,8 @@ public class ByteConvertHelper {
/** /**
* 高字节数组转换为float * 高字节数组转换为float
* *
* @param b byte[] * @param b 字节
* @return float * @return 转换后的数据
*/ */
public static float toFloatByHL(byte[] b) { public static float toFloatByHL(byte[] b) {
int i = toIntByHL(b); int i = toIntByHL(b);
...@@ -315,8 +321,8 @@ public class ByteConvertHelper { ...@@ -315,8 +321,8 @@ public class ByteConvertHelper {
/** /**
* 获取短整形的字节,高字节在前,低字节在后的byte数组 * 获取短整形的字节,高字节在前,低字节在后的byte数组
* *
* @param value * @param value 需要转换的数据
* @return * @return 转换后的数据
*/ */
public static byte[] getBytes(short value) { public static byte[] getBytes(short value) {
return toHL(value); return toHL(value);
...@@ -325,8 +331,8 @@ public class ByteConvertHelper { ...@@ -325,8 +331,8 @@ public class ByteConvertHelper {
/** /**
* 获取短整形的字节,高字节在前,低字节在后的byte数组 * 获取短整形的字节,高字节在前,低字节在后的byte数组
* *
* @param value * @param value 需要转换的数据
* @return * @return 转换后的数据
*/ */
public static byte[] getBytes(int value) { public static byte[] getBytes(int value) {
return toHL(value); return toHL(value);
...@@ -335,8 +341,8 @@ public class ByteConvertHelper { ...@@ -335,8 +341,8 @@ public class ByteConvertHelper {
/** /**
* 获取短整形的字节,高字节在前,低字节在后的byte数组 * 获取短整形的字节,高字节在前,低字节在后的byte数组
* *
* @param value * @param value 需要转换的数据
* @return * @return 转换后的数据
*/ */
public static byte[] getBytes(long value) { public static byte[] getBytes(long value) {
return toHL(value); return toHL(value);
...@@ -344,6 +350,9 @@ public class ByteConvertHelper { ...@@ -344,6 +350,9 @@ public class ByteConvertHelper {
/** /**
* 将byte数组中的元素倒序排列 * 将byte数组中的元素倒序排列
*
* @param b 需要转换的数据
* @return 转换后的数据
*/ */
public static byte[] bytesReverseOrder(byte[] b) { public static byte[] bytesReverseOrder(byte[] b) {
int length = b.length; int length = b.length;
...@@ -357,8 +366,8 @@ public class ByteConvertHelper { ...@@ -357,8 +366,8 @@ public class ByteConvertHelper {
/** /**
* 将本机的 short 转换成网络上传输支持的 short ,用于多语言通讯时处理, 将 short 类型的值转换为字节序颠倒过来对应的 short 值 * 将本机的 short 转换成网络上传输支持的 short ,用于多语言通讯时处理, 将 short 类型的值转换为字节序颠倒过来对应的 short 值
* *
* @param from * @param from 需要转换的数据
* @return * @return 转换后的数据
*/ */
public static short reverse(short from) { public static short reverse(short from) {
return toShortByHL(toLH(from)); return toShortByHL(toLH(from));
...@@ -367,8 +376,8 @@ public class ByteConvertHelper { ...@@ -367,8 +376,8 @@ public class ByteConvertHelper {
/** /**
* 将本机的 int 转换成网络上传输支持的 int ,用于多语言通讯时处理, 将 int 类型的值转换为字节序颠倒过来对应的 int 值 * 将本机的 int 转换成网络上传输支持的 int ,用于多语言通讯时处理, 将 int 类型的值转换为字节序颠倒过来对应的 int 值
* *
* @param from * @param from 需要转换的数据
* @return * @return 转换后的数据
*/ */
public static int reverse(int from) { public static int reverse(int from) {
return toIntByHL(toLH(from)); return toIntByHL(toLH(from));
...@@ -377,8 +386,8 @@ public class ByteConvertHelper { ...@@ -377,8 +386,8 @@ public class ByteConvertHelper {
/** /**
* 将本机的 long 转换成网络上传输支持的 long ,用于多语言通讯时处理, 将 long 类型的值转换为字节序颠倒过来对应的 long 值 * 将本机的 long 转换成网络上传输支持的 long ,用于多语言通讯时处理, 将 long 类型的值转换为字节序颠倒过来对应的 long 值
* *
* @param from * @param from 需要转换的数据
* @return * @return 转换后的数据
*/ */
public static long reverse(long from) { public static long reverse(long from) {
return toLongByHL(toLH(from)); return toLongByHL(toLH(from));
...@@ -387,68 +396,146 @@ public class ByteConvertHelper { ...@@ -387,68 +396,146 @@ public class ByteConvertHelper {
/** /**
* 将本机的 float 转换成网络上传输支持的 float ,用于多语言通讯时处理, 将 float 类型的值转换为字节序颠倒过来对应的 float 值 * 将本机的 float 转换成网络上传输支持的 float ,用于多语言通讯时处理, 将 float 类型的值转换为字节序颠倒过来对应的 float 值
* *
* @param f float * @param from 需要转换的数据
* @return float * @return 转换后的数据
*/ */
public static float reverse(float f) { public static float reverse(float from) {
float result = toFloatByHL(toLH(f)); return toFloatByHL(toLH(from));
return result;
} }
/** /**
* 将String转为byte数组 * 将字节数组转换为String
*
* @param bytes 需要转换的字节,如 [0x00,0x01]
* @return 返回转换成功的字符串 如: 0001
*/
public static String toHexString(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
String hv = Integer.toHexString(b & 0xff);
if (hv.length() < 2) {
result.append(0);
}
result.append(hv);
}
return result.toString();
}
/**
* 将字节数组转换为String
*
* @param bytes 需要转换的字节,如 [0x00,0x01]
* @return 返回转换成功的字符串 如: 0001
*/
public static String toHexString1(byte[] bytes) {
return toHexString1(bytes, 0, 0);
}
/**
* 将字节数组转换为String
*
* @param bytes 需要转换的字节,如 [0x00,0x01]
* @param offset 偏移量
* @param len 需要转换的长度,当为0时,则默认为整个字符串的长度
* @return 返回转换成功的字符串 如: 0001
*/ */
public static byte[] stringToBytes(String s, int length) { public static String toHexString1(byte[] bytes, int offset, int len) {
while (s.getBytes().length < length) { if (len == 0) {
s += " "; len = bytes.length;
}
StringBuilder sb = new StringBuilder();
for (int i = offset; i < len; i++) {
byte by = bytes[i];
sb.append(String.format("%02X", by));
} }
return s.getBytes(); return sb.toString();
} }
/** /**
* 将字节数组转换为String * 将字节数组转换为String
* *
* @param b byte[] 需要转换的字节,如 [0x00,0x01] * @param from 需要转换的字节,如 0001
* @return String 返回转换成功的字符串 如: 0001 * @return 返回转换成功的字符串 如: [0x00,0x01]
*/ */
public static String bytesToString(byte[] b) { public static byte[] fromHexString(String from) {
StringBuffer result = new StringBuffer(); if (from == null || from.length() < 1) {
int length = b.length; return new byte[0];
}
from = from.toUpperCase().replaceAll(" ", "");
int length = from.length() / 2;
char[] hexChars = from.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
result.append((char) (b[i] & 0xff)); int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
} }
return result.toString(); return d;
} }
/** /**
* 将字符串转换为byte数组 * Convert char to byte
* *
* @param s String * @param c char
* @return byte[] * @return byte
*/ */
public static byte[] stringToBytes(String s) { private static byte charToByte(char c) {
return s.getBytes(); return (byte) "0123456789ABCDEF".indexOf(c);
}
/**
* 将字节数组转换为String
*
* @param from 需要转换的字节,如 0001
* @return 返回转换成功的字符串 如: [0x00,0x01]
*/
public static byte[] fromHexString1(String from) {
byte[] bytes = new byte[from.length() / 2];
for (int i = 0; i < from.length() / 2; i++) {
int b = Integer.parseInt(from.substring(i * 2, i * 2 + 2), 16);
bytes[i] = (byte) b;
}
return bytes;
} }
/** /**
* 将字节转换为字节字符串。如 [0x00,0x01]转成成 00 01 * 将字节转换为字节字符串。如 [0x00,0x01]转成成 00 01
* *
* @param bb * @param bytes 需要转化的数据
* @return * @return 转换后的数据
*/ */
public static String logBytes(byte[] bb) { public static String logBytes(byte[] bytes) {
int length = bb.length; int length = bytes.length;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) { for (byte b : bytes) {
sb.append(bb + " "); sb.append(b);
sb.append(" ");
} }
return sb.toString(); return sb.toString();
} }
// public static void main(String[] args) { /**
// long old = 99L; * 将整形转换为BCD值
// long from = reverse(old); *
// long to = reverse(from); * @param from 需要转换的整形
// System.out.println(String.format("old:%d %d %d", old, from, to)); * @return 转换之后的值
// } */
public static byte toBCD(int from) {
if (from >= 100) {
throw new CodeException("整形转换成字节的PCD码必须小于100");
}
byte bt = (byte) ((from / 10 * 16) + from % 10);
return bt;
}
/**
* 将BCD值转换为整形
*
* @param from 需要转换的BCD值
* @return 转换之后的值
*/
public static int fromBCD(byte from) {
return (from / 16) * 10 + from % 16;
}
} }
package com.yanzuoguang.util.helper;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 将时间格式字符串转换为时间
*/
public class DateAutoHelper {
/**
* 无符号正则表达式
*/
public static final String DATE_FORMAT_NO_SPLIT_REGEX = "^(\\d{4})(\\d{2})(\\d{2})$";
/**
* 有符号正常日期格式
*/
public static final String DATE_FORMAT_COMMON_REGEX = "^(\\d{4,})[/-](\\d{1,2})[/-](\\d{1,2})$";
/**
* 有符号正常日期格式替换
*/
public static final String DATE_FORMAT_COMMON_REPLACE = "$1-$2-$3 00:00:00.000";
/**
* 倒序的日期格式
*/
public static final String DATE_FORMAT_REVERT_REGEX = "^(\\d{1,2})[/-](\\d{1,2})[/-](\\d{4,})$";
/**
* 有符号正常日期格式替换
*/
public static final String DATE_FORMAT_REVERT_REPLACE = "$3-$2-$1 00:00:00.000";
/**
* 正常时间格式
*/
public static final String DATETIME_HOUR_FORMAT_REGEX = "^(\\d{4,})[/-](\\d{1,2})[/-](\\d{1,2}).{1}(\\d{1,2}):(\\d{1,2})$";
/**
* 正常时间格式替换
*/
public static final String DATETIME_HOUR_FORMAT_REPLACE = "$1-$2-$3 $4:$5:00.000";
/**
* 正常时间格式
*/
public static final String DATETIME_FORMAT_REGEX = "^(\\d{4,})[/-](\\d{1,2})[/-](\\d{1,2}).{1}(\\d{1,2}):(\\d{1,2}):(\\d{1,2})$";
/**
* 正常时间格式替换
*/
public static final String DATETIME_FORMAT_REPLACE = "$1-$2-$3 $4:$5:$6.000";
/**
* 时间格式化字符串 yyyy-MM-dd HH:mm:ss.SSS
*/
public static final String DATETIME_FULL_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
/**
* 缓存的自动识别的格式正则表达式
*/
private static List<DateReplace> autoDateCache = new ArrayList<>();
static {
registerAutoFormat(DATE_FORMAT_NO_SPLIT_REGEX, DATE_FORMAT_COMMON_REPLACE);
registerAutoFormat(DATE_FORMAT_COMMON_REGEX, DATE_FORMAT_COMMON_REPLACE);
registerAutoFormat(DATE_FORMAT_REVERT_REGEX, DATE_FORMAT_REVERT_REPLACE);
registerAutoFormat(DATETIME_HOUR_FORMAT_REGEX, DATETIME_HOUR_FORMAT_REPLACE);
registerAutoFormat(DATETIME_FORMAT_REGEX, DATETIME_FORMAT_REPLACE);
}
/**
* 时间格式字符串
*/
private static class DateReplace {
// 正则表达式
public String regex;
// 替换表达式
public String replace;
// 终止标志位
public boolean end;
}
/**
* 注册正则表达式,将时间转换为正确格式的正则表达式,后注册的会优先执行 。
*
* @param regex 正则表达式
* @param replace 替换表达式
*/
public static void registerAutoFormat(String regex, String replace) {
registerAutoFormat(regex, replace, true);
}
/**
* 注册正则表达式,将时间转换为正确格式的正则表达式,后注册的会优先执行 。
*
* @param regex 正则表达式
* @param replace 替换表达式
* @param end 是否需要结束
*/
public static void registerAutoFormat(String regex, String replace, boolean end) {
DateReplace item = new DateReplace();
item.regex = regex;
item.replace = replace;
item.end = end;
autoDateCache.add(item);
}
/**
* 根据时间字符串自动识别时间
*
* @param date 时间字符串
* @return 时间
*/
public static Date getAutoDate(String date) throws ParseException {
if (date == null || date.trim().length() < 1) {
return null;
}
date = date.trim();
int size = autoDateCache.size();
for (int i = size - 1; i >= 0; i--) {
// 遍历所有时间格式
DateReplace item = autoDateCache.get(i);
String dateTo = date.replaceAll(item.regex, item.replace);
// 如何替换成功,且终止标志位为true则终止执行
boolean isBreak = item.end && !dateTo.equals(date);
date = dateTo;
if (isBreak) {
break;
}
}
// 将正常格式的时间字符串转换为时间
return new SimpleDateFormat(DATETIME_FULL_FORMAT).parse(String.valueOf(date));
}
}
package com.yanzuoguang.util.helper;
import com.yanzuoguang.util.exception.CodeException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 日期工具类
*/
public class DateHelper {
private static final String FORMAT_DAY_STRING = "yyyy-MM-dd";
private static final String FORMAT_SECOND_STRING = "yyyy-MM-dd HH:mm:ss";
private static SimpleDateFormat FORMAT_DAY = new SimpleDateFormat(FORMAT_DAY_STRING);
/**
* 获取时间
*
* @param from
* @return
*/
public static Date getDateTime(Object from) {
try {
if (from instanceof Date) {
return (Date) from;
} else if (from == null) {
return null;
}
return DateAutoHelper.getAutoDate(String.valueOf(from));
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return null;
}
/**
* Timestamp 转成 "yyyy-MM-dd HH:mm:ss"字符串
*
* @param date 需要处理的日期
* @return 转换后的字符串
*/
public static String toString(Timestamp date) {
if (date == null) {
return StringHelper.EMPTY;
}
SimpleDateFormat format = new SimpleDateFormat(FORMAT_SECOND_STRING);
return format.format(date);
}
/**
* 取得当前日期对象
*
* @return 返回java.util.Date日期对象
*/
public static Date getCurDate() {
return new Date();
}
/**
* 将指定Date类型转换成指定格式的字符串,格式串参见类注释
*
* @param date 日期方式
* @param format 指定的格式,当format为NULL或空串时,<BR>
* 默认为 yyyy-MM-dd 格式
* @return 当date为NULL时, 返回空串
*/
public static String getDate(Date date, String format) {
if (date == null) {
return StringHelper.EMPTY;
}
if (format == null || format.length() == 0) {
format = "yyyy-MM-dd";
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 获取日期 yyyy-MM-dd
*
* @param date 日期参数
* @return 返回的结果
*/
public static String getYearMonthDay(Date date) {
return getDate(date, FORMAT_DAY_STRING);
}
/**
* 取得当前日期的字符串表示,格式为 yyyy-MM-dd
*
* @return 返回日期的字符串表示
*/
public static String getToday() {
return getYearMonthDay(getCurDate());
}
/**
* 获取年份
*
* @param date 需要处理的日期
* @return 获取到的年份
*/
public static int getYear(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
return c.get(Calendar.YEAR);
}
/**
* 获取月份
*
* @param date 需要处理的日期
* @return 获取到的月份
*/
public static int getMonth(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
return c.get(Calendar.MONTH);
}
/**
* 获取日期
*
* @param date 需要处理的日期
* @return 获取的天数
*/
public static int getDay(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
return c.get(Calendar.DAY_OF_MONTH);
}
/**
* 获取当天的日期
*
* @param date 需要的日期
* @return 返回的日期
*/
public static Calendar getDayCalendarBegin(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
//当前起始日期
Calendar begin = Calendar.getInstance();
begin.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
return begin;
}
/**
* 获取某一天起始和结束时间
*
* @param date 某一天
* @return 返回的日期
*/
public static Date getDayStart(Date date) {
Calendar begin = getDayCalendarBegin(date);
return begin.getTime();
}
/**
* 获取某一天起始和结束时间
*
* @param date 某一天
* @return 返回的日期
*/
public static Date getDayEnd(Date date) {
Calendar end = getDayCalendarBegin(date);
end.add(Calendar.DAY_OF_MONTH, 1);
end.add(Calendar.SECOND, -1);
return end.getTime();
}
/**
* 获取本月开始时间
*
* @param date 某一天
* @return 返回的日期
*/
public static Date getMonthStart(Date date) {
Calendar cal = getDayCalendarBegin(date);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
return cal.getTime();
}
/**
* 获得本月最后一天24点时间
*
* @param date 某一天
* @return 返回的值
*/
public static Date getMonthEnd(Date date) {
Calendar cal = getDayCalendarBegin(date);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
return cal.getTime();
}
/**
* 获取本年开始时间
*
* @param date 某一天
* @return 返回值
*/
public static Date getYearStart(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(cal.get(Calendar.YEAR), 0, 0, 0, 0, 0);
return cal.getTime();
}
/**
* 本季度开始时间
*
* @param date 某一天
* @return 返回值
*/
public static Date getQuarterStart(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
int currentMonth = c.get(Calendar.MONTH) + 1;
SimpleDateFormat longSdf = new SimpleDateFormat(FORMAT_SECOND_STRING);
SimpleDateFormat shortSdf = new SimpleDateFormat(FORMAT_DAY_STRING);
Date now = null;
try {
if (currentMonth >= 1 && currentMonth <= 3)
c.set(Calendar.MONTH, 0);
else if (currentMonth >= 4 && currentMonth <= 6)
c.set(Calendar.MONTH, 3);
else if (currentMonth >= 7 && currentMonth <= 9)
c.set(Calendar.MONTH, 6);
else if (currentMonth >= 10 && currentMonth <= 12)
c.set(Calendar.MONTH, 9);
c.set(Calendar.DATE, 1);
now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
} catch (Exception e) {
e.printStackTrace();
}
return now;
}
/**
* 本季度的结束时间,即2012-03-31 23:59:59
*
* @param date 某一天
* @return 返回值
*/
public static Date getQuarterEnd(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(getQuarterStart(date));
cal.add(Calendar.MONTH, 3);
cal.add(Calendar.MILLISECOND, -1);
return cal.getTime();
}
/**
* 获取当前时间的年、月
*
* @param format 需要的格式
* @return 返回值
*/
public static String geYearMonth(String format) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 获取当前时间的年
*
* @return 当前年份
*/
public static String getCurrentYear() {
Calendar calendar = Calendar.getInstance();
return calendar.get(Calendar.YEAR) + "";
}
/**
* 将时间格式转为yyyy-MM-dd HH:mm:ss格式
*
* @param date 某一天
* @return 返回值
*/
public static String parseToStr(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_SECOND_STRING);
return sdf.format(date);
}
/**
* 判断字符串日期是否为同一天
*
* @param strFrom 对比的某一天
* @param strTo 对比的某一天
* @return 需要的返回值
*/
public static boolean isEqualsDay(String strFrom, String strTo) {
try {
Date dateFrom = DateAutoHelper.getAutoDate(strFrom);
Date dateTo = DateAutoHelper.getAutoDate(strTo);
SimpleDateFormat format = new SimpleDateFormat(FORMAT_DAY_STRING);
return format.format(dateFrom).equals(format.format(dateTo));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 判断两个日期是否为同一年(排除同月同天的情况)
*
* @param dateFrom 对比的某一天
* @param dateTo 对比的某一天
* @return 需要的返回值
*/
public static boolean isEqualsYear(Date dateFrom, Date dateTo) {
SimpleDateFormat format = new SimpleDateFormat("yyyy");
return format.format(dateFrom).equals(format.format(dateTo));
}
/**
* 判断两个日期是否为同一月
*
* @param dateFrom 对比的某一天
* @param dateTo 对比的某一天
* @return 需要的返回值
*/
public static boolean isEqualsMonth(Date dateFrom, Date dateTo) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
return format.format(dateFrom).equals(format.format(dateTo));
}
/**
* 计算两个日期之间相差的天数
*
* @param from 较小的时间
* @param to 较大的时间
* @return 相差天数
*/
public static long betweenDay(Date from, Date to) {
long mill = betweenMillSecond(from, to, FORMAT_DAY_STRING);
return mill / (1000 * 3600 * 24);
}
/**
* 计算两个日期之间相差的秒数
*
* @param from 较小的时间
* @param to 较大的时间
* @return 相差秒数
*/
public static long betweenSecond(Date from, Date to) {
long mill = betweenMillSecond(from, to, FORMAT_SECOND_STRING);
return mill / 1000;
}
/**
* 计算两个时间相差的毫秒数
*
* @param from 开始时间
* @param to 结束时间
* @param format 通过format来确定精度
* @return 相差毫秒数
*/
public static long betweenMillSecond(Date from, Date to, String format) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
from = sdf.parse(sdf.format(from));
to = sdf.parse(sdf.format(to));
Calendar cal = Calendar.getInstance();
cal.setTime(from);
long fromMill = cal.getTimeInMillis();
cal.setTime(to);
long toMill = cal.getTimeInMillis();
long mill = toMill - fromMill;
return mill;
} catch (ParseException ex) {
throw new CodeException(ex);
}
}
/**
* 获取周,从星期1开始,索引号为0
*
* @param dt 传入时间
* @return 星期序号
*/
public static int getWeek(Date dt) {
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
int w = cal.get(Calendar.DAY_OF_WEEK);
if (w < 1) {
w = 1;
}
w = (w + 5) % 7;
return w;
}
/**
* 获取当前日期是星期几<br>
*
* @param dt 传入的时间
* @return 当前日期是星期几
*/
public static String getWeekName(Date dt) {
String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
int w = getWeek(dt);
return weekDays[w];
}
/**
* 根据时间字符串获取对应的周几
*
* @param date 时间字符串
* @return 获取后的结果
*/
public static String getWeekName1(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (week_index < 0) {
week_index = 0;
}
String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
return weeks[week_index];
}
/**
* 增加年份处理
*
* @param date 当前日期
* @param year 需要增加的年份
* @return 增加年份后的值
*/
public static Date addYear(Date date, int year) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.YEAR, year);
return cal.getTime();
}
/**
* 获取当前时间,精准到秒,格式为: yyyy-MM-dd HH:mm:ss
*
* @return 当前时间
*/
public static String getNow() {
return GetDateTimeString(new Date());
}
/**
* 获取时间的字符串,精准到秒,为null则返回空字符串,格式为: yyyy-MM-dd HH:mm:ss
*
* @param date 需要获取的时间
* @return 获取到的结果
*/
public static String GetDateTimeString(Date date) {
return GetDateTimeString(FORMAT_SECOND_STRING, date);
}
/**
* 获取时间为指定格式的字符串,为null则返回空字符串
*
* @param format 格式 yyyy-MM-dd HH:mm:ss
* @param date 字符串
* @return
*/
public static String GetDateTimeString(String format, Date date) {
String to = "";
if (date != null) {
to = new SimpleDateFormat(format).format(date);
}
return to;
}
/**
* 比较时间
*
* @param from 对比时间
* @param to
* @return
*/
public static int compare(Date from, Date to) {
if (from == null && to == null) {
return 0;
} else if (from == null) {
return 1;
} else if (to == null) {
return -1;
} else if (from.getTime() < to.getTime()) {
return 1;
} else if (from.getTime() > to.getTime()) {
return -1;
} else {
return 0;
}
}
/**
* 将时间字符串格式化为 yyyy-MM-dd hh:mm:ss
*
* @param from 需要格式化的字符串
* @return 格式化后的结果
* @throws ParseException 可能抛出不能解释字符串的异常
*/
public static String formatDateString(String from) {
try {
SimpleDateFormat format = new SimpleDateFormat(FORMAT_SECOND_STRING);
Date dt = format.parse(from);
return format.format(dt);
} catch (ParseException e) {
throw new CodeException(e);
}
}
/**
* 判断时间是否在时间段内
*
* @param date 当前时间 yyyy-MM-dd HH:mm:ss
* @param from 开始时间 00:00:00
* @param to 结束时间 00:05:00
* @return
*/
public static boolean isBetween(Date date, String from, String to) {
Date fromDate = getDateTime(GetDateTimeString(FORMAT_DAY_STRING + " " + from, date));
Date toDate = getDateTime(GetDateTimeString(FORMAT_DAY_STRING + " " + to, date));
return date.getTime() >= fromDate.getTime() && date.getTime() <= toDate.getTime();
}
/**
* 获取当前日期
*
* @param from 当前时间 yyyy-MM-dd HH:mm:ss
* @return 返回日期: yyyy-MM-dd
*/
public static String toDay(String from) {
if (StringHelper.isEmpty(from)) {
return from;
}
try {
return FORMAT_DAY.format(FORMAT_DAY.parse(from));
} catch (ParseException e) {
ExceptionHelper.handleException(e, from);
}
return StringHelper.EMPTY;
}
/**
* 获取当前日期字符串
*
* @param date 需要获取的日期
* @return 获取到的日期字符串
*/
public static String toDay(Date date) {
return FORMAT_DAY.format(date);
}
/**
* 获取当前日期
*
* @param date 需要获取的日期
* @return 获取到的日期字符串
*/
public static String toDay(long date) {
return FORMAT_DAY.format(new Date(date));
}
/**
* 获取指定时间月份的第一天
*
* @param time 需要获取的时间
* @return 指定时间月份的第一天
*/
public static String toMonth(Date time) {
return GetDateTimeString("yyyy-MM-01", time);
}
/**
* 获取指定时间年份的第一天
*
* @param time 需要获取的时间
* @return 指定时间年份的第一天
*/
public static String toYear(Date time) {
return GetDateTimeString("yyyy-01-01", time);
}
}
package com.yanzuoguang.util.helper;
import java.lang.reflect.Method;
import java.util.HashMap;
/**
* 字符串和枚举进行转换
*/
public class EnumHelper {
private static HashMap<Class, Method> CacheMethod = new HashMap<>();
public static <T extends Enum<T>> T toEnum(String vStr, T vDefault) {
Class<T> vType = (Class<T>) vDefault.getClass();
T result = vDefault;
try {
if (!StringHelper.isEmpty(vStr)) {
result = Enum.valueOf(vType, vStr);
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, vStr);
}
return result;
}
public static <T> T toEnum(Class<T> vType, String vStr) {
return toEnum(vType, vStr, null);
}
public static <T> T toEnum(Class<T> vType, String vStr, T vDefault) {
T result = vDefault;
try {
if (StringHelper.isInteger(vStr)) {
result = toEnum(vType, StringHelper.toInt(vStr));
} else if (!StringHelper.isEmpty(vStr)) {
result = (T) Enum.valueOf((Class) vType, vStr);
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, vStr);
}
if (result == null && vDefault == null) {
result = toEnum(vType, 0);
}
return result;
}
public static <T> T toEnum(Class<T> vType, int i) {
T result = null;
try {
if (CacheMethod.containsKey(vType)) {
Method met = CacheMethod.get(vType);
result = (T) met.invoke(null, i);
} else {
Method[] vMets = vType.getMethods();
for (Method vMet : vMets) {
String vName = vMet.getName();
if (vName.equals("forValue")
&& vMet.getParameterTypes().length == 1) {
Class vTempType = vMet.getParameterTypes()[0];
Object obj = vMet.invoke(null, i);
result = (T) obj;
CacheMethod.put(vType, vMet);
break;
}
}
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, i);
}
return result;
}
}
package com.yanzuoguang.util.helper;
import java.util.ArrayList;
import java.util.List;
/**
* Java事件处理类
*
* @param <T>
*/
public class Event<T> {
// 事件列表
private List<T> m_List = new ArrayList<>();
/**
* 添加处理对象
*
* @param t
*/
public void add(T t) {
if (t != null) {
m_List.add(t);
}
}
/**
* 触发事件
*
* @param m
* @param <M>
* @throws Exception
*/
public <M extends EventRun<T>> void exeucte(M m) throws Exception {
for (T item : m_List) {
m.Execute(item);
}
}
/**
* 删除某个事件处理类
*
* @param t 需要删除的事件处理类
* @return
*/
public boolean remove(T t) {
if (t != null) {
return m_List.remove(t);
}
return false;
}
/**
* 清除所有事件
*/
public void clear() {
m_List.clear();
}
/**
* 判断是否包含事件
*
* @param t 需要判断的事件
* @return 是否包含
*/
public boolean contants(T t) {
if (t != null) {
return m_List.contains(t);
}
return false;
}
/**
* 获取事件列表
*
* @return 事件列表集合
*/
public List<T> getList() {
return m_List;
}
/**
* 获取事件长度
*
* @return 长度
*/
public int size() {
return m_List.size();
}
}
package com.yanzuoguang.util.helper;
/**
* 执行的时候得事件处理类
*
* @param <T> 需要处理的数据的类型
*/
public interface EventRun<T> {
/**
* 事件的执行主体
*
* @param t 接口
* @throws Exception 异常错误
*/
void Execute(T t) throws Exception;
}
package com.yanzuoguang.util.helper;
/**
* 异常处理帮助类
*/
public class ExceptionHelper {
/**
* 不跑出异常,记录日常日志
*
* @param ex
* @param from
*/
public static void handleException(Throwable ex, Object from) {
// todo: 需要修改
// Log.error(ExceptionHelper.class, ex, StringHelper.toString(from));
}
/**
* 异常信息输出
*
* @param local
* @param start
* @param end
* @param allsize
* @param str
* @throws Exception
*/
public static void subStringException(String local, int start, int end, int allsize, String str) throws Exception {
String exception = local + "/n" + "开始:" + start + " 结束:" + end + "总长:" + allsize + "/n" + str;
throw new Exception(exception);
}
}
package com.yanzuoguang.util.helper;
import com.yanzuoguang.util.exception.CodeException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
/**
* HTTP请求工具类
*/
public class HttpHelper {
/**
* 发送POST请求,当请求失败时,抛出异常或返回空字符串
*
* @param url 目的地址
* @param jsonString 请求参数,json字符串。
* @return 远程响应结果
*/
public static String post(String url, String jsonString) {
try {
// 打开URL连接
java.net.HttpURLConnection httpConn = getConn(url);
return post(httpConn, url, jsonString);
} catch (Exception ex) {
throw new CodeException(ex);
}
}
/**
* 发送POST请求,当请求失败时,抛出异常或返回空字符串
*
* @param url 目的地址
* @param jsonString 请求参数,json字符串。
* @return 远程响应结果
*/
public static String postApplicationJSON(String url, String jsonString) {
try {
// 打开URL连接
java.net.HttpURLConnection httpConn = getConn(url);
httpConn.setRequestProperty("Content-Type", "application/json");
return post(httpConn, url, jsonString);
} catch (Exception ex) {
throw new CodeException(ex);
}
}
/**
* 获取连接
*
* @param url
* @return
* @throws IOException
*/
private static HttpURLConnection getConn(String url) throws IOException {
// 创建URL对象
java.net.URL connURL = new java.net.URL(url);
// 打开URL连接
java.net.HttpURLConnection httpConn = (java.net.HttpURLConnection) connURL.openConnection();
// 设置通用属性
httpConn.setRequestProperty("Accept", "*/*");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
// 设置POST方式
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
return httpConn;
}
/**
* 发送POST请求,当请求失败时,抛出异常或返回空字符串
*
* @param url 目的地址
* @param jsonString 请求参数,json字符串。
* @return 远程响应结果
*/
public static String post(HttpURLConnection httpConn, String url, String jsonString) throws IOException {
String result = "";// 返回的结果
BufferedReader in = null;// 读取响应输入流
PrintWriter out = null;
StringBuffer sb = new StringBuffer();// 处理请求参数
String params = "";
try {
params = jsonString;
// 获取HttpURLConnection对象对应的输出流
out = new PrintWriter(httpConn.getOutputStream());
// 发送请求参数
out.write(params);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应,设置编码方式
in = new BufferedReader(new InputStreamReader(httpConn
.getInputStream(), "UTF-8"));
String line;
// 读取返回的内容
while ((line = in.readLine()) != null) {
result += line;
}
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
return result;
}
}
package com.yanzuoguang.util.helper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
/**
* JSON序列化的处理
* Created by yanzu on 2017/5/28.
*/
public class JSONHelper {
/**
* 将JSON字符串转化为JSON对象
*
* @param json JSON字符串
* @param type 对象的类型
* @param <T> 转换后的结果的类型
* @return 转换后的结果
* @throws Exception 转换结果发生异常
*/
public static <T> T deserialize(String json, Class<T> type) {
return JSON.parseObject(json, type);
}
/**
* 将JSON字符串转化为JSON对象
*
* @param json JSON字符串
* @param type 对象的类型
* @param <T> 转换后的结果的类型
* @return 转换后的结果
* @throws Exception 转换结果发生异常
*/
public static <T> T deserialize(String json, TypeReference<T> type) {
return JSON.parseObject(json, type);
}
/**
* 将JSON字符串转换为数组
*
* @param json 需要转换的JSON
* @param type 转换的类型
* @param <T> 数组的类型
* @return 返回数组
*/
public static <T> T deserializeArray(String json, TypeReference<T> type) {
if (json == null || json.length() < 1) {
return null;
}
json = json.trim();
if (json.startsWith("{")) {
json = String.format("[%s]", json);
}
return JSON.parseObject(json, type);
}
/**
* 将对象序列化成JSON
*
* @param value 需要序列化的对象
* @return JSON结果
* @throws Exception 抛出的异常信息
*/
public static String serialize(Object value) {
return JSON.toJSONString(value);
}
/**
* 将对象序列化成JSON
*
* @param value 需要序列化的对象
* @param isLine 是否需要换行
* @return JSON结果
* @throws Exception 抛出的异常信息
*/
public static String serialize(Object value, boolean isLine) {
return JSON.toJSONString(value, isLine);
}
}
\ No newline at end of file
package com.yanzuoguang.util.helper;
import com.yanzuoguang.util.exception.CodeException;
/**
* 重复执行工具类
*/
public class RunHelper {
/**
* 执行次数
*/
public static int REQ_SIZE = 3;
/**
* 执行次数,并且获取最后一次的异常
*
* @param tag 标记
* @param run 需要执行的函数
* @param sleep 需要沉睡的时间
*/
public static void run(String tag, Runnable run, int sleep) {
run(tag, run, sleep, REQ_SIZE);
}
/**
* 执行次数,并且获取最后一次的异常
*
* @param tag 标记
* @param run 需要执行的函数
* @param sleep 需要沉睡的时间
* @param size 需要执行的次数
*/
public static void run(String tag, Runnable run, int sleep, int size) {
Exception ex = null;
for (int i = 0; i < size; i++) {
try {
run.run();
ex = null;
break;
} catch (Exception e) {
if (i < size) {
ThreadHelper.sleep(sleep); // 间隔100ms,防止服务器重启时请求失败
}
ex = e;
}
}
if (ex != null) {
throw new CodeException(tag + ex.getMessage(), ex);
}
}
}
package com.yanzuoguang.util.helper;
import com.yanzuoguang.util.exception.CodeException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* 字符串帮主类
*/
@SuppressWarnings("unused")
public class StringHelper {
/**
* 空字符串常量
*/
public static final String EMPTY = "";
//------------------------------------------------------ 空值判断和处理 -----------------------------------------------------------------------
/**
* 检测字符是否为空
*
* @param p 需要检测的字符
* @return 检测结果
*/
public static boolean isEmptyChar(char p) {
if (p == '\r'
|| p == '\n'
|| p == '\t'
|| p == ' ') {
return true;
}
return false;
}
/**
* 判断传入的字符串是否为空
*
* @param froms 需要检测的字符串
* @return 是否为空
*/
public static boolean isEmpty(Object... froms) {
for (Object from : froms) {
boolean isEmpty = from == null || from.toString().length() < 1;
if (isEmpty) {
return isEmpty;
}
}
return false;
}
/**
* 判断字符串是否为空
*
* @param from 来源数据
* @return 是否为空
*/
public static boolean isEmpty(String from) {
return from == null || from.length() < 1;
}
/**
* 获取空字符串
*
* @param str
* @return
*/
public static String getEmpty(Object str) {
if (isEmpty(str)) {
return "";
}
return str.toString();
}
/**
* 传入很多字符串,获取第一个非空的字符串,至少需要两个参数
*
* @param from0 第一个参数
* @param froms 参数列表
* @return 第一个非空字符串
*/
public static String getFirst(String from0, String... froms) {
if (!isEmpty(from0)) {
return from0;
}
for (String from : froms) {
if (!isEmpty(from)) {
return from;
}
}
return EMPTY;
}
//------------------------------------------------------ 转换值 -----------------------------------------------------------------------
/**
* 类型匹配
*
* @param type 类型
* @param vBase 类型的名称
* @return 读取的结果
*/
public static boolean isType(Class<?> type, Class<?> vBase) {
if (type == null) {
return false;
} else if (type.equals(vBase)) {
return true;
}
if (type.toString().equals("System.Object")) {
return false;
} else {
return isType(type.getSuperclass(), vBase);
}
}
/**
* 根据类型来获取值
*
* @param cls 类型
* @param from 对象
* @return 返回获取的值
*/
public static <T> T to(Class<T> cls, T from) {
String vName = cls.getName();
Object to = null;
if (cls.isEnum()) {
String strValue = toString(from);
to = EnumHelper.toEnum(cls, strValue);
} else if (isType(cls, String.class)) {
to = toString(from);
} else if ("boolean".equals(vName) || isType(cls, Boolean.class)) {
String strValue = toString(from);
to = toBoolean(strValue);
} else if ("int".equals(vName) || isType(cls, Integer.class)) {
to = toInt(from);
} else if ("double".equals(vName) || isType(cls, Double.class)) {
to = toDouble(from);
} else if ("float".equals(vName) || isType(cls, Float.class)) {
to = toDouble(from);
} else if (isType(cls, Double.class)) {
to = toDecimal(from);
} else if (isType(cls, Date.class)) {
to = DateHelper.getDateTime(from);
}
if (to != null) {
return (T) to;
}
return from;
}
/**
* 将 object 转换为String
*
* @param obj 需要转换的object
* @return 转换成功的字符串
*/
public static String toString(Object obj) {
return obj == null ? null : obj.toString();
}
/**
* 将字符串转换为 bool ,当不能转换时,则默认为false
*
* @param from 需要转换的字符串
* @param defValue 默认值
* @return 转换成功后的值
*/
public static boolean toBoolean(Object from, boolean defValue) {
boolean result = defValue;
try {
if (!isEmpty(from)) {
result = (!compare(from, "0", true)
&& !compare(from, "false", true)
&& !compare(from, "no", true)
&& !isEmpty(from));
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将字符串转换为 bool ,当不能转换时,则默认为false
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static boolean toBoolean(Object from) {
return toBoolean(from, false);
}
/**
* 将字符串转换为 Int,当不能转换时,则默认为0
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static short toShort(Object from) {
short result = 0;
try {
if (!isEmpty(from)) {
result = Short.parseShort(from.toString());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将字符串转换为 Int,当不能转换时,则默认为0
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static int toInt(Object from) {
int result = 0;
try {
if (!isEmpty(from)) {
// String类型的小数转int会出错
result = Integer.parseInt(from.toString());
}
} catch (Exception ex) {
try {
double d = Double.parseDouble(from.toString());
int i = (int) d;
result = Integer.parseInt(String.valueOf(i));
} catch (Exception e) {
ExceptionHelper.handleException(ex, from);
}
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将字符串转换为 long,当不能转换时,则默认为0
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static long toLong(Object from) {
long result = 0;
try {
if (!isEmpty(from)) {
result = Long.parseLong(from.toString());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将字符串转换为 long,当不能转换时,则默认为0
*
* @param from 需要转换的字节数组
* @return 转换成功后的值
*/
public static long toLong(byte[] from) {
if (from.length > 0) {
return ByteHelper.toLongByLH(from);
}
return 0L;
}
/**
* 将字符串转换为 Float,当不能转换时,则默认为0
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static float toFloat(Object from) {
float result = 0;
try {
if (!isEmpty(from)) {
result = Float.parseFloat(from.toString());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将字符串转换为 Double,当不能转换时,则默认为0
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static double toDouble(Object from) {
double result = 0.0;
try {
if (!isEmpty(from)) {
result = Double.parseDouble(from.toString());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将字符串转换为Decimal,当不能转换时,则默认值为0
*
* @param from 需要转换的字符串
* @return 转换成功后的值
*/
public static double toDecimal(Object from) {
Double result = new Double(0);
try {
if (!isEmpty(from)) {
result = new Double(from.toString());
}
} catch (Exception ex) {
ExceptionHelper.handleException(ex, from);
}
return result;
}
/**
* 将对象转换为价格,空值用'-'表示
*
* @param from 需要转换的价格
* @return 价格字符串
*/
public static String toPrice(Object from) {
String str = "-";
if (!isEmpty(from) && toDouble(from) != 0) {
str = "" + toDouble(from);
}
return str;
}
//------------------------------------------------------ 字符串编码 -----------------------------------------------------------------------
/**
* 使用Unicode转码
*
* @param str
* @return
*/
public static String encoding(String str) {
return encoding("UTF-8", str);
}
/**
* 字符串编码转换
*
* @param charset 输入字符串
* @param from 输入字符串
* @return
*/
public static String encoding(String charset, String from) {
byte[] buff;
try {
buff = from.getBytes(charset);
from = new String(buff); // 将字节流转换为字符串
from = from.replace("\0", "").replace("\n", "");
} catch (UnsupportedEncodingException e) {
ExceptionHelper.handleException(e, from);
}
return from;
}
//------------------------------------------------------ 常用函数 -----------------------------------------------------------------------
/**
* 将字符串进行分割
*
* @param from 需要分割的字符串
* @param regex 分割的正则表达式
* @return 分割后的字符串
*/
public static String[] split(String from, String regex) {
return from.split(regex);
}
/**
* 将 list 转换为字符串
*
* @param list
* @return
*/
public static String join(Object... list) {
return join(Arrays.asList(list));
}
/**
* 将 list 转换为字符串
*
* @param list 需要处理的字符串列表
* @return 处理后的字符串
*/
public static String join(List list) {
StringBuilder sb = new StringBuilder();
for (Object item : list) {
if (item == null) {
continue;
}
String to = item.toString();
if (isEmpty(to)) {
continue;
}
if (sb.length() > 0) {
sb.append(",");
}
sb.append(to);
}
return sb.toString();
}
/**
* 去掉两边的空格
*
* @param from 需要去掉空格的字符串
* @return 去掉字符串的值
*/
public static String trim(String from) {
if (from == null) {
return EMPTY;
}
return from.trim();
}
/**
* 去掉左边的字符串
*
* @param from
* @param left
* @return
*/
public static String trimLeft(String from, String... left) {
int pos = 0;
boolean isHandle;
do {
isHandle = false;
for (String item : left) {
int size = item.length();
if (from.indexOf(item, pos) == pos) {
isHandle = true;
pos += size;
continue;
}
}
} while (isHandle);
if (pos > 0) {
return from.substring(pos);
} else {
return from;
}
}
/**
* 对比字符串是否相等,不区分大小写
*
* @param from 第一个字符串
* @param to 第二个字符串
* @return 相等时返回true
*/
public static boolean compare(String from, String to) {
return compare(from, to, false);
}
/**
* 比较两个字符串是否相等
*
* @param from 字符串1
* @param to 字符串2
* @param ignoreCase 是否区分大小写
* @return 比较结果
*/
public static boolean compare(String from, String to, boolean ignoreCase) {
if (from == null && to == null) {
return true;
} else if (from == null || to == null) {
return false;
} else if (from.length() != to.length()) {
return false;
} else if (ignoreCase) {
return from.compareToIgnoreCase(to) == 0;
} else {
return from.compareTo(to) == 0;
}
}
/**
* 比较两个对象转换为字符串是否相等
*
* @param from 字符串1
* @param to 字符串2
* @param ignoreCase 是否区分大小写
* @return 比较结果
*/
public static boolean compare(Object from, Object to, boolean ignoreCase) {
String fromStr = toString(from);
String toStr = toString(to);
return compare(fromStr, toStr, ignoreCase);
}
//------------------------------------------------------ 转换值 -----------------------------------------------------------------------
/**
* 计算分页数量
*
* @param count 数据条数
* @param size 每页大小
* @return
*/
public static int getPage(int count, int size) {
if (size != 0) {
return count / size + (count % size > 0 ? 1 : 0);
}
return 0;
}
/**
* 将字符串转换为菜单
*
* @param args 需要获取的路径,会自动剔除空字符串 ["a" ,"b" ]
* @return 获取到的路径, 结果为 a => b
*/
public static String getGo(String... args) {
StringBuilder sb = new StringBuilder();
for (String arg : args) {
if (isEmpty(arg)) {
continue;
}
if (sb.length() > 0) {
sb.append(" => ");
}
sb.append(arg);
}
return sb.toString();
}
/**
* 判断字符串是否是整数
*/
public static boolean isInteger(String value) {
try {
Integer.parseInt(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
/**
* 获取UUID
*
* @return
*/
public static String getUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 获取主键
*
* @return
*/
public static String getNewID() {
String tag = String.format("z%012d", new Date().getTime() / 1000);
String id = getUUID();
return tag + id.substring(tag.length());
}
/**
* MD5加密
*
* @param string 源字符串
* @return 加密后的字符串
*/
public static String md5(String string) {
byte[] hash = null;
try {
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10)
hex.append("0");
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
/**
* MD5加密
*
* @param from 需要加密的字符串
* @return 加密的结果
*/
public static String md51(String from) {
String to = from;
try {
// 生成实现指定摘要算法的 MessageDigest 对象。
MessageDigest md = MessageDigest.getInstance("MD5");
// 使用指定的字节数组更新摘要。
md.update(from.getBytes());
// 通过执行诸如填充之类的最终操作完成哈希计算。
byte b[] = md.digest();
// 生成具体的md5密码到buf数组
int i;
StringBuilder buf = new StringBuilder();
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
to = buf.toString();
// Log.info(class, "32位: " + buf.toString());// 32位的加密
// Log.info(class, "16位: " + buf.toString().substring(8, 24));// 16位的加密,其实就是32位加密后的截取
} catch (Exception e) {
ExceptionHelper.handleException(e, from);
}
return to;
}
/**
* 获取组合编号的MD5值
*
* @param froms 需要组合的编号
* @return MD5后的值
*/
public static String getNewMD5Id(Date date, Object... froms) {
if (date == null) {
throw new CodeException("生成时间搓 MD5 ID 时,时间不能为空");
}
String tag = String.format("z%012d", date.getTime() / 1000);
String id = md51(getId(froms));
return tag + id.substring(tag.length());
}
/**
* 获取组合编号的MD5值
*
* @param date 需要组合的编号
* @param args 需要组合的编号
* @return MD5后的值
*/
public static String getNewIdMD5(Date date, Object... args) {
return getNewMD5Id(date, args);
}
/**
* 获取组合编号的MD5值
*
* @param froms 需要组合的编号
* @return MD5后的值
*/
public static String getMD5Id(Object... froms) {
return md51(getId(froms));
}
/**
* 获取组合编号的MD5值
*
* @param froms 需要组合的编号
* @return MD5后的值
*/
public static String getIdMD5(Object... froms) {
return getMD5Id(froms);
}
/**
* 获取组合编号
*
* @param args 需要组合的编号
* @return 将ID列表进行组合生成ID
*/
public static String getId(Object... args) {
StringBuilder sb = new StringBuilder();
for (Object arg : args) {
if (sb.length() > 0) {
sb.append(":");
}
sb.append(arg);
}
return sb.toString();
}
/**
* 获取组合的SQL语句
*
* @param froms SQL语句
* @return
*/
public static String getSql(String... froms) {
StringBuilder sb = new StringBuilder();
for (String sql : froms) {
if (isEmpty(sql)) {
continue;
}
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(sql.trim());
}
return sb.toString();
}
}
package com.yanzuoguang.util.helper;
import java.util.ArrayList;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadHelper {
private static Object _ThreadLock = new Object();
private static boolean _ThreadIsRun = false;
private static Date _ThreadDate = null;
private static ExecuteRun Timeout;
private static ExecuteRun Interval;
private static void InitStatic() {
_ThreadDate = StringHelper.GetDateTime("1987-11-04");
Timeout = new ExecuteRun();
Interval = new ExecuteRun();
ThreadDelegateCode vAdd = new ThreadDelegateCode() {
public void Execute() {
OnExecuteAdd();
}
};
ThreadDelegateCode vItemAdd = new ThreadDelegateCode() {
public void Execute() {
OnItemExecuted();
}
};
Timeout.OnAdd.Add(vAdd);
Timeout.OnItemExecuted.Add(vItemAdd);
Interval.OnAdd.Add(vAdd);
Interval.OnItemExecuted.Add(vItemAdd);
StartMonitor();
}
// #region 内部累
private static class ExecuteData {
public Date Date;
public double ExecuteCount;
public double ExecuteError; // 调试变量
public String Flag;
public int Time;
public ThreadDelegateCode Execute;
public ExecuteData() {
this.Date = new Date();
}
}
public static class ExecuteRun {
private Object m_Lock = new Object();
private ArrayList<ExecuteData> m_List = new ArrayList<ExecuteData>();
private Event<ThreadDelegateCode> OnAdd = new Event<ThreadDelegateCode>();
private Event<ThreadDelegateCode> OnRemove = new Event<ThreadDelegateCode>();
private Event<ThreadDelegateCode> OnItemExecuted = new Event<ThreadDelegateCode>();
private Event<ThreadDelegateCode> OnExecuted = new Event<ThreadDelegateCode>();
public Event<ThreadDelegateCode> GetOnAdd() {
return OnAdd;
}
public Event<ThreadDelegateCode> GetOnRemove() {
return OnRemove;
}
public Event<ThreadDelegateCode> GetOnItemExecuted() {
return OnItemExecuted;
}
public Event<ThreadDelegateCode> GetOnExecuted() {
return OnExecuted;
}
/**
* 执行完任务后,是否需要删除该任务,并且设置允许执行的最大错误
*
* @param vIsRemove
* @param vMaxError
*/
public final void Execute(boolean vIsRemove, int vMaxError) {
for (int i = m_List.size() - 1; i >= 0; i--) {
Date vNow = new Date();
ExecuteData vItem = null;
synchronized (this.m_Lock) {
vItem = m_List.size() > i ? m_List.get(i) : null;
}
if (vItem == null) {
continue;
}
double vMillseconds = 0;
// 在Window CE中时间相减可能会出错
try {
// 处理非法改动时间
if (vItem.Date.compareTo(vNow) > 0) {
vItem.Date = vNow;
}
vMillseconds = (vNow.getTime() - vItem.Date.getTime());
} catch (Exception ex) {
Log.error(ThreadHelper.class, ex);
}
// 未到执行时间
if (vMillseconds <= vItem.Time) {
continue;
}
if (vMaxError == -1 || vItem.ExecuteError < vMaxError) {
try {
vItem.ExecuteCount++;
vItem.ExecuteError++;
vItem.Execute.Execute();
vItem.ExecuteError = 0;
this.ExecuteEvent(this.OnItemExecuted);
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
vItem.Date = new Date();
}
try {
if (vIsRemove) {
synchronized (this.m_Lock) {
this.m_List.remove(i);
this.ExecuteEvent(this.OnRemove);
}
}
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
}
this.ExecuteEvent(this.OnExecuted);
}
/**
* 设置需要执行的任务
*
* @param vExecute 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public final String Set(ThreadDelegateCode vExecute, int vTime) {
ExecuteData tempVar = new ExecuteData();
tempVar.Flag = StringHelper.
tempVar.Execute = vExecute;
tempVar.Time = vTime;
ExecuteData vData = tempVar;
synchronized (m_Lock) {
m_List.add(vData);
}
this.ExecuteEvent(this.OnAdd);
return vData.Flag;
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public final void Clear(String flag) {
synchronized (m_Lock) {
for (ExecuteData item : this.m_List) {
if (item.Flag.equals(flag)) {
this.m_List.remove(item);
this.ExecuteEvent(this.OnRemove);
break;
}
}
}
}
/**
* 清除需要执行的任务
*
* @param vExecute 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public final void Clear(ThreadDelegateCode vExecute) {
synchronized (m_Lock) {
for (ExecuteData item : this.m_List) {
if (item.Execute == vExecute) {
this.m_List.remove(item);
this.ExecuteEvent(this.OnRemove);
break;
}
}
}
}
private void ExecuteEvent(Event<ThreadDelegateCode> vExecute) {
try {
if (vExecute != null) {
vExecute.Exeucte(new ThreadDelegateCodeExecute());
}
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
}
public final int getCount() {
return this.m_List.size();
}
}
private static void OnItemExecuted() {
_ThreadDate = new Date();
}
private static void OnExecuteAdd() {
StartThread();
}
private static void StartThread() {
synchronized (_ThreadLock) {
if (_ThreadIsRun) {
return;
}
RunThread(new ThreadDelegateCode() {
public void Execute() throws Exception {
_ThreadIsRun = true;
while (_ThreadIsRun) {
try {
Timeout.Execute(true, -1);
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
try {
Interval.Execute(false, -1);
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
if (Timeout.getCount() == 0 && Interval.getCount() == 0) {
break;
}
Thread.sleep(10);
}
_ThreadIsRun = false;
}
});
}
}
static {
// InitStatic();
}
/**
* 监控线程的方法,防止线程执行死机
*/
private static void StartMonitor() {
RunThread(new ThreadDelegateCode() {
public void Execute() throws Exception {
do {
if (_ThreadIsRun && ((new Date().getTime() - _ThreadDate.getTime()) / 1000) > 5) {
try {
if (_ThreadIsRun) {
_ThreadIsRun = false;
}
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
_ThreadIsRun = false;
StartThread();
}
Thread.sleep(1000 * 60);
} while (true);
}
});
}
/**
* 多少毫秒后执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vFrom
* 需要执行的窗体
* @param vExecute
* 需要执行的程序
* @param vTime
* 间隔时间
* @return 执行标志
*/
// public static String SetTimeout(Form vForm, ThreadDelegateCode vExecute,
// int vTime)
// {
// return Timeout.Set(vForm, vExecute, vTime);
// }
/**
* 多少毫秒后执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vExecute 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public static String SetTimeout(ThreadDelegateCode vExecute, int vTime) {
return Timeout.Set(vExecute, vTime);
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public static void ClearTimeout(String flag) {
Timeout.Clear(flag);
}
/**
* 清除需要执行的任务
*
* @param vExecute 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public static void ClearTimeout(ThreadDelegateCode vExecute) {
Timeout.Clear(vExecute);
}
/**
* 每隔多少毫秒执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vFrom
* 需要执行的窗体
* @param vExecute
* 需要执行的程序
* @param vTime
* 间隔时间
* @return 执行标志
*/
// public static String SetInterval(Form vForm, ThreadDelegateCode vExecute,
// int vTime)
// {
// return Interval.Set(vForm, vExecute, vTime);
// }
/**
* 每隔多少毫秒执行任务,适用于执行时间短,不需要单独开线程的程序
*
* @param vExecute 需要执行的程序
* @param vTime 间隔时间
* @return 执行标志
*/
public static String SetInterval(ThreadDelegateCode vExecute, int vTime) {
return Interval.Set(vExecute, vTime);
}
/**
* 清除需要执行的任务
*
* @param flag 执行标志
*/
public static void ClearInterval(String flag) {
Interval.Clear(flag);
}
/**
* 清除需要执行的任务
*
* @param vExecute 执行的方法,注意有多个同样的方法时,只会清除第一个
*/
public static void ClearInterval(ThreadDelegateCode vExecute) {
Interval.Clear(vExecute);
}
public static void Sleep(int p) {
try {
Thread.sleep(p);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void ExecuteCatch(ThreadDelegateCode vExecute) {
try {
vExecute.Execute();
} catch (Exception ex) {
ex.printStackTrace();
Log.error(ThreadHelper.class,ex);
}
}
private static ExecutorService _ExecuteService = Executors.newCachedThreadPool();
public static void RunThread(final ThreadDelegateCode vExecute) {
_ExecuteService.execute(new Runnable() {
@Override
public void run() {
ExecuteCatch(vExecute);
}
});
}
public static void RunThread(final RunInterval vInterval) {
RunThread(new ThreadDelegateCode() {
public void Execute() throws Exception {
while (!vInterval.getBreak()) {
try {
vInterval.getCode().Execute();
} catch (Exception ex) {
Log.error(ThreadHelper.class,ex);
}
Thread.sleep(vInterval.getTime());
}
}
});
}
public static void sleep(long timer) {
try {
Thread.sleep(timer);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
package com.yanzuoguang.util.helper.table;
import java.util.ArrayList;
import java.util.List;
/**
* 表格头
*/
public class TableHead {
/**
* 构造函数
*/
public TableHead() {
this.TotalColumn = 0;
this.TotalRow = 0;
this.DataColumn = 0;
this.Columns = new ArrayList<>();
}
/**
* 总行数
*/
private int TotalRow;
/**
* 总列数
*/
private int TotalColumn;
/**
* 已添加数据列
*/
private int DataColumn;
/**
* 列头数
*/
private List<TableHeadItem> Columns;
public int getTotalRow() {
return TotalRow;
}
public void setTotalRow(int totalRow) {
TotalRow = totalRow;
}
public int getTotalColumn() {
return TotalColumn;
}
public void setTotalColumn(int totalColumn) {
TotalColumn = totalColumn;
}
public int getDataColumn() {
return DataColumn;
}
public void setDataColumn(int dataColumn) {
DataColumn = dataColumn;
}
public List<TableHeadItem> getColumns() {
return Columns;
}
public void setColumns(List<TableHeadItem> columns) {
Columns = columns;
}
}
package com.yanzuoguang.util.helper.table;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 表头计算
*/
public class TableHeadHelper {
/**
* 列头函数
*
* @param columns 计算列头
* @return 返回计算结果
*/
public static TableHead getTableHead(String... columns) {
TableHead head = new TableHead();
head.setTotalColumn(columns.length);
// 父子级别关系映射
Map<String, TableHeadItem> mapHead = new LinkedHashMap<String, TableHeadItem>();
// 当前节点的子节点元素
Map<String, List<TableHeadItem>> mapSub = new LinkedHashMap<String, List<TableHeadItem>>();
// 最顶层的元素
Map<String, TableHeadItem> mapTop = new LinkedHashMap<String, TableHeadItem>();
for (String column : columns) {
TableHeadItem item = setHead(mapHead, mapSub, mapTop, column);
// 设置表格的最大行数
head.setTotalRow(Math.max(item.getLevel(), head.getTotalRow()));
}
// 计算合并行的数量,第几行
for (Map.Entry<String, TableHeadItem> item : mapHead.entrySet()) {
setCellRow(head, item.getValue());
}
// 计算列合并的数量,第几列
for (Map.Entry<String, TableHeadItem> item : mapTop.entrySet()) {
setCellColumn(head, mapSub, item.getValue());
}
return head;
}
private static TableHeadItem setHead(Map<String, TableHeadItem> mapHead, Map<String, List<TableHeadItem>> mapSub,
Map<String, TableHeadItem> mapTop, String columnFrom) {
String[] columns = columnFrom.split(":");
StringBuilder path = new StringBuilder();
TableHeadItem last = null;
for (int i = 0; i < columns.length; i++) {
// 列名称
String column = columns[i];
// 父路径与当前节点路径
String parentPath = path.toString();
if (i > 0) {
path.append(":");
}
path.append(column);
String nowPath = path.toString();
last = new TableHeadItem();
last.setName(column);
last.setPath(nowPath);
last.setLevel(i + 1);
last.setDataColumn(columnFrom.equals(nowPath));
if (i == 0 && !mapTop.containsKey(nowPath)) {
mapTop.put(nowPath, last);
}
// 添加到最顶层元素中
if (!mapSub.containsKey(parentPath)) {
mapSub.put(parentPath, new ArrayList<TableHeadItem>());
}
// 将元素添加到当前元素中
if (!mapHead.containsKey(nowPath)) {
mapHead.put(nowPath, last);
// 添加到父级元素的下级元素
mapSub.get(parentPath).add(last);
}
last = mapHead.get(nowPath);
last.setLevelMax(Math.max(last.getLevelMax(), columns.length));
}
return last;
}
private static void setCellRow(TableHead head, TableHeadItem value) {
// 合并行数量
int rowCell = head.getTotalRow() - value.getLevelMax() + 1;
value.setRow(value.getLevel());
value.setRowCell(1);
// 计算第几行,合并几行
if (value.getLevel() == 1) {
// 第一行的规则
if (value.getLevelMax() == 1) {
value.setRowCell(rowCell);
}
} else if (value.getLevel() == value.getLevelMax()) {
// 最后一行的规则
if (value.getLevelMax() == 2) {
value.setRowCell(rowCell);
} else {
value.setRow(head.getTotalRow());
}
} else {
// 其他行
if (value.getLevel() == value.getLevelMax() - 1) {
value.setRowCell(rowCell);
}
}
}
private static void setCellColumn(TableHead head, Map<String, List<TableHeadItem>> mapSub, TableHeadItem value) {
// 设置当前列号
value.setColumn(head.getDataColumn() + 1);
// 设置默认合并单元格数量
value.setColumnCell(1);
// 将列添加到当前列集合中
head.getColumns().add(value);
// 计算合并几列
if (value.isDataColumn()) {
head.setDataColumn(head.getDataColumn() + 1);
}
// 假如有子节点,则合并的单元格等于子节点的想加
List<TableHeadItem> subColumns = mapSub.containsKey(value.getPath()) ?
mapSub.get(value.getPath()) : new ArrayList<TableHeadItem>();
if (subColumns != null && subColumns.size() > 0) {
value.setColumnCell(0);
for (TableHeadItem subColumn : subColumns) {
setCellColumn(head, mapSub, subColumn);
value.setColumnCell(subColumn.getColumnCell());
}
}
}
}
package com.yanzuoguang.util.helper.table;
/**
* 列头
*/
public class TableHeadItem {
/**
* 最高级别
*/
private String Name;
/**
* 路径
*/
private String Path;
/**
* 级别
*/
private int Level;
/**
* 当前列的最大级别
*/
private int LevelMax;
/**
* 第几行
*/
private int Row;
/**
* 合并多少行
*/
private int RowCell;
/**
* 第几列
*/
private int Column;
/**
* 合并多少列
*/
private int ColumnCell;
/**
* 是否属于数据列
*/
private boolean dataColumn;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getPath() {
return Path;
}
public void setPath(String path) {
Path = path;
}
public int getLevel() {
return Level;
}
public void setLevel(int level) {
Level = level;
}
public int getLevelMax() {
return LevelMax;
}
public void setLevelMax(int levelMax) {
LevelMax = levelMax;
}
public int getRow() {
return Row;
}
public void setRow(int row) {
Row = row;
}
public int getRowCell() {
return RowCell;
}
public void setRowCell(int rowCell) {
RowCell = rowCell;
}
public int getColumn() {
return Column;
}
public void setColumn(int column) {
Column = column;
}
public int getColumnCell() {
return ColumnCell;
}
public void setColumnCell(int columnCell) {
ColumnCell = columnCell;
}
public boolean isDataColumn() {
return dataColumn;
}
public void setDataColumn(boolean dataColumn) {
dataColumn = dataColumn;
}
}
...@@ -21,6 +21,6 @@ ...@@ -21,6 +21,6 @@
// */ // */
// @Override // @Override
// public String toString() { // public String toString() {
// return JSONHelper.SerializeObject(this); // return JSONHelper.serialize(this);
// } // }
//} //}
package helper;
import com.yanzuoguang.util.helper.ByteHelper;
import org.junit.Assert;
import org.junit.Test;
public class TestByteHelper {
@Test
public void test() {
long from = 0x0f0f;
// from = 1999;
System.out.println(from);
System.out.println(ByteHelper.reverse(from));
System.out.println(ByteHelper.reverse(ByteHelper.reverse(from)));
System.out.println(ByteHelper.toHexString(ByteHelper.toHL(from)));
System.out.println(ByteHelper.toHexString(ByteHelper.toHL(from)));
System.out.println(ByteHelper.toHexString(ByteHelper.toLH(from)));
System.out.println(ByteHelper.toLongByHL(ByteHelper.toHL(from)));
System.out.println(ByteHelper.toLongByLH(ByteHelper.toLH(from)));
}
@Test
public void test1() {
long old = 1999;
old = 0x0f0f;
long from = ByteHelper.reverse(old);
long to = ByteHelper.reverse(from);
Assert.assertEquals(old, to);
System.out.println(String.format("old:%d %d %d", old, from, to));
}
}
package helper;
import com.yanzuoguang.util.helper.DateAutoHelper;
import org.junit.Assert;
import org.junit.Test;
import java.text.ParseException;
public class TestDateAutoHelper {
@Test
public void testGetAutoDate() throws ParseException {
Assert.assertEquals("Wed Nov 04 00:00:00 CST 1987", "Wed Nov 04 00:00:00 CST 1987");
Assert.assertEquals("Wed Nov 04 00:00:00 CST 1987", DateAutoHelper.getAutoDate("1987-11-04").toString());
Assert.assertEquals("Wed Nov 04 12:50:00 CST 1987", DateAutoHelper.getAutoDate("1987-11-04 12:50").toString());
Assert.assertEquals("Wed Nov 04 12:50:15 CST 1987", DateAutoHelper.getAutoDate("1987-11-04 12:50:15").toString());
Assert.assertEquals("Wed Nov 04 12:50:15 CST 1987", DateAutoHelper.getAutoDate("1987-11-04 12:50:15.000").toString());
Assert.assertEquals("Wed Nov 04 00:00:00 CST 1987", DateAutoHelper.getAutoDate("19871104").toString());
Assert.assertEquals("Wed Nov 04 00:00:00 CST 1987", DateAutoHelper.getAutoDate("04/11/1987").toString());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment