重构代码
diff --git a/common/build.gradle b/common/build.gradle
new file mode 100644
index 0000000..c5ae67d
--- /dev/null
+++ b/common/build.gradle
@@ -0,0 +1,14 @@
+plugins {
+ id 'java'
+}
+
+dependencies {
+ implementation 'org.slf4j:slf4j-parent:1.7.26'
+ implementation 'org.slf4j:slf4j-api:1.7.26'
+ implementation 'javax.validation:validation-api:2.0.1.Final'
+
+ compileOnly 'org.projectlombok:lombok:1.18.8'
+ annotationProcessor 'org.projectlombok:lombok:1.18.8'
+
+ implementation 'org.apache.commons:commons-lang3:3.9'
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/APIRequestParam.java b/common/src/main/java/com/supwisdom/dlpay/api/APIRequestParam.java
new file mode 100644
index 0000000..75eadc6
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/APIRequestParam.java
@@ -0,0 +1,165 @@
+package com.supwisdom.dlpay.api;
+
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.beans.Introspector;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
+public abstract class APIRequestParam {
+ @Sign
+ private String sign;
+ @Sign
+ private String sign_type;
+ @Sign
+ private String version;
+
+ private static final Logger logger = LoggerFactory.getLogger(APIRequestParam.class);
+
+ public String getSign() {
+ return sign;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getSign_type() {
+ return sign_type;
+ }
+
+ public void setSign_type(String sign_type) {
+ this.sign_type = sign_type;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ private String createLinkString(Map<String, String> params) {
+
+ List<String> keys = new ArrayList<String>(params.keySet());
+ Collections.sort(keys);
+
+ String prestr = "";
+
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+
+ if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
+ prestr = prestr + key + "=" + value;
+ } else {
+ prestr = prestr + key + "=" + value + "&";
+ }
+ }
+
+ return prestr;
+ }
+
+ private Map<String, String> paraFilter(Map<String, String> sArray) {
+ Map<String, String> result = new HashMap<String, String>();
+ if (sArray == null || sArray.size() <= 0) {
+ return result;
+ }
+ for (String key : sArray.keySet()) {
+ String value = sArray.get(key);
+ if (null == value || "".equals(value.trim())
+ || "null".equalsIgnoreCase(value.trim())
+ || key.equalsIgnoreCase("sign")
+ || key.equalsIgnoreCase("sign_type")) {
+ continue;
+ }
+ result.put(key, value);
+ }
+ return result;
+ }
+
+ private String md5(String plainText) {
+ //定义一个字节数组
+ byte[] secretBytes = null;
+ try {
+ // 生成一个MD5加密计算摘要
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ //对字符串进行加密
+ md.update(plainText.getBytes());
+ //获得加密后的数据
+ secretBytes = md.digest();
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("没有md5这个算法!");
+ }
+ StringBuilder builder = new StringBuilder();
+ for (byte secretByte : secretBytes) {
+ builder.append(String.format("%02X", ((int) secretByte) & 0xFF));
+ }
+ return builder.toString();
+ }
+
+ private boolean calcSignAndCheck(Map<String, String> map, String key) {
+ String sign = map.get("sign");
+ String signType = map.get("sign_type") == null ? "MD5" : map.get("sign_type");
+ if (StringUtils.isEmpty(sign)) return false;
+
+ String signdata = createLinkString(paraFilter(map));
+ logger.info("signdata=[" + signdata + "]");
+
+ String calcSign = null;
+ //fixme: 根据 signType 计算签名
+ if ("MD5".equalsIgnoreCase(signType)) {
+ calcSign = md5(signdata + key); //默认MD5
+ }
+
+ if (sign.equalsIgnoreCase(calcSign)) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean checkSign(String key) {
+ Class clazz = this.getClass();
+ Map<String, String> paramMap = new HashMap<>();
+ Method[] allGetter = clazz.getMethods();
+
+ for (Method meth : allGetter) {
+ if (meth.getName().startsWith("get") || meth.getName().startsWith("is")) {
+ String fieldName = Introspector.decapitalize(meth.getName().substring(meth.getName().startsWith("get") ? 3 : 2));
+ Field field;
+ try {
+ field = clazz.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ try {
+ field = clazz.getSuperclass().getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e1) {
+ continue;
+ }
+ }
+
+ if (field.isAnnotationPresent(Sign.class)) {
+ Object value;
+ try {
+ value = meth.invoke(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ continue;
+ }
+ paramMap.put(fieldName, value == null ? null : value.toString());
+ }
+ }
+ }
+ return calcSignAndCheck(paramMap, key);
+ }
+
+ public abstract boolean checkParam() throws RequestParamCheckException;
+}
+
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sign.java b/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sign.java
new file mode 100644
index 0000000..1c9d9ca
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/annotation/Sign.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Sign {
+ int order() default 0;
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayfinishParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayfinishParam.java
new file mode 100644
index 0000000..0b07e7d
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayfinishParam.java
@@ -0,0 +1,21 @@
+package com.supwisdom.dlpay.api.bean;
+
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class CitizenCardPayfinishParam extends APIRequestParam {
+ @Sign
+ @NotNull(message = "交易参考号不能为空")
+ private String refno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java
new file mode 100644
index 0000000..b31a90a
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParam.java
@@ -0,0 +1,49 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class CitizenCardPayinitParam extends APIRequestParam {
+ @Sign
+ @NotNull(message = "卡唯一号不能为空")
+ private String cardNo;
+
+ @Sign
+ @NotNull(message = "请指定交易商户")
+ private String shopaccno;
+
+ @Sign
+ @NotNull
+ @Min(value = 0L, message = "交易金额必须大于零")
+ private Integer amount;
+
+ private List<ConsumeFeetype> feelist;
+
+ @Sign
+ @NotNull(message = "对接系统唯一订单号不能为空")
+ private String billno;
+
+ @Sign
+ @NotNull(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotNull(message = "交易时间不能为空")
+ private String transtime;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT))
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT))
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonQueryRechargeResultParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonQueryRechargeResultParam.java
new file mode 100644
index 0000000..d76faa8
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonQueryRechargeResultParam.java
@@ -0,0 +1,24 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+
+@Data
+public class CommonQueryRechargeResultParam extends APIRequestParam {
+ @Sign
+ private String refno;
+ @Sign
+ private String billno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (StringUtils.isEmpty(refno) && StringUtils.isEmpty(billno)) {
+ throw new RequestParamCheckException("流水号不能为空");
+ }
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonRechargeConfirmParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonRechargeConfirmParam.java
new file mode 100644
index 0000000..db748c4
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonRechargeConfirmParam.java
@@ -0,0 +1,21 @@
+package com.supwisdom.dlpay.api.bean;
+
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+@Data
+public class CommonRechargeConfirmParam extends APIRequestParam {
+ @Sign
+ @NotEmpty(message = "流水号不能为空")
+ private String refno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonRechargeInitParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonRechargeInitParam.java
new file mode 100644
index 0000000..66654d8
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/CommonRechargeInitParam.java
@@ -0,0 +1,51 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class CommonRechargeInitParam extends APIRequestParam {
+ @Sign
+ @NotNull(message = "请指定充值用户")
+ private String userid;
+
+ @Sign
+ @NotNull(message = "充值金额必须大于零")
+ @Min(value = 0L, message = "充值金额必须大于零")
+ private Integer amount;
+
+ private List<ConsumeFeetype> feelist;
+
+ @Sign
+ @NotEmpty(message = "请指定充值的支付方式")
+ private String sourcetype;
+
+ @Sign
+ @NotEmpty(message = "对接系统唯一订单号不能为空")
+ private String billno;
+
+ @Sign
+ @NotNull(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotNull(message = "交易时间不能为空")
+ private String transtime;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT))
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT))
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumeFeetype.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumeFeetype.java
new file mode 100644
index 0000000..d9f75b1
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumeFeetype.java
@@ -0,0 +1,14 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.Data;
+
+@Data
+public class ConsumeFeetype {
+ private String feetype;
+ private Integer amount;
+
+ @Override
+ public String toString() {
+ return String.format("feetype='%s', amount=%d", feetype, amount);
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumePayCancelParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumePayCancelParam.java
new file mode 100644
index 0000000..b03c75f
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumePayCancelParam.java
@@ -0,0 +1,43 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class ConsumePayCancelParam extends APIRequestParam {
+ @Sign
+ @NotNull
+ private String refno;
+ @Sign
+ private String billno;
+ @Sign
+ private String shopaccno;
+ @Sign
+ @NotNull(message = "撤销或退款流水号不能为空")
+ private String requestbillno;
+ @Sign
+ @NotNull(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotNull(message = "交易时间不能为空")
+ private String transtime;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (StringUtils.isEmpty(refno) && (StringUtils.isEmpty(billno) || StringUtils.isEmpty(shopaccno)))
+ throw new RequestParamCheckException("原流水唯一号不能为空");
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) {
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ }
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) {
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+ }
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumePayRefundParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumePayRefundParam.java
new file mode 100644
index 0000000..50948d0
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/ConsumePayRefundParam.java
@@ -0,0 +1,49 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class ConsumePayRefundParam extends APIRequestParam {
+ @Sign
+ private String refno;
+ @Sign
+ private String billno;
+ @Sign
+ private String shopaccno;
+
+ @Sign
+ @Min(value = 0L, message = "错误的退款金额")
+ private Integer refundAmount;
+
+ @Sign
+ @NotNull(message = "撤销或退款流水号不能为空")
+ private String requestbillno;
+ @Sign
+ @NotNull(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotNull(message = "交易时间不能为空")
+ private String transtime;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (StringUtils.isEmpty(refno) && (StringUtils.isEmpty(billno) || StringUtils.isEmpty(shopaccno))) {
+ throw new RequestParamCheckException("原流水唯一号不能为空");
+ }
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) {
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ }
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) {
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+ }
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/QueryDtlResultParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/QueryDtlResultParam.java
new file mode 100644
index 0000000..45077bb
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/QueryDtlResultParam.java
@@ -0,0 +1,50 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+@Data
+public class QueryDtlResultParam extends APIRequestParam {
+ @Sign
+ private String refno;
+ @Sign
+ private String billno;
+ @Sign
+ private String shopaccno;
+
+ public String getRefno() {
+ return refno;
+ }
+
+ public void setRefno(String refno) {
+ this.refno = refno;
+ }
+
+ public String getBillno() {
+ return billno;
+ }
+
+ public void setBillno(String billno) {
+ this.billno = billno;
+ }
+
+ public String getShopaccno() {
+ return shopaccno;
+ }
+
+ public void setShopaccno(String shopaccno) {
+ this.shopaccno = shopaccno;
+ }
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (StringUtils.isEmpty(refno) && (StringUtils.isEmpty(billno)
+ || StringUtils.isEmpty(shopaccno))) {
+ throw new RequestParamCheckException("流水唯一号不能为空");
+ }
+ return true;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/bean/YktCardPayinitParam.java b/common/src/main/java/com/supwisdom/dlpay/api/bean/YktCardPayinitParam.java
new file mode 100644
index 0000000..aa06109
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/bean/YktCardPayinitParam.java
@@ -0,0 +1,60 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class YktCardPayinitParam extends APIRequestParam {
+ @Sign
+ private String uid;
+ @Sign
+ @NotEmpty(message = "请指定交易商户")
+ private String shopaccno;
+ @Sign
+ @NotNull(message = "支付金额不能为空")
+ @Min(value = 0, message = "支付金额不能小于 0")
+ private Integer amount;
+
+ private List<ConsumeFeetype> feelist;
+
+ @Sign
+ @NotNull(message = "订单号不能为空")
+ private String billno;
+ @Sign
+ @NotNull(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotNull(message = "交易时间不能为空")
+ private String transtime;
+ @Sign
+ @NotNull(message = "一卡通唯一号不能为空")
+ private String stuempno;
+ @Sign
+ private String yktshopid;
+ @Sign
+ private String devphyid;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) {
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ }
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) {
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+ }
+ if (!StringUtils.isEmpty(yktshopid) && !StringUtils.isNumeric(yktshopid))
+ throw new RequestParamCheckException("一卡通商户号非整数");
+
+ return true;
+ }
+}
+
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/exception/RequestParamCheckException.java b/common/src/main/java/com/supwisdom/dlpay/api/exception/RequestParamCheckException.java
new file mode 100644
index 0000000..a58a336
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/exception/RequestParamCheckException.java
@@ -0,0 +1,14 @@
+package com.supwisdom.dlpay.api.exception;
+
+public class RequestParamCheckException extends Exception {
+ private int errCode;
+
+ public RequestParamCheckException(String message) {
+ super(String.format("Req-%d,%s", 300001, message));
+ this.errCode = errCode;
+ }
+
+ public int getErrCode() {
+ return errCode;
+ }
+}
diff --git a/common/src/main/java/com/supwisdom/dlpay/api/util/DateUtil.java b/common/src/main/java/com/supwisdom/dlpay/api/util/DateUtil.java
new file mode 100644
index 0000000..2e45a7e
--- /dev/null
+++ b/common/src/main/java/com/supwisdom/dlpay/api/util/DateUtil.java
@@ -0,0 +1,345 @@
+package com.supwisdom.dlpay.api.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class DateUtil {
+ private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);
+ public static final String DATE_FMT = "yyyyMMdd";
+ public static final String TIME_FMT = "HHmmss";
+ public static final String DATETIME_FMT = "yyyyMMddHHmmss";
+
+ /**
+ * Description: 返回一个当前时间 @return String 格式:yyyyMMddHHmmss @exception Modify
+ * History:
+ */
+ public static String getNow() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ return sdf.format(new Date());
+ }
+
+
+ /**
+ * Description: 根据类型返回一个当前时间 @param partten String @return String 格式:partten
+ */
+ public static String getNow(String partten) {
+ SimpleDateFormat sdf = new SimpleDateFormat(partten);
+ return sdf.format(new Date());
+ }
+
+ /**
+ * Description: 得到一个特殊的时间 @param startTime String 格式:yyyyMMddHHmmss @param
+ * interval int 秒 @return String 格式:partten @exception Modify History:
+ */
+ public static String getNewTime(String startTime, int interval) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date d = sdf.parse(startTime);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(d.getTime());
+ calendar.add(Calendar.SECOND, interval);
+ return sdf.format(calendar.getTime());
+ } catch (ParseException e) {
+ return startTime;
+ }
+ }
+
+ /**
+ * Description: 得到一个特殊的时间 @param startTime String 格式:partten @param
+ * interval int 秒 @return String 格式:partten @exception Modify History:
+ */
+ public static String getNewTime(String startTime, int interval, String partten) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(partten);
+ Date d = sdf.parse(startTime);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(d.getTime());
+ calendar.add(Calendar.SECOND, interval);
+ return sdf.format(calendar.getTime());
+ } catch (ParseException e) {
+ return startTime;
+ }
+ }
+
+ public static String getNewDay(String startDay, int intervalday) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+ Date d = sdf.parse(startDay);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(d.getTime());
+ calendar.add(Calendar.DATE, intervalday);
+ return sdf.format(calendar.getTime());
+ } catch (ParseException e) {
+ return startDay;
+ }
+ }
+
+ /**
+ * 得到两个日期相差的天数 格式 yyyyMMdd @return diffdays = secondDay - firstDay
+ */
+ public static long getIntervalDay(String firstDay, String secondDay) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+ Date f = sdf.parse(firstDay);
+ Date s = sdf.parse(secondDay);
+ long time = s.getTime() - f.getTime();
+ return time / (24 * 60 * 60 * 1000);
+ } catch (ParseException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式:yyyyMMddHHmmss
+ *
+ * @param secondTime String 格式: yyyyMMddHHmmss @return int |
+ * firstTime=second int=0 | firstTime>secondTime int>0 |
+ * firstTime<secondTime int<0 @exception Modify History:
+ */
+ public static int compareDatetime(String firstTime, String secondTime) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date f = sdf.parse(firstTime);
+ Date s = sdf.parse(secondTime);
+ return f.compareTo(s);
+ } catch (ParseException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式:pattern
+ *
+ * @param secondTime String 格式: yyyyMMddHHmmss @return int |
+ * firstTime=second int=0 | firstTime>secondTime int>0 |
+ * firstTime<secondTime int<0 @exception Modify History:
+ */
+ public static int compareDatetime(String firstTime, String secondTime, String pattern) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ Date f = sdf.parse(firstTime);
+ Date s = sdf.parse(secondTime);
+ return f.compareTo(s);
+ } catch (ParseException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Description: 比较两个时间字符串的时间差 @param firstTime String 格式:yyyyMMddHHmmss
+ *
+ * @param secondTime String 格式: yyyyMMddHHmmss @param second int 格式 @return
+ * int | firstTime+seconds=secondTime int=0 | firstTime+seconds>secondTime
+ * int>0 | firstTime+seconds<secondTime int<0 @exception Modify History:
+ */
+ public static int compareDatetime(String firstTime, String secondTime, int seconds) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date f = sdf.parse(firstTime);
+ Date s = sdf.parse(secondTime);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(f.getTime());
+ calendar.add(Calendar.SECOND, seconds);
+ Date temp = calendar.getTime();
+ return temp.compareTo(s);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Description: 对time重新格式化
+ */
+ public static String reformatDatetime(String time, String fromPattern, String toPattern) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(fromPattern);
+ Date d = sdf.parse(time);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(d.getTime());
+ sdf = new SimpleDateFormat(toPattern);
+ return sdf.format(calendar.getTime());
+ } catch (Exception e) {
+ e.printStackTrace();
+ return time;
+ }
+ }
+
+ /**
+ * 获得两个字符串日期之间的时间差(单位毫秒) 格式 yyyyMMddHHmmss
+ */
+ public static long getInterval(String startTime, String endTime) {
+ long duration = 0;
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ duration = sdf.parse(endTime).getTime() - sdf.parse(startTime).getTime();
+ } catch (ParseException e) {
+ logger.error("Hi guys,there is an error when you try to parse the date string");
+ }
+ return duration;
+ }
+
+ /**
+ * 获得两个字符串日期之间的时间差(单位毫秒)
+ */
+ public static long getIntervalTime(String startTime, String endTime, String pattern) {
+ long duration = 0;
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ duration = sdf.parse(endTime).getTime() - sdf.parse(startTime).getTime();
+ } catch (ParseException e) {
+ logger.error("Hi guys,there is an error when you try to parse the date string");
+ }
+ return duration;
+ }
+
+ /**
+ * 转换成日期格式
+ * 短格式:20140401 -> 2014-04-01
+ * 中格式:201404011200 -> 2014-04-01 12:00
+ * 长格式:20140401123025 -> 2014-04-01 12:30:25
+ **/
+ public static String parseToDateFormat(String str) {
+ switch (str.length()) {
+ case 8:
+ str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8);
+ break;
+ case 12:
+ str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12);
+ break;
+ case 14:
+ str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12) + ":" + str.substring(12, 14);
+ break;
+ default:
+ break;
+ }
+ return str;
+ }
+
+ /**
+ * 解日期格式
+ * 短格式:2014-04-01 -> 20140401
+ * 中格式:2014-04-01 12:00 -> 201404011200
+ * 长格式:2014-04-01 12:30:25 -> 20140401123025
+ **/
+ public static String unParseToDateFormat(String str) {
+ return str.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "");
+ }
+
+ /**
+ * 检验时间格式
+ */
+ public static boolean checkDatetimeValid(String datetime, String pattern) {
+ if (null == datetime) return false;
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ Date d = sdf.parse(datetime);
+ return datetime.trim().equals(sdf.format(d));
+ } catch (Exception e) {
+ }
+ return false;
+ }
+
+ /**
+ * 获取指定日期是星期几 格式 yyyyMMdd
+ * MON|TUE|WED|THU|FRI|SAT|SUN
+ * 1 2 3 4 5 6 7
+ */
+ public static int getWeekday(String datestr) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+ Calendar calendar = Calendar.getInstance();
+ boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY); //一周第一天是否为星期天
+ Date d = sdf.parse(datestr);
+ calendar.setTimeInMillis(d.getTime());
+ int weekDay = calendar.get(calendar.DAY_OF_WEEK);
+ if (isFirstSunday) {
+ weekDay = weekDay - 1;
+ if (weekDay == 0) {
+ weekDay = 7;
+ }
+ }
+ return weekDay;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /**
+ * 获取指定日期
+ */
+ public static Date getSpecifyDate(String datestr, String pattern) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ Date result = sdf.parse(datestr);
+ return result;
+ } catch (Exception e) {
+ return new Date();
+ }
+ }
+
+ public static Integer getLastDayOfMonth(Integer year, Integer month) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.MONTH, month - 1);
+ cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
+ String str = new SimpleDateFormat("yyyyMMdd ").format(cal.getTime()).toString();
+ Integer result = Integer.parseInt(str.substring(0, 4) + str.substring(4, 6) + str.substring(6, 8));
+ return result;
+ }
+
+ private static Date set(Date date, int calendarField, int amount) {
+ Calendar c = Calendar.getInstance();
+ c.setLenient(false);
+ c.setTime(date);
+ c.add(calendarField, amount);
+ return c.getTime();
+ }
+
+
+ public static Date setMinutes(Date date, int amount) {
+ return set(date, Calendar.MINUTE, amount);
+ }
+
+
+ public static long getNowSecond() {
+ Calendar calendar = Calendar.getInstance();
+ return calendar.getTimeInMillis() / 1000;
+ }
+
+
+ public static String getUTCTime(Long timeInMillisSecond) {
+ Calendar time = Calendar.getInstance();
+ SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+ fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+ time.setTimeInMillis(timeInMillisSecond);
+ return fmt.format(time.getTime());
+ }
+
+ public static String getUTCTime() {
+ return getUTCTime(System.currentTimeMillis());
+ }
+
+ public static int compareDay(Timestamp d1, Timestamp d2) {
+ Calendar cd1 = Calendar.getInstance();
+ cd1.setTimeInMillis(d1.getTime());
+ Calendar cd2 = Calendar.getInstance();
+ cd2.setTimeInMillis(d2.getTime());
+
+ if (cd1.get(Calendar.YEAR) != cd2.get(Calendar.YEAR)) {
+ return cd1.compareTo(cd2);
+ }
+
+ return Integer.compare(cd1.get(Calendar.DAY_OF_YEAR), cd2.get(Calendar.DAY_OF_YEAR));
+ }
+
+ public static Boolean sameDay(Timestamp d1, Timestamp d2) {
+ return (compareDay(d1, d2) == 0);
+ }
+}