/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通用工具类
 *
 * @author Chill
 */
public class CommonUtil {

	private final static Logger logger = LoggerFactory.getLogger(CommonUtil.class);

	/**金额为分的格式 */
	public static final String CURRENCY_FEN_REGEX = "\\-?[0-9]+";

	/**
	 * 获取String类型请求参数
	 * @param request 请求
	 * @return 参数
	 */
	public static Map<String, String> getParams(HttpServletRequest request) {
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iterator = requestParams.keySet().iterator(); iterator.hasNext();) {
			String name = (String) iterator.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}

			params.put(name, valueStr);
		}
		return params;
	}

	/**
	 * 将分为单位的转换为元并返回金额格式的字符串 （除100）
	 *
	 * @param amount
	 * @return
	 * @throws Exception
	 */
	public static String changeF2Y(String amount) throws Exception{
		if(!amount.matches(CURRENCY_FEN_REGEX)) {
			throw new Exception("金额格式有误");
		}

		int flag = 0;
		String amString = amount;
		if(amString.charAt(0)=='-'){
			flag = 1;
			amString = amString.substring(1);
		}
		StringBuffer result = new StringBuffer();
		if(amString.length()==1){
			result.append("0.0").append(amString);
		}else if(amString.length() == 2){
			result.append("0.").append(amString);
		}else{
			String intString = amString.substring(0,amString.length()-2);
			for(int i=1; i<=intString.length();i++){
				if( (i-1)%3 == 0 && i !=1){
					result.append(",");
				}
				result.append(intString.substring(intString.length()-i,intString.length()-i+1));
			}
			result.reverse().append(".").append(amString.substring(amString.length()-2));
		}
		if(flag == 1){
			return "-"+result.toString();
		}else{
			return result.toString();
		}
	}

	/**
	 * 将MAP组成xml
	 * @param params 参数
	 * @return
	 */
	public static String wechatLinkXml(Map<String, String> params) {
		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		String paramXml = "";
		StringBuilder preStr = new StringBuilder();

		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			String value = params.get(key);
			preStr.append("<" + key + ">" + "<![CDATA[" + value + "]]>" + "</" + key + ">");
		}
		paramXml = "<xml>" + preStr.toString() + "</xml>";

		return paramXml;
	}

	/**
	 * 将元为单位的转换为分 替换小数点，支持以逗号区分的金额
	 *
	 * @param amount
	 * @return
	 */
	public static String changeY2F(String amount){
		//处理包含, ￥ 或者$的金额
		String currency =  amount.replaceAll("\\$|\\￥|\\,", "");
		int index = currency.indexOf(".");
		int length = currency.length();
		Long amLong = 0L;
		if(index == -1){
			amLong = Long.valueOf(currency+"00");
		}else if(length - index >= 3){
			amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
		}else if(length - index == 2){
			amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
		}else{
			amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
		}
		return amLong.toString();
	}

	/**
	 * 指定长度,切割集合
	 * @param source
	 * @param len
	 * @param <T>
	 * @return
	 */
	public static  <T> List<List<T>> subWithLen(List<T> source, int len) {
		if (source == null || source.size() == 0 || len < 1) {
			return null;
		}

		List<List<T>> result = new ArrayList<List<T>>();
		int count = (source.size() + len - 1) / len;
		for (int i = 0; i < count; i++) {
			List<T> value = null;
			if ((i + 1) * len < source.size()) {
				value = source.subList(i * len, (i + 1) * len);
			} else {
				value = source.subList(i * len, source.size());
			}
			result.add(value);
		}
		return result;
	}

	/**
	 * 将秒数转换成天具体的天时分秒
	 * 比如172800S转换成2天0时0分0秒
	 *
	 * @param second
	 * @return
	 */
	public static String formatSecond(Object second) {
		String timeStr = "0秒";
		if (second != null) {
			Double s = (Double) second;
			String format;
			Object[] array;
			Integer days = (int) (s / (60 * 60 * 24));
			Integer hours = (int) (s / (60 * 60) - days * 24);
			Integer minutes = (int) (s / 60 - hours * 60 - days * 24 * 60);
			Integer seconds = (int) (s - minutes * 60 - hours * 60 * 60 - days * 24 * 60 * 60);
			if (days > 0) {
				format = "%1$,d天%2$,d时%3$,d分%4$,d秒";
				array = new Object[]{days, hours, minutes, seconds};
			} else if (hours > 0) {
				format = "%1$,d时%2$,d分%3$,d秒";
				array = new Object[]{hours, minutes, seconds};
			} else if (minutes > 0) {
				format = "%1$,d分%2$,d秒";
				array = new Object[]{minutes, seconds};
			} else {
				format = "%1$,d秒";
				array = new Object[]{seconds};
			}
			timeStr = String.format(format, array);
		}
		return timeStr;
	}

	/**
	 * 自动生成昵称（中文）
	 *
	 * @param len 昵称长度
	 * @return
	 */
	public static String getRandomNickname(int len) {
		String ret = "";
		for (int i = 0; i < len; i++) {
			String str = null;
			// 定义高低位
			int highPos, lowPos;
			Random random = new Random();
			// 获取高位值
			highPos = (176 + Math.abs(random.nextInt(39)));
			// 获取低位值
			lowPos = (161 + Math.abs(random.nextInt(93)));
			byte[] b = new byte[2];
			b[0] = (new Integer(highPos).byteValue());
			b[1] = (new Integer(lowPos).byteValue());
			try {
				// 转成中文
				str = new String(b, "GBK");
			} catch (UnsupportedEncodingException ex) {
				ex.printStackTrace();
			}
			ret += str;
		}
		return ret;
	}

	/**
	 * 获取真实IP地址
	 *
	 * @param request
	 * @return
	 */
	public static String getIPAddress(HttpServletRequest request) {
		String ip = null;

		//X-Forwarded-For：Squid 服务代理
		String ipAddresses = request.getHeader("X-Forwarded-For");
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			//Proxy-Client-IP：apache 服务代理
			ipAddresses = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			//WL-Proxy-Client-IP：weblogic 服务代理
			ipAddresses = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			//HTTP_CLIENT_IP：有些代理服务器
			ipAddresses = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			//X-Real-IP：nginx服务代理
			ipAddresses = request.getHeader("X-Real-IP");
		}

		//有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
		if (ipAddresses != null && ipAddresses.length() != 0) {
			ip = ipAddresses.split(",")[0];
		}

		//还是不能获取到，最后再通过request.getRemoteAddr();获取
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 取得当前页第一项在全部项中的偏移量 (0-based)。
	 * page 当前页码
	 * itemsPerPage 每页项数
	 *
	 * @return 偏移量
	 */
	public static int getOffset(Integer page, Integer itemsPerPage) {
		return (page > 0) ? (itemsPerPage * (page - 1)) : 0;
	}

	/**
	 * 想取倒数第几个后面的字符串就把num设成几，str是原来的字符串，返回得到字符串
	 *
	 * @param str         字符串
	 * @param num         倒数第几个
	 * @param splitString 分割符
	 * @return 字符串
	 */
	public static String getSubStr(String str, int num, String splitString) {
		String result = "";
		int i = 0;
		while (i < num) {
			int lastFirst = str.lastIndexOf(splitString);
			result = str.substring(lastFirst) + result;
			str = str.substring(0, lastFirst);
			i++;
		}
		return result.substring(1);
	}

	/**
	 * 参数转换
	 *
	 * @param params
	 */
	public static void convertParams(Map<String, Object> params) {
		if (isNotNull(params.get("startCreateTime"))) {
			params.put("startCreateTime", formatStartTime(params.get("startCreateTime").toString()));
		}
		if (isNotNull(params.get("endCreateTime"))) {
			params.put("endCreateTime", formatEndTime(params.get("endCreateTime").toString()));
		}
	}

	/**
	 * 将一个 Map 对象转化为一个 JavaBean
	 *
	 * @param clazz 目标类
	 * @param map   map
	 * @param <T>   返回目标类
	 * @return 返回目标类
	 */
	public static <T> T toBean(Class<T> clazz, Map map) {
		return JSONObject.parseObject(JSONObject.toJSONString(map), clazz);
	}

	/**
	 * 非空判断
	 *
	 * @param obj
	 * @return
	 */
	public static boolean isNotNull(Object obj) {
		return obj != null && !obj.toString().isEmpty();
	}


	/**
	 * 空判断
	 *
	 * @param obj
	 * @return
	 */
	public static boolean isNull(Object obj) {
		return !isNotNull(obj);
	}

	/**
	 * 是否为空
	 *
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		return obj == null || obj.toString().length() == 0;
	}

	/**
	 * 格式化starTime, 设置为当天00:00:00
	 *
	 * @param stringDate "yyyy-MM-dd'T'HH:mm:ss.SSS Z"格式的时间
	 * @return yyyy-MM-dd HH:mm:ss 格式的时间
	 */
	public static String formatStartTime(String stringDate) {
		if (isEmpty(stringDate)) {
			return null;
		}

		// 方式一. 包含Z
		Date date = null;
		if (stringDate.contains("Z")) {
			// UTC 通用标准时，以Z来标识, 转换为标准时间
			stringDate = stringDate.replace("Z", " UTC");
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式二. 2018年01月21日
		if (stringDate.contains("年")) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式三. Tue May 01 2018 00:00:00 GMT 0800 (中国标准时间)
		if (stringDate.contains("GMT")) {
			stringDate = parseTime(stringDate);
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式四. 2018-01-21 15:55:55
		if (!stringDate.contains("UTC") && !stringDate.contains("Z") && !stringDate.contains("年") &&
			!stringDate.contains("GMT") && stringDate.length() > 11) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式五. 2018-05-21
		if (stringDate.length() < 11 && stringDate.contains("-")) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String starTime = format2.format(date);
		if (starTime.contains("23:59:59")) {
			starTime = starTime.replace("23:59:59", "00:00:00");
		}
		return starTime;
	}

	public static String parseTime(String datdString) {
		datdString = datdString.replace("GMT", "").replaceAll("\\(.*\\)", "");
		//将字符串转化为date类型，格式2016-10-12
		SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss z", Locale.ENGLISH);
		Date dateTrans = null;
		try {
			dateTrans = format.parse(datdString);
			return new SimpleDateFormat("yyyy-MM-dd").format(dateTrans);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return datdString;
	}

	/**
	 * 格式化endTime, 设置为当天23:59:59
	 *
	 * @param stringDate "yyyy-MM-dd'T'HH:mm:ss.SSS Z"格式的时间
	 * @return yyyy-MM-dd HH:mm:ss 格式的时间
	 */
	public static String formatEndTime(String stringDate) {
		if (isEmpty(stringDate)) {
			return null;
		}

		// 方式一. 包含Z
		Date date = null;
		if (stringDate.contains("Z")) {
			// UTC 通用标准时，以Z来标识, 转换为标准时间
			stringDate = stringDate.replace("Z", " UTC");
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式二. 2018年01月21日
		if (stringDate.contains("年")) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式三. Tue May 01 2018 00:00:00 GMT 0800 (中国标准时间)
		if (stringDate.contains("GMT")) {
			stringDate = parseTime(stringDate);
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式四. 2018-01-21 15:55:55
		if (!stringDate.contains("UTC") && !stringDate.contains("Z") && !stringDate.contains("年") &&
			!stringDate.contains("GMT") && stringDate.length() > 11) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		// 方式五. 2018-05-21
		if (stringDate.length() < 11 && stringDate.contains("-")) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			try {
				date = format.parse(stringDate);
			} catch (ParseException e) {
				logger.info("格式化endTime异常");
				e.printStackTrace();
			}
		}

		SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String endTime = format2.format(date);
		if (endTime.contains("00:00:00")) {
			endTime = endTime.replace("00:00:00", "23:59:59");
		}
		return endTime;
	}

	// 获得UUID
	public static String getUUID() {
		return UUID.randomUUID().toString().replace("-", "");
	}

	// 获得当前时间 年月日时分秒。。。
	public static String getDateByYMDHMS() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
		String nowDate = sdf.format(new Date()).toString();
		return nowDate;
	}

	// 获得当前时间 年月日
	public static String getDateByYMD() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String nowDate = sdf.format(new Date()).toString();
		return nowDate;
	}



	/**
	 * MD5加密
	 */
	public static String md5(String value) {
		String result = null;
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
			md5.update((value).getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException error) {
			error.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		byte b[] = md5.digest();
		int i;
		StringBuffer buf = new StringBuffer("");

		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));
		}

		result = buf.toString();
		return result;
	}

	/**
	 * 判断用户密码是否正确
	 * * @param newpasswd 用户输入的密码
	 * * @param oldpasswd
	 * 数据库中存储的密码－－用户密码的摘要
	 * * @return 　　　　* @throws NoSuchAlgorithmException
	 * 　* @throws UnsupportedEncodingException
	 */
	public static boolean checkpassword(String newpasswd, String oldpasswd)
		throws NoSuchAlgorithmException, UnsupportedEncodingException {
		if (md5(newpasswd).equals(oldpasswd)) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 根据img获取图片的宽高
	 *
	 * @param imgUrl 图片地址
	 * @return 图片的对象，对象中图片的真实宽高
	 */
	public static BufferedImage getBufferedImage(String imgUrl) {
		URL url = null;
		InputStream is = null;
		BufferedImage img = null;
		try {
			url = new URL(imgUrl);
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			//  设置请求头信息
			con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0");
			con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			con.setRequestProperty("Connection", "keep-alive");

			is = con.getInputStream();
			img = ImageIO.read(is);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			img = null;
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return img;
	}

	public static HashMap<String, Object> convertToMap(Object obj) {

		HashMap<String, Object> map = new HashMap<>();
		Field[] fields = obj.getClass().getDeclaredFields();
		for (int i = 0, len = fields.length; i < len; i++) {
			String varName = fields[i].getName();
			boolean accessFlag = fields[i].isAccessible();
			fields[i].setAccessible(true);

			Object o = null;
			try {
				o = fields[i].get(obj);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
			if (o != null) {
				map.put(varName, o.toString());
			}

			fields[i].setAccessible(accessFlag);
		}

		return map;
	}

	/**
	 * 将json转化成map
	 *
	 * @param jsonStr
	 * @return
	 */
	public static Map<String, String> convertJsonStrToMap(String jsonStr) {
		LinkedHashMap<String, String> map = JSON.parseObject(jsonStr, new TypeReference<LinkedHashMap<String, String>>() {
		});
		return map;
	}

	/**
	 *
	 * @param str
	 * @param map
	 * @return
	 */
	public static String replaceMapToString(String str, Map<String, String> map) {
		// 切割左边框
		String[] split = str.split("\\{\\{");
		StringBuffer sb = new StringBuffer();
		for (String s : split) {
			sb.append(s);
		}

		// 切割右边框
		String s = sb.toString();
		String[] split1 = s.split("}}");
		StringBuffer sb1 = new StringBuffer();
		for (String s1 : split1) {
			sb1.append(s1);
		}
		String s3 = sb1.toString();

		for (Map.Entry entry : map.entrySet()) {
			String s1 = entry.getKey().toString();
			String s2 = entry.getValue().toString();
			s3 = s3.replace(s1, s2);
		}

		return s3;
	}

	/**
	 * 将数据保留两位小数
	 *
	 * @param num
	 * @return
	 */
	public static Double getTwoDecimal(double num) {
		Double temp = (double) Math.round(num * 100) / 100;
		return temp;
	}


	public static Boolean checkStrInArray(String str, String... args) {
		Boolean bool = new Boolean(false);
		if ((args.length <= 0) || CommonUtil.isNull(str)) {
			return bool;
		}
		// 遍历数组,要求的值在数组中,返回true
		for (String arg : args) {
			if (arg.equals(str)) {
				bool = true;
			}
		}
		return bool;
	}

	/**
	 * 删除html标签
	 *
	 * @param htmlStr
	 * @return
	 */
	public static String delHTMLTag(String htmlStr) {
		// 定义script的正则表达式
		String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>";
		// 定义style的正则表达式
		String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>";
		//定义HTML标签的正则表达式
		String regEx_html = "<[^>]+>";

		Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
		Matcher m_script = p_script.matcher(htmlStr);
		//过滤
		htmlStr = m_script.replaceAll("");

		Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
		Matcher m_style = p_style.matcher(htmlStr);
		//过滤style标签
		htmlStr = m_style.replaceAll("");

		Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
		Matcher m_html = p_html.matcher(htmlStr);
		//过滤html标签
		htmlStr = m_html.replaceAll("");
		htmlStr = htmlStr.replaceAll("(\\r\\n|\\r|\\n|\\n\\r)", "");
		//返回文本字符串
		return htmlStr.trim();
	}
	/*
	 * 将时间戳转换为时间
	 */
	public static String stampToDate(String s){
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long lt = new Long(s);
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}


	public static String getTodayString(Date date){
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String res = simpleDateFormat.format(date);
		return res;
	}

	/**
	 * 获取明天的此时此刻
	 * @param date
	 * @return
	 */
	public static Date getNextDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, +1);//+1今天的时间加一天
		date = calendar.getTime();
		return date;
	}

	/**
	 * 获取N天后的此刻
	 * @param date 当前时间
	 * @param days 延迟N天
	 * @return N天后的此刻
	 */
	public static Date getNextNDay(Date date, Integer days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, days);
		date = calendar.getTime();
		return date;
	}

	/**
	 * 获取N月后的此刻
	 * @param date 当前时间
	 * @param months 延迟N个月
	 * @return N月后的此刻
	 */
	public static Date getNextNMonth(Date date, Integer months) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, months);
		date = calendar.getTime();
		return date;
	}

	public static Long betweenDays(String a, String b) {

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");// 自定义时间格式

		Calendar calendar_a = Calendar.getInstance();// 获取日历对象
		Calendar calendar_b = Calendar.getInstance();

		Date date_a = null;
		Date date_b = null;

		try {
			date_a = simpleDateFormat.parse(a);//字符串转Date
			date_b = simpleDateFormat.parse(b);
			calendar_a.setTime(date_a);// 设置日历
			calendar_b.setTime(date_b);
		} catch (ParseException e) {
			e.printStackTrace();//格式化异常
		}

		long time_a = calendar_a.getTimeInMillis();
		long time_b = calendar_b.getTimeInMillis();

		long between_days = (time_b - time_a) / (1000 * 3600 * 24);//计算相差天数

		return between_days;
	}

	/**
	 * 计算两个日期相差的天数
	 *
	 * @param date1 <String>
	 * @param date2 <String>
	 * @return int
	 * @throws ParseException
	 */
	public static int getDaySpace(String date1, String date2) {
		int result = 0;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();

		try {
			c1.setTime(sdf.parse(date1));
			c2.setTime(sdf.parse(date2));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		result = c2.get(Calendar.DAY_OF_YEAR) - c1.get(Calendar.DAY_OF_YEAR);
		return Math.abs(result);
	}

	/**
	 * Object转BigDecimal类型
	 *
	 * @param value 要转的object类型
	 * @return 转成的BigDecimal类型数据
	 */
	public static BigDecimal getBigDecimal(Object value) {
		BigDecimal ret = null;
		if (value != null) {
			if (value instanceof BigDecimal) {
				ret = (BigDecimal) value;
			} else if (value instanceof String) {
				ret = new BigDecimal((String) value);
			} else if (value instanceof BigInteger) {
				ret = new BigDecimal((BigInteger) value);
			} else if (value instanceof Number) {
				ret = new BigDecimal(((Number) value).doubleValue());
			} else {
				throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
			}
		}
		return ret;
	}

	/**
	 * 获取当日0点
	 * @return 时间
	 */
	public static Date getTodayStartTime() {
		Calendar todayStart = Calendar.getInstance();
		todayStart.set(Calendar.HOUR_OF_DAY, 0);
		todayStart.set(Calendar.MINUTE, 0);
		todayStart.set(Calendar.SECOND, 0);
		todayStart.set(Calendar.MILLISECOND, 0);
		return todayStart.getTime();
	}

	/**
	 * 获取当日结束时间
	 * @return 时间
	 */
	public static Date getTodayEndTime() {
		Calendar todayEnd = Calendar.getInstance();
		todayEnd.set(Calendar.HOUR_OF_DAY, 23);
		todayEnd.set(Calendar.MINUTE, 59);
		todayEnd.set(Calendar.SECOND, 59);
		todayEnd.set(Calendar.MILLISECOND, 999);
		return todayEnd.getTime();
	}

	/**
	 * 获取当周星期一为开始时间
	 *
	 * @return 时间
	 */
	public static Date getWeekStartTime() {
		Calendar weekStart = Calendar.getInstance();
		int week = weekStart.get(Calendar.DAY_OF_WEEK) - 1;
		if (week == 0) {
			week = 7;
		}
		weekStart.add(Calendar.DATE, -week + 1);
		weekStart.set(Calendar.HOUR_OF_DAY, 0);
		weekStart.set(Calendar.MINUTE, 0);
		weekStart.set(Calendar.SECOND, 0);
		weekStart.set(Calendar.MILLISECOND, 0);
		return weekStart.getTime();
	}

	/**
	 * 获取当周星期天为结束时间
	 *
	 * @return 时间
	 */
	public static Date getWeekEndTime() {
		Calendar weekEnd = Calendar.getInstance();
		int week = weekEnd.get(Calendar.DAY_OF_WEEK) - 1;
		if (week == 0) {
			week = 7;
		}
		weekEnd.add(Calendar.DATE, -week + 7);
		weekEnd.set(Calendar.HOUR_OF_DAY, 23);
		weekEnd.set(Calendar.MINUTE, 59);
		weekEnd.set(Calendar.SECOND, 59);
		weekEnd.set(Calendar.MILLISECOND, 999);
		return weekEnd.getTime();
	}

	/**
	 * 获取当月开始时间
	 * @return 时间
	 */
	public static Date getMonthStartTime() {
		Calendar monthStart = Calendar.getInstance();
		monthStart.set(Calendar.DAY_OF_MONTH, 1);
		monthStart.set(Calendar.HOUR_OF_DAY, 0);
		monthStart.set(Calendar.MINUTE, 0);
		monthStart.set(Calendar.SECOND, 0);
		monthStart.set(Calendar.MILLISECOND, 0);
		return monthStart.getTime();
	}

	/**
	 * 获取当月结束时间
	 * @return 时间
	 */
	public static Date getMonthEndTime() {
		Calendar monthEnd = Calendar.getInstance();
		monthEnd.set(Calendar.DAY_OF_MONTH, monthEnd.getActualMaximum(Calendar.DAY_OF_MONTH));
		monthEnd.set(Calendar.HOUR_OF_DAY, 23);
		monthEnd.set(Calendar.MINUTE, 59);
		monthEnd.set(Calendar.SECOND, 59);
		monthEnd.set(Calendar.MILLISECOND, 999);
		return monthEnd.getTime();
	}

	/**
	 * 获取当年开始时间
	 * @return 时间
	 */
	public static Date getYearStartTime() {
		Calendar yearStart = Calendar.getInstance();
		yearStart.set(Calendar.DAY_OF_YEAR, 1);
		yearStart.set(Calendar.HOUR_OF_DAY, 0);
		yearStart.set(Calendar.MINUTE, 0);
		yearStart.set(Calendar.SECOND, 0);
		yearStart.set(Calendar.MILLISECOND, 0);
		return yearStart.getTime();
	}

	/**
	 * 获取当年结束时间
	 * @return 时间
	 */
	public static Date getYearEndTime() {
		Calendar yearEnd = Calendar.getInstance();
		int year = yearEnd.get(Calendar.YEAR);
		yearEnd.clear();
		yearEnd.set(Calendar.YEAR, year);
		yearEnd.set(Calendar.HOUR_OF_DAY, 23);
		yearEnd.set(Calendar.MINUTE, 59);
		yearEnd.set(Calendar.SECOND, 59);
		yearEnd.set(Calendar.MILLISECOND, 999);
		yearEnd.roll(Calendar.DAY_OF_YEAR, -1);
		return yearEnd.getTime();
	}

	public static Date getCurrentDate() {
		Date date=new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(calendar.DATE, 0);//如果把0修改为-1就代表昨天
		return calendar.getTime();
	}

	/**
	 * 判断空集合
	 *
	 * @param list
	 * @return
	 */
	public static Boolean isNullList(List list) {
		if (list == null || list.isEmpty()) {
			return true;
		}
		return false;
	}

	/**
	 * 判断非空集合
	 *
	 * @param list
	 * @return
	 */
	public static Boolean isNotNullList(List list) {
		return !isNullList(list);
	}

	/**
	 * 计算两个日期相差天数: date2 - date1
	 * @param date1 日期一
	 * @param date2 日期二
	 * @return 相差天数
	 */
	public static int differentDays(Date date1, Date date2) {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(date1);
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(date2);

		int day1 = calendar1.get(Calendar.DAY_OF_YEAR);
		int day2 = calendar2.get(Calendar.DAY_OF_YEAR);
		int year1 = calendar1.get(Calendar.YEAR);
		int year2 = calendar2.get(Calendar.YEAR);

		// 不同年
		if (year1 != year2) {
			int timeDistance = 0;
			for (int i = year1; i < year2; i++) {
				if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
					// 闰年
					timeDistance += 366;
				} else {
					// 不是闰年
					timeDistance += 365;
				}
			}
			return timeDistance + (day2 - day1);
		} else {
			// 同年
			return day2 - day1;
		}
	}

	/**
	 * 计算两个日期相差天数
	 * @param date1 日期一
	 * @param date2 日期二
	 * @return 相差天数
	 */
	public static int differentDayMillisecond(Date date1, Date date2) {
		return (int) ((date2.getTime() - date1.getTime()) / (3600 * 1000 * 24));
	}

	public static String htmlCover(String str) {
		if (str != null && str.length() > 0) {
			str = str.replaceAll("\\n", "");
			str = str.replaceAll("&nbsp;", " ");
			str = str.replaceAll("&ldquo;", "\"");
			str = str.replaceAll("&rdquo;", "\"");
			str = str.replaceAll("&quot;", "\"");
			str = str.trim();
		}
		return str;
	}
}
