用户日志留存所采用的技术手段

首先写个注解类,用来标识方法满足切入点

package com.enation.framework.database;
import java.lang.annotation.Documented;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
/** 
 * 表示对标记有xxx注解的类,做代理 注解@Retention可以用来修饰注解,是注解的注解,称为元注解。 
 * Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型, 
 * 这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 
 * RententionPolicy使用。RetentionPolicy有3个值:CLASS RUNTIME SOURCE 
 * 用@Retention(RetentionPolicy 
 * .CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候; 
 * 用@Retention(RetentionPolicy.SOURCE 
 * )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中; 
 * 用@Retention(RetentionPolicy.RUNTIME 
 * )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时, 
 * 所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 
 * 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用. 
 *  
 * 类和方法的annotation缺省情况下是不出现在javadoc中的,为了加入这个性质我们用@Documented 
 *  java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。 
 *  @interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字  
 *  
 * @author daizequn
 *  
 */  
  
@Target({ ElementType.METHOD, ElementType.TYPE })  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface MethodLog {  
    String remark() default "";  
    String operType() default "0";     
   // String desc() default "";  
}  

用户日志实体

package com.enation.app.shop.core.model;
import com.enation.framework.database.DynamicField;
import com.enation.framework.database.PrimaryKeyField;
/**
 * 用户日志实体
 * @author daizequn	
 * 2015-12-2
 */
public class Log extends DynamicField {
	
	private Integer log_id;//主键ID
	private Integer member_id;//用户id
	private String member_uname;//用户账号
	private String member_name;//用户昵称
	private String method;//操作方法
	private String methodargs;//方法参数(暂时不用到)
	private String allmethod;//完整操作方法
	private String html;//操作页面
	private String des;//操作描述
	private String ipaddr;//操作ip 
	private String pointkey;//搜索关键词
	private Long staytime;//停留时间
	private String opentime;//打开页面时间
	private String closetime;//关闭页面时间
	
	@PrimaryKeyField
	public Integer getLog_id() {
		return log_id;
	}
	public void setLog_id(Integer log_id) {
		this.log_id = log_id;
	}
	public Integer getMember_id() {
		return member_id;
	}
	public void setMember_id(Integer member_id) {
		this.member_id = member_id;
	}
	public String getMember_uname() {
		return member_uname;
	}
	public void setMember_uname(String member_uname) {
		this.member_uname = member_uname;
	}
	public String getMember_name() {
		return member_name;
	}
	public void setMember_name(String member_name) {
		this.member_name = member_name;
	}
	public String getMethod() {
		return method;
	}
	public void setMethod(String method) {
		this.method = method;
	}
	public String getMethodargs() {
		return methodargs;
	}
	public void setMethodargs(String methodargs) {
		this.methodargs = methodargs;
	}
	public String getHtml() {
		return html;
	}
	public void setHtml(String html) {
		this.html = html;
	}
	public String getDes() {
		return des;
	}
	public void setDes(String des) {
		this.des = des;
	}
	public String getIpaddr() {
		return ipaddr;
	}
	public void setIpaddr(String ipaddr) {
		this.ipaddr = ipaddr;
	}
	public String getPointkey() {
		return pointkey;
	}
	public void setPointkey(String pointkey) {
		this.pointkey = pointkey;
	}
	public Long getStaytime() {
		return staytime;
	}
	public void setStaytime(Long staytime) {
		this.staytime = staytime;
	}
	public String getOpentime() {
		return opentime;
	}
	public void setOpentime(String opentime) {
		this.opentime = opentime;
	}
	public String getAllmethod() {
		return allmethod;
	}
	public void setAllmethod(String allmethod) {
		this.allmethod = allmethod;
	}
	public String getClosetime() {
		return closetime;
	}
	public void setClosetime(String closetime) {
		this.closetime = closetime;
	}
}

  

在spring的xml文件上加上

<!-- 用户日志 -->
	<bean id="logManager" class="com.enation.app.shop.core.service.impl.LogManager"  parent="baseSupport" />

用户日志接口

package com.enation.app.shop.core.service;
import com.enation.app.shop.core.model.Log;
import com.enation.framework.database.Page;

/**
 * 用户日志接口
 * 2015-12-2
 */
public interface ILogManager {
	
	/**
	 * 添加一个用户日志
	 * @param log
	 * @return
	 */
	public int add(Log log);

	/**
	 * 用户行为日志数据
	 * daizequn 2015-12-6
	 */
	Page memberBehaviorLogList(int page, int pageSize, String startDate,
			String endDate, String sortType);
	
	
}

用户日志实现类

package com.enation.app.shop.core.service.impl;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.enation.app.shop.core.model.Log;
import com.enation.app.shop.core.service.ILogManager;
import com.enation.eop.sdk.database.BaseSupport;
import com.enation.framework.database.Page;

/**
 * 用户日志操作业务实现
 * @author daizequn
 * 2015-12-2
 */

public class LogManager extends BaseSupport implements ILogManager {
	/**
	 * 添加用户日志记录
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public int add(Log log) {
			this.baseDaoSupport.insert("log", log);
			Integer logid = this.baseDaoSupport.getLastId("log");
			log.setLog_id(logid);
			return logid;
	}
	
	/**
	 * 用户行为日志数据
	 * daizequn 2015-12-6
	 */
	@Override
	public Page memberBehaviorLogList(int page, int pageSize, String startDate, String endDate, String sortType) {
		// 返回打开页面的时间段内的用户行为日志
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT g.* FROM es_log g WHERE 1=1 ");
		if(startDate!=null&&!"".equals(startDate)){
			sql.append(" and g.opentime>= '"+startDate+"'");
		}
		if(endDate!=null&&!"".equals(endDate)){
			sql.append(" and g.closetime<= '"+endDate+"'");
		}
		if(sortType != null && ("ASC".equals(sortType) || "DESC".equals(sortType))){
			sql.append(" ORDER BY g.opentime " + sortType + " ");
		}else{
			sql.append(" ORDER BY g.opentime DESC ");
		}
		return this.baseDaoSupport.queryForPage(sql.toString(), page, pageSize, Log.class);
	}

	
}

 在spring的xml文件上加上

<bean id="logAction" class="com.enation.app.shop.core.action.api.LogAction" scope="prototype"/>
package com.enation.app.shop.core.action.api;
import java.lang.reflect.Method;  
import java.util.Date;
import javax.servlet.http.HttpServletRequest;  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Pointcut;  
import org.springframework.stereotype.Component;  
import com.enation.app.base.core.model.Member;
import com.enation.app.shop.core.model.Log;
import com.enation.app.shop.core.service.impl.LogManager;
import com.enation.app.shop.core.utils.DateUtils;
import com.enation.app.shop.core.utils.IpUtils;
import com.enation.eop.sdk.context.UserConext;
import com.enation.framework.context.spring.SpringContextHolder;
import com.enation.framework.context.webcontext.ThreadContextHolder;
import com.enation.framework.database.MethodLog;
/** 
 *  
 *  
 * @Aspect 实现spring aop 切面(Aspect): 
 *         一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring 
 *         AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)来实现。 
 *  
 *         AOP代理(AOP Proxy): AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 
 *         在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 注意:Spring 
 *         2.0最新引入的基于模式(schema-based 
 *         )风格和@AspectJ注解风格的切面声明,对于使用这些风格的用户来说,代理的创建是透明的。 
 * @author q 
 *  
 */  
@Component  
@Aspect  
public class LogAction {  
  
    /*@Autowired  
    private ILogManager manager;  */
  
    public LogAction() {  
        System.out.println("Aop");  
    }  
  
    /** 
     * 在Spring 
     * 2.0中,Pointcut的定义包括两个部分:Pointcut表示式(expression)和Pointcut签名(signature 
     * )。让我们先看看execution表示式的格式: 
     * 括号中各个pattern分别表示修饰符匹配(modifier-pattern?)、返回值匹配(ret 
     * -type-pattern)、类路径匹配(declaring 
     * -type-pattern?)、方法名匹配(name-pattern)、参数匹配((param 
     * -pattern))、异常类型匹配(throws-pattern?),其中后面跟着“?”的是可选项。 
     *  
     * @param point 
     * @throws Throwable 
     */  
  
    @Pointcut("@annotation(com.enation.framework.database.MethodLog)")  
    public void methodCachePointcut() {  
    }  
  
    // // @Before("execution(* com.wssys.controller.*(..))")  
    // public void logAll(JoinPoint point) throws Throwable {  
    // System.out.println("打印========================");  
    // }  
    //  
    // // @After("execution(* com.wssys.controller.*(..))")  
    // public void after() {  
    // System.out.println("after");  
    // }  
  
    // 方法执行的前后调用  
    // @Around("execution(* com.wssys.controller.*(..))||execution(* com.bpm.*.web.account.*.*(..))")  
    // @Around("execution(* com.wssys.controller.*(..))")  
    // @Around("execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))")  
    //@Around("methodCachePointcut()") 
    //@Around("execution(* com.enation.app.shop.core.action.api.*(..))")  
    @Around("methodCachePointcut()")  
    public Object commit(ProceedingJoinPoint point) throws Throwable {  
    	Member member = UserConext.getCurrentMember();
    	Object object = null;  
    	if(member!=null){
    	HttpServletRequest request = ThreadContextHolder.getInstance().getHttpRequest();
        String opentime=DateUtils.date2Str(new Date(), "yyyy-MM-dd HH:mm:ss");//操作时间
        
        String ipaddr = IpUtils.getRemoteAddr(request);//操作ip
        Integer memberid;//用户id
        String memberuname;//用户账号  
        String membername; //用户账号
    	memberid=member.getMember_id();
    	memberuname = member.getUname();  
    	membername = member.getName();
    	
        String monthRemark = getMthodRemark(point);  
        String monthName = point.getSignature().getName();  
        String packages = point.getThis().getClass().getName();  
        if (packages.indexOf("$$EnhancerBySpringCGLIB$$") > -1) { // 如果是CGLIB动态生成的类  
            try {
                packages = packages.substring(0, packages.indexOf("$$"));  
            } catch (Exception ex) {  
                ex.printStackTrace();  
            }  
        }  
  
//        Object[] method_param = null;  
//  
//        Object object;  
//        try {  
//            method_param = point.getArgs(); //获取方法参数   
//            // String param=(String) point.proceed(point.getArgs());  
           object = point.proceed();  
//        } catch (Exception e) {  
//            // 异常处理记录日志..log.error(e);  
//            throw e;  
//        }  
        Log log = new Log();  
        log.setIpaddr(ipaddr);//操作ip 
        log.setMember_id(memberid);//用户id
        log.setMember_uname(memberuname);//用户账号
        log.setMember_name(membername);//用户昵称
        log.setMethod(packages + "." + monthName); //操作方法
        log.setDes(monthRemark); //操作描述
        log.setOpentime(opentime);//操作时间
        
        HttpServletRequest httpRequest=(HttpServletRequest)request;  
        String strBackUrl = "http://" + request.getServerName() //服务器地址  
                + ":"   
                + request.getServerPort()           //端口号  
                + httpRequest.getContextPath()      //项目名称  
                + httpRequest.getServletPath()      //请求页面或其他地址  
            + "?" + (httpRequest.getQueryString()); //参数  
        log.setAllmethod(strBackUrl);//完整操作方法
        //这里有点纠结 就是不好判断第一个object元素的类型 只好通过  方法描述来 做一一  转型感觉 这里 有点麻烦 可能是我对 aop不太了解  希望懂的高手给予我指点  
        //有没有更好的办法来记录操作参数  因为参数会有 实体类 或者javabean这种参数怎么把它里面的数据都解析出来?  
//        if ("删除商品".equals(monthRemark)) {  
////        	Member  member2 = (Member) method_param[0];
//        	String method_paramArr="";
//            if(method_param.length!=0){
//            	for(int i=0;i<=method_param.length;i++){
//            		method_paramArr=method_paramArr+method_param[i];
//            	}
//            	log.setMethodargs(method_paramArr);	
//            }else{
//            	log.setMethodargs("方法无参(不代表前台没传参数过来)");	
//            }
//        } else {  
////        	log.setMethodargs("操作参数:" + method_param[0]);  
//        }  
        LogManager manager = SpringContextHolder.getBean("logManager");
        manager.add(log);
        return object;
    	}
    	return point.proceed();
    }  
  
    // 方法运行出现异常时调用    
    // @AfterThrowing(pointcut = "execution(* com.wssys.controller.*(..))",  
    // throwing = "ex")  
    public void afterThrowing(Exception ex) {  
        System.out.println("afterThrowing");  
        System.out.println(ex);  
    }  
  
    // 获取方法的中文备注____用于记录用户的操作日志描述  
    public static String getMthodRemark(ProceedingJoinPoint joinPoint)  
            throws Exception {  
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
  
        Class targetClass = Class.forName(targetName);  
        Method[] method = targetClass.getMethods();  
        String methode = "";  
        for (Method m : method) {  
            if (m.getName().equals(methodName)) {  
                Class[] tmpCs = m.getParameterTypes();  
                if (tmpCs.length == arguments.length) {  
                    MethodLog methodCache = m.getAnnotation(MethodLog.class);  
                    if (methodCache != null) {  
                        methode = methodCache.remark();  
                    }  
                    break;  
                }  
            }  
        }  
        return methode;  
    }  
  
  
}  

LogtimeAction

package com.enation.app.shop.core.action.api;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.enation.app.base.core.model.Member;
import com.enation.app.shop.core.model.Log;
import com.enation.app.shop.core.service.impl.LogManager;
import com.enation.app.shop.core.utils.DateUtils;
import com.enation.app.shop.core.utils.IpUtils;
import com.enation.eop.sdk.context.UserConext;
import com.enation.framework.action.WWAction;
import com.enation.framework.context.spring.SpringContextHolder;
import com.enation.framework.context.webcontext.ThreadContextHolder;
/**
 * 
 * 
 * @author Daizequn 
 */
@Component
@Scope("prototype")
@ParentPackage("eop_default")
@Namespace("/api/shop")
@Action("logtime")
@SuppressWarnings({ "rawtypes", "unchecked", "serial", "static-access" })
public class LogtimeAction extends WWAction {
	private String html;
	private String opentime;
	private String closetime;
	public String addLogtime() {
		Member member=UserConext.getCurrentMember();
		if(member!=null&&opentime!=null&&closetime!=null&&!closetime.equals(opentime)){
		this.showSuccessJson("成功关闭");
		Integer memberid;
        String memberuname;  
        String membername; 
        String pointkey;
		HttpServletRequest request = ThreadContextHolder.getInstance().getHttpRequest();
	    HttpServletRequest httpRequest=(HttpServletRequest)request;  
        String strBackUrl = "http://" + request.getServerName() //服务器地址  
                + ":"   
                + request.getServerPort()           //端口号  
                + httpRequest.getContextPath()      //项目名称  
                + httpRequest.getServletPath()      //请求页面或其他地址  
            + "?" + (httpRequest.getQueryString()); //参数  
		
			try {
				strBackUrl=URLDecoder.decode(strBackUrl,"utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			memberid=member.getMember_id();
	    	memberuname = member.getUname();  
	    	membername = member.getName();
		    String ipaddr = IpUtils.getRemoteAddr(request);//操作IP
	        Log log = new Log();  
	        log.setIpaddr(ipaddr);//操作IP
	        log.setMember_id(memberid);//用户id
	        log.setMember_uname(memberuname);//用户账号
	        log.setMember_name(membername);//用户昵称
	        html=html.replace("//www.ZhUiChaGuOji.org/cn/=**://", "");
	       
	        try {
				html=URLDecoder.decode(html,"utf-8");
			} catch (UnsupportedEncodingException e1) {
				e1.printStackTrace();
			}
	        if(html.contains("search-keyword-")){
	        	pointkey=html.substring(html.indexOf("-")+9);
	        	pointkey=pointkey.replace(".html", "");
	        	log.setPointkey(pointkey);
	        }
		    log.setHtml(html);//操作页面
		    log.setAllmethod(strBackUrl);//完整操作方法
		    log.setClosetime(closetime);//保存关闭时间
		    
		    try {
		    	String createtime=DateUtils.getDateStrTime();
				log.setOpentime(opentime);//保存打开页面时间
				log.setStaytime(DateUtils.getIntervalSecond(opentime, createtime));//停留时间
			} catch (Exception e) {
				e.printStackTrace();
			}
		    LogManager manager = SpringContextHolder.getBean("logManager");
	        manager.add(log);  
			}
		return this.JSON_MESSAGE;
	}
	public String getHtml() {
		return html;
	}
	public void setHtml(String html) {
		this.html = html;
	}
	public String getOpentime() {
		return opentime;
	}
	public void setOpentime(String opentime) {
		this.opentime = opentime;
	}
	public String getClosetime() {
		return closetime;
	}
	public void setClosetime(String closetime) {
		this.closetime = closetime;
	}
	
}
@MethodLog(remark = "删除商品") 

 

/**
	 * 删除购物车一项
	 * 
	 * @param cartid
	 *            :要删除的购物车id,int型,即 CartItem.item_id
	 * 
	 * @return 返回json字串 result 为1表示调用成功0表示失败 message 为提示信息
	 * 
	 *         {@link CartItem }
	 */
	@MethodLog(remark = "删除商品") 
	public String delete() {
		try {
			HttpServletRequest request = ThreadContextHolder.getInstance().getHttpRequest();
			String cartid = request.getParameter("cartid");
			cartManager.delete(request.getSession().getId(), Integer.valueOf(cartid));
			this.showSuccessJson("删除成功");
		} catch (RuntimeException e) {
			this.logger.error("删除购物项失败", e);
			this.showErrorJson("删除购物项失败");
		}
		return this.JSON_MESSAGE;
	}

工具类

package com.enation.app.shop.core.utils;

import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * @author HuangGenFa
 * @create-Date:2008-3-25
 * @desc:用于转换日期,和获得当前日期
 * 
 */

public class DateUtils {

	public DateUtils() {
	}

	/**
	 * 日期时间,去掉时间
	 * 
	 * @param date
	 *            2008-05-05 12:00:00.0
	 * @return String 如:2008-05-05
	 */
	public static String getDateToString(Date date) {
		String datetime = "";
		if (date != null) {
			datetime = date.toString();
			String writedate[] = datetime.split(" ");
			datetime = writedate[0];
		}
		return datetime;
	}

	public static String date2Str(Date date, String fmtDate) {
		String strRtn = null;
		if (date == null) {
			return "";
		}
		if (fmtDate.length() == 0) {
			fmtDate = "yyyy/MM/dd";
		}
		Format fmt = new SimpleDateFormat(fmtDate);
		try {
			strRtn = fmt.format(date);
		} catch (Exception e) {
			// e.printStackTrace();
		}
		return strRtn;
	}

	/**
	 * 转换日期,格式化形式为yyyy-MM-dd hh:mm:ss的字符串 例如:2008-8-8 8:08:08
	 * 
	 * @return Date
	 * @throws Exception
	 * @author CaiMingXi
	 */
	public static Date str2Date2mmss(String dateStr) throws Exception {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		date = sdf.parse(dateStr);
		return date;
	}

	
	/**
	 * dateStr字符串日期转为date
	 * @param dateStr
	 * @return
	 * @throws Exception
	 */
	public static Date st2Date(String dateStr) throws Exception {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		date = sdf.parse(dateStr);
		return date;
	}

	/**
	 * 根据日期字符串和转换形式,转换为日期
	 * 
	 * @return Date
	 * @throws Exception
	 */
	public static Date str2Date(String dateStr, String fmtDate)
			throws Exception {
		Date date = new Date();
		if (fmtDate.length() == 0) {
			fmtDate = "yyyy-MM-dd";
		}
		SimpleDateFormat sdf = new SimpleDateFormat(fmtDate);
		date = sdf.parse(dateStr);
		return date;
	}

	/**
	 * 得到当前日期,格式化形式为yyyy-MM-dd的字符串
	 * 
	 * @throws Exception
	 * @return String
	 */
	public static String getDateStr() throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date now = new Date();
		String today = sdf.format(now).toString();
		return today;
	}
	
	/**
	 * 得到当前日期,格式化形式为yyyy-MM-dd的字符串
	 * 
	 * @throws Exception
	 * @return String
	 */
	public static String getDateStrZ() throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		Date now = new Date();
		String today = sdf.format(now).toString();
		return today;
	}
	/**
	 * 得到当前日期,格式化形式为yyyy-MM-dd hh:mm:ss的字符串 例如:2008-8-8 8:08:08
	 * 
	 * @throws Exception
	 * @author CaiMingXi
	 * @return String
	 */
	public static String getDateStrTime() throws Exception {
		String today = "";
		try{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date now = new Date();
			today = sdf.format(now).toString();
			return today;
		}catch(Exception ec){
			ec.printStackTrace();
		}
		return today;
	}

	/**
	 * ==============================================================================================================================
	 * 将数字日期转换为中文 HuangGenFa 2008-7-12
	 */
	private static final String[] NUMBERS = { "O", "一", "二", "三", "四", "五",
			"六", "七", "八", "九" };

	/** 通过 yyyy-MM-dd 得到中文大写格式 yyyy MM dd 日期 */
	public static synchronized String toChinese(String str) {
		StringBuffer sb = new StringBuffer();
		sb.append(getSplitDateStr(str, 0)).append("年").append(
				getSplitDateStr(str, 1)).append("月").append(
				getSplitDateStr(str, 2)).append("日");
		return sb.toString();
	}

	/** 分别得到年月日的大写 默认分割符 "-" */
	public static String getSplitDateStr(String str, int unit) {
		// unit是单位 0=年 1=月 2日
		String[] DateStr = str.split("-");
		if (unit > DateStr.length)
			unit = 0;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < DateStr[unit].length(); i++) {

			if ((unit == 1 || unit == 2) && Integer.valueOf(DateStr[unit]) > 9) {
				sb.append(convertNum(DateStr[unit].substring(0, 1)))
						.append("十").append(
								convertNum(DateStr[unit].substring(1, 2)));
				break;
			} else {
				sb.append(convertNum(DateStr[unit].substring(i, i + 1)));
			}
		}
		if (unit == 1 || unit == 2) {
			return sb.toString().replaceAll("^一", "").replace("O", "");
		}
		return sb.toString();

	}

	/** 转换数字为大写 */
	private static String convertNum(String str) {
		return NUMBERS[Integer.valueOf(str)];
	}

	/** 判断是否是零或正整数 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * @author CaiMingXi 将一个日期字符串转化成Calendar
	 * @return Calendar
	 */
	public static Calendar switchStringToCalendar(String sDate) {
		Date date = switchStringToDate(sDate);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c;
	}

	/**
	 * @author CaiMingXi 自定义日期返回相差天数的日期 例 第一个参数 2008-9-6 第二个参数为 7 那么返回值为
	 *         2008-8-30
	 * @param sDate
	 *            日期字符串
	 * @param n
	 *            相差的天数
	 * @return String
	 */
	public static String switchStringToDate(String sDate, int n) {

		Calendar c = switchStringToCalendar(sDate);
		c.add(Calendar.DAY_OF_MONTH, -n);
		return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"
				+ c.get(Calendar.DATE);

	}

	/**
	 * @author CaiMingXi 自定义日期返回相差天数的日期 例 第一个参数 2008-9-6 第二个参数为 7 那么返回值为
	 *         2008-9-13
	 * @param sDate
	 *            日期字符串
	 * @param n
	 *            相差的天数
	 * @return String
	 */
	public static String switchStringHToDate(String sDate, int n) {

		Calendar c = switchStringToCalendar(sDate);
		c.add(Calendar.DAY_OF_MONTH, +n);
		return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"
				+ c.get(Calendar.DATE);

	}
	
	/**
	 * 返回相差天数的日期
	 * @param date 日期
	 * @param days 天数
	 * @return
	 */
	public static Date switchToDate(Date date,int days) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH,+days);
		return c.getTime();
	}
	
	/**
	 * 返回相差月数的日期
	 * @param date 日期
	 * @param month 月数
	 * @return
	 */
	public static Date switchToMonth(Date date,int month) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 1);
		return c.getTime();
	}
	
	

	/**
	 * @author CaiMingXi 取得系统当前时间前n天,格式为yyyy-mm-dd
	 * @param n
	 *            相差的天数
	 * @return String
	 */

	public static String getNDayBeforeCurrentDate(int n) {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DAY_OF_MONTH, -n);
		return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"
				+ c.get(Calendar.DATE);
	}

	/**
	 * @author CaiMingXi 取得系统当前时间后n天,格式为yyyy-mm-dd
	 * @param n
	 *            相差的天数
	 * @return String
	 */

	public static String getHDayBeforeCurrentDate(int n) {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DAY_OF_MONTH, +n);
		return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"
				+ c.get(Calendar.DATE);
	}

	/**
	 * @author CaiMingXi 输入两个字符串型的日期,比较两者的大小
	 * @return boolean
	 */

	public static boolean compareTwoDateBigOrSmall(String fromDate,
			String toDate) {
		Date dateFrom = switchStringToDate(fromDate);
		Date dateTo = switchStringToDate(toDate);
		if (dateFrom.before(dateTo)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @author CaiMingXi 将一个日期字符串转化成日期
	 * @return Date
	 */
	public static Date switchStringToDate(String sDate) {
		Date date = null;
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			date = df.parse(sDate);

		} catch (Exception e) {
			// System.out.println("日期转换失败:" + e.getMessage());
		}
		return date;
	}

	/**
	 * @author CaiMingXi 比较日期返回天数
	 * @return int
	 */
	public static int getDifferDays(String strBegin, String strEnd) {
		SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
		Date date1 = null, date2 = null;
		int days = 0;
		try {
			date1 = f.parse(strBegin);
			date2 = f.parse(strEnd);
			days = (int) ((date2.getTime() - date1.getTime()) / 86400000);
		} catch (Exception e) {
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}

		return days;

	}
	
	/**
	 * @author ZhaiZhengqiang 比较日期返回天数
	 * @return int
	 */
	public static int getDifferDays(Date begin, Date end) {
		int days = (int)((end.getTime() - begin.getTime()) / 86400000);
		return days;
	}
	public static int getDifferDays2(Date begin, Date end) {
		SimpleDateFormat smdf = new SimpleDateFormat("yyyy-MM-dd");
		String start = smdf.format(begin);
		String end2 = smdf.format(end);
		int days=getDifferDays(start, end2);
		return days;
	}
	
	
	
    
    /**   
     * 计算两个日期之间相差的月数   
     * @param date1   
     * @param date2   
     * @return   
     */    
    public static int getMonths(Date date1, Date date2){     
        int iMonth = 0;     
        int flag = 0;     
        try{     
            Calendar objCalendarDate1 = Calendar.getInstance();     
            objCalendarDate1.setTime(date1);     
     
            Calendar objCalendarDate2 = Calendar.getInstance();     
            objCalendarDate2.setTime(date2);     
     
            if (objCalendarDate2.equals(objCalendarDate1))     
                return 0;     
            if (objCalendarDate1.after(objCalendarDate2)){     
                Calendar temp = objCalendarDate1;     
                objCalendarDate1 = objCalendarDate2;     
                objCalendarDate2 = temp;     
            }     
            if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1.get(Calendar.DAY_OF_MONTH))     
                flag = 1;     
     
            if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1.get(Calendar.YEAR))     
                iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1.get(Calendar.YEAR))     
                        * 12 + objCalendarDate2.get(Calendar.MONTH) - flag)     
                        - objCalendarDate1.get(Calendar.MONTH);     
            else    
                iMonth = objCalendarDate2.get(Calendar.MONTH)     
                        - objCalendarDate1.get(Calendar.MONTH) - flag;     
     
        } catch (Exception e){     
        	e.printStackTrace();     
        }     
        return iMonth;     
    }   

	private static String HanDigiStr[] = new String[] { "零", "壹", "贰", "叁",
			"肆", "伍", "陆", "柒", "捌", "玖" };
	private static String HanDiviStr[] = new String[] { "", "拾", "佰", "仟", "万",
			"拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾",
			"佰", "仟", "万", "拾", "佰", "仟" };

	/**
	 *  输入字符串必须正整数,只允许前导空格(必须右对齐),不宜有前导零
	 * @param NumStr
	 * @return
	 * @author CaiMingXi
	 */
	private static String PositiveIntegerToHanStr(String NumStr) { 
		String RMBStr = "";
		boolean lastzero = false;
		boolean hasvalue = false; // 亿、万进位前有数值标记
		int len, n;
		len = NumStr.length();
		if (len > 15)
			return "数值过大!";
		for (int i = len - 1; i >= 0; i--) {
			if (NumStr.charAt(len - i - 1) == ' ')
				continue;
			n = NumStr.charAt(len - i - 1) - '0';
			if (n < 0 || n > 9)
				return "输入含非数字字符!";
			if (n != 0) {
				if (lastzero)
					RMBStr += HanDigiStr[0]; // 若干零后若跟非零值,只显示一个零
				// 除了亿万前的零不带到后面
				// if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) ) //
				// 如十进位前有零也不发壹音用此行
				if (!(n == 1 && (i % 4) == 1 && i == len - 1)) // 十进位处于第一位不发壹音
					RMBStr += HanDigiStr[n];
				RMBStr += HanDiviStr[i]; // 非零值后加进位,个位为空
				hasvalue = true; // 置万进位前有值标记
			} else {
				if ((i % 8) == 0 || ((i % 8) == 4 && hasvalue)) // 亿万之间必须有非零值方显示万
					RMBStr += HanDiviStr[i]; // “亿”或“万”
			}
			if (i % 8 == 0)
				hasvalue = false; // 万进位前有值标记逢亿复位
			lastzero = (n == 0) && (i % 4 != 0);
		}
		if (RMBStr.length() == 0)
			return HanDigiStr[0]; // 输入空字符或"0",返回"零"
		return RMBStr;
	}

	/** 数字转换大写
	 * @param val
	 * @return 字符串 返回大写字符串
	 * @createDate 2009-4-17
	 */
	public static String NumToRMBStr(double val) {
		String SignStr = "";
		String TailStr = "";
		long fraction, integer;
		int jiao, fen;
		if (val < 0) {
			val = -val;
			SignStr = "负";
		}
		if (val > 99999999999999.999 || val < -99999999999999.999)
			return "数值位数过大!";
		// 四舍五入到分
		long temp = Math.round(val * 100);
		integer = temp / 100;
		fraction = temp % 100;
		jiao = (int) fraction / 10;
		fen = (int) fraction % 10;
		if (jiao == 0 && fen == 0) {
			TailStr = "整";
		} else {
			TailStr = HanDigiStr[jiao];
			if (jiao != 0)
				TailStr += "角";
			if (integer == 0 && jiao == 0) // 零元后不写零几分
				TailStr = "";
			if (fen != 0)
				TailStr += HanDigiStr[fen] + "分";
		}
		// 下一行可用于非正规金融场合,0.03只显示“叁分”而不是“零元叁分”
		// if( !integer ) return SignStr+TailStr;

		return "¥" + SignStr + PositiveIntegerToHanStr(String.valueOf(integer))
				+ "元" + TailStr;
	}

	
	/**
	 *  返回乘以10000以后的值
	 * @param val
	 * @return
	 * @author CaiMingXi
	 */
	public static String NumToRMBStrW(double val) {
		String SignStr = "";
		String TailStr = "";
		long fraction, integer;
		int jiao, fen;
		if (val < 0) {
			val = -val;
			SignStr = "负";
		}
		if (val > 99999999999999.999 || val < -99999999999999.999)
			return "数值位数过大!";
		// 四舍五入到分
		long temp = Math.round(val * 100);
		integer = temp / 100;
		fraction = temp % 100;
		jiao = (int) fraction / 10;
		fen = (int) fraction % 10;
		if (jiao == 0 && fen == 0) {
			TailStr = "整";
		} else {
			TailStr = HanDigiStr[jiao];
			if (jiao != 0)
				TailStr += "角";
			if (integer == 0 && jiao == 0) // 零元后不写零几分
				TailStr = "";
			if (fen != 0)
				TailStr += HanDigiStr[fen] + "分";
		}
		// 下一行可用于非正规金融场合,0.03只显示“叁分”而不是“零元叁分”
		// if( !integer ) return SignStr+TailStr;

		// 返回乘以10000以后的值
		return SignStr + PositiveIntegerToHanStr(String.valueOf(integer)) + "元"
				+ TailStr;
	}
	/**
	 * @author dzq 比较日期返回分钟
	 * @return Long
	 */
	public static Long getIntervalMini(String strSmall, String strBig) {
		SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long date1=0L;
		long date2=0L;
		long mini=0L;
		try {
			date1 = f.parse(strSmall).getTime();
			date2=f.parse(strBig).getTime();
			mini=((date2-date1)/1000);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		return (mini/60);

	}
	/**
	 * @author dzq 比较日期返回分钟
	 * @return Long
	 */
	public static Long getIntervalSecond(String strSmall, String strBig) {
		SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long date1=0L;
		long date2=0L;
		long second=0L;
		try {
			date1 = f.parse(strSmall).getTime();
			date2=f.parse(strBig).getTime();
			second=((date2-date1)/1000);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		return (second);

	}
	/**
	 * 返回  增加月份后的日期=日期+加上期限(月份数)
	 * @author dzq 
	 * @param date 日期
	 * @param expires 期限
	 * @return String
	 */
	public static String addExpires(Date date, Integer expires) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, expires);
		Date nDate = calendar.getTime(); 
		SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String newDate=f.format(nDate);
		return newDate;

	}
	/**
	 * 返回  增加月份后的日期=日期+加上期限(月份数)
	 * @author dzq 
	 * @param date 日期
	 * @param expires 期限
	 * @return Date
	 */
	public static Date addExpiresDate(Date date, Integer expires) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, expires);
		Date nDate = calendar.getTime(); 
		return nDate;

	}
	
	/**
	 * ==============================================================================================================================
	 */
	public static void main(String[] args) {

//		 String fromDate = "2008-10-6";
//		 String toDate = "2008-10-9";
//		 Date dateFrom = switchStringToDate(fromDate);
//		 Date dateTo = switchStringToDate(toDate);
		 try {
			// SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//			 int d = getDifferDays2(new Date(),DateUtil.getMonthLastDate(new Date()));
//			System.out.println(getDateStrTime());
			 System.out.println(getIntervalSecond("2015-12-04 10:12:10", "2015-12-05 10:13:10"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		System.out.println(DateUtils.getIntervalMini("2011-06-11 08:17:15", "2011-06-13 08:17:15"));

	}
}
package com.enation.app.shop.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;


public class DateUtil {
	
	private static final String PATTERN_DATE = "yyyy-MM-dd";
	
	private static final String PATTERN_TIME = "HH:mm:ss";
	
	private static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
	
	private static final String PATTERN_FULL = "yyyy-MM-dd HH:mm:ss.SSS";

	
	public static final Date parse(String pattern, String source) {
		try {
			return new SimpleDateFormat(pattern, Locale.US).parse(source);
		} catch (ParseException e) {
			throw new RuntimeException("parse date error : ", e);
		}
	}

	
	public static final Date parseDateTime(String source) {
		try {
			return new SimpleDateFormat(PATTERN_DATETIME).parse(source);
		} catch (ParseException e) {
			throw new RuntimeException("parse date error : ", e);
		}
	}

	
	public static final Date parseDate(String source) {
		try {
			return new SimpleDateFormat(PATTERN_DATE).parse(source);
		} catch (ParseException e) {
			throw new RuntimeException("parse date error : ", e);
		}
	}

	
	public static final Date parseTime(String source) {
		try {
			return new SimpleDateFormat(PATTERN_TIME).parse(source);
		} catch (ParseException e) {
			throw new RuntimeException("parse date error : ", e);
		}
	}

	
	public static final Date parseFull(String source) {
		try {
			return new SimpleDateFormat(PATTERN_FULL).parse(source);
		} catch (ParseException e) {
			throw new RuntimeException("parse date error : ", e);
		}
	}

	
	public static final String format(String pattern, Date date) {
		return new SimpleDateFormat(pattern, Locale.US).format(date);
	}

	
	public static final String formatDateTime(Date date) {
		return new SimpleDateFormat(PATTERN_DATETIME).format(date);
	}

	
	public static final String formatDate(Date date) {
		return new SimpleDateFormat(PATTERN_DATE).format(date);
	}

	
	public static final String formatTime(Date date) {
		return new SimpleDateFormat(PATTERN_TIME).format(date);
	}

	
	public static final String formatFull(Date date) {
		return new SimpleDateFormat(PATTERN_FULL).format(date);
	}

	
	public static final String format(String outPatt, String inPatt, String source) {
		return format(outPatt, parse(inPatt, source));
	}

	
	public static final String getTimestamp(String pattern) {
		return format(pattern, new Date());
	}

	
	public static final int calDValueOfYear(Date fromDate, Date toDate) {
		Calendar sCal = Calendar.getInstance();
		Calendar eCal = Calendar.getInstance();
		sCal.setTime(fromDate);
		eCal.setTime(toDate);

		return eCal.get(Calendar.YEAR) - sCal.get(Calendar.YEAR);
	}

	
	public static final int calDValueOfMonth(Date fromDate, Date toDate) {
		Calendar sCal = Calendar.getInstance();
		Calendar eCal = Calendar.getInstance();
		sCal.setTime(fromDate);
		eCal.setTime(toDate);

		return 12 * (eCal.get(Calendar.YEAR) - sCal.get(Calendar.YEAR)) + (eCal.get(Calendar.MONTH) - sCal.get(Calendar.MONTH));
	}

	
	public static final int calDValueOfDay(Date fromDate, Date toDate) {
		return (int) ((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));
	}

	
	public static final Date getFirstDayOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	
	public static final Date getFirstDayOfWeek(Date date) {
		return getFirstDayOfWeek(date, Calendar.MONDAY);
	}

	
	public static final Date getLastDayOfWeek(Date date) {
		return getLastDayOfWeek(date, Calendar.MONDAY);
	}

	
	public static final Date getFirstDayOfWeek(Date date, int firstDayOfWeek) {
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(firstDayOfWeek);

		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	
	public static final Date getLastDayOfWeek(Date date, int firstDayOfWeek) {
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(firstDayOfWeek);

		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		calendar.add(Calendar.DAY_OF_YEAR, 7);
		calendar.add(Calendar.MILLISECOND, -1);

		return calendar.getTime();
	}

	
	public static final Date[] getWeek(Date date) {
		return getWeek(date, Calendar.MONDAY);
	}

	
	public static final Date[] getWeek(Date date, int firstDayOfWeek) {
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(firstDayOfWeek);

		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date firstDate = calendar.getTime();

		calendar.add(Calendar.DAY_OF_YEAR, 7);
		calendar.add(Calendar.MILLISECOND, -1);
		Date lastDate = calendar.getTime();

		return new Date[] { firstDate, lastDate };
	}

	
	public static java.sql.Date toSQLDate(Date date) {
		return new java.sql.Date(date.getTime());
	}

	
	public static java.sql.Date getSQLDate() {
		return new java.sql.Date(System.currentTimeMillis());
	}
	
	
	public static java.sql.Timestamp getSQLTimestamp() {
		return new java.sql.Timestamp(System.currentTimeMillis());
	}
	
	public static java.sql.Timestamp getTimestamp(int day) {
		return new java.sql.Timestamp(System.currentTimeMillis()+24*60*60*1000*day);
	}

	
	public static Date add(Date date, int field, int increment) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		cal.add(field, increment);
		return cal.getTime();
	}

	
	public static Date set(Date date, int field, int value) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(field, value);
		return cal.getTime();
	}
	
	/**
	 * 当月第一天
	 * @return
	 */
	public static Date getMonthFirstDate(){
		Calendar curCal = Calendar.getInstance();
		curCal.set(Calendar.DAY_OF_MONTH, 1);
		return curCal.getTime();
	}
	
	/**
	 * 当月最后一天
	 * @return
	 */
	public static Date getMonthLastDate(){
		Calendar curCal = Calendar.getInstance();
		curCal.set(Calendar.DATE, 1);  
		curCal.roll(Calendar.DATE, - 1);  
		return curCal.getTime();
	}
	
	/**
	 * 当月最后一天
	 * @return
	 */
	public static Date getMonthLastDate(Date date){
		Calendar curCal = Calendar.getInstance();
		curCal.setTime(date);
		curCal.set(Calendar.DATE, 1);  
		curCal.roll(Calendar.DATE, - 1);  
		return curCal.getTime();
	}
	
	/**
	 * 当月最后一天
	 * @return
	 */
	public static Date getSqMonthLastDate(Date date, Integer sq){
		Calendar curCal = Calendar.getInstance();
		curCal.setTime(date);
		curCal.add(Calendar.MONTH, sq);
		curCal.set(Calendar.DATE, 1);  
		curCal.roll(Calendar.DATE, - 1);  
		return curCal.getTime();
	}
	
	/**
	 * 获取一个月以前
	 * @return
	 */
	public static Date getMonthBefore(){
		return DateUtil.getNDatesBefore(-30);
	}
	
	/**
	 * 获取多少天之前
	 * n为正数是,表示多少天后
	 * 负数时,表示多少天前
	 * @param n
	 * @return
	 */
	public static Date getNDatesBefore(Integer n){
		Calendar curCal = Calendar.getInstance();
		curCal.add(Calendar.DATE, n);
		return curCal.getTime();
	}

    
    public Integer getMonthWeekCount(Date date){
    	Calendar c = Calendar.getInstance();
    	int week = c.get(Calendar.WEEK_OF_MONTH);//获取是本月的第几周
    	return week;
    }
    
    /**
	 * 给任意一个日期,输出当周的周一
	 * 周日要回退几天
	 * @return
	 */
	public static Date getMonday(Date date) {
		Calendar curCal = Calendar.getInstance();
		curCal.setTime(date);
		int week  = curCal.get(Calendar.DAY_OF_WEEK);
		//周日的话回退几天,找周一
		if(week == Calendar.SUNDAY)
			curCal.add(Calendar.DATE, -3);
		curCal.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);
	    return curCal.getTime();   
	}

	
	public static void main(String[] args) {		
		System.out.println(DateUtil.getTimestamp("yyyyMMdd"));
		
		
		String str=DateUtil.formatDate(DateUtil.add(new Date(), Calendar.DAY_OF_YEAR, -30));
		System.out.println(str);
		
	}
	
}
package com.enation.app.shop.core.utils;


import java.io.Serializable;

public class IpInfo implements Serializable {

	private static final long serialVersionUID = 1L;

	private String region;// 省
	private String city;// 市
	private String county;// 区
	private String isp;// ISP公司
	private String citySimpleName;// 市级简称

	public IpInfo() {
		super();
	}

	public IpInfo(String region, String city) {
		super();
		this.region = region;
		this.city = city;
	}

	public IpInfo(String region, String city, String county) {
		super();
		this.region = region;
		this.city = city;
		this.county = county;
	}

	public String getRegion() {
		return region;
	}

	public void setRegion(String region) {
		this.region = region;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getCounty() {
		return county;
	}

	public void setCounty(String county) {
		this.county = county;
	}

	public String getIsp() {
		return isp;
	}

	public void setIsp(String isp) {
		this.isp = isp;
	}

	public String getCitySimpleName() {
		if (city != null) {
			citySimpleName = city.replace("市", "").replace("地区", "");
		}
		return citySimpleName;
	}

	public void setCitySimpleName(String citySimpleName) {
		this.citySimpleName = citySimpleName;
	}

}
package com.enation.app.shop.core.utils;


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class IpUtils {

	/**
	 * 获得用户远程地址
	 */
	public static String getRemoteAddr(HttpServletRequest request) {
		String remoteAddr = request.getHeader("X-Real-IP");
		if (StringUtils.isNotBlank(remoteAddr)) {
			remoteAddr = request.getHeader("X-Forwarded-For");
		} else if (StringUtils.isNotBlank(remoteAddr)) {
			remoteAddr = request.getHeader("Proxy-Client-IP");
		} else if (StringUtils.isNotBlank(remoteAddr)) {
			remoteAddr = request.getHeader("WL-Proxy-Client-IP");
		}
		return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
	}

	public static void main(String[] args) {
		String ip = "183.58.24.176";

		try {
			IpInfo ipInfo = IpUtils.getIpInfo(ip);
//			System.out.println(ipInfo.getRegion() + ipInfo.getCity()
//					+ ipInfo.getCounty() + "   " + ipInfo.getIsp());
			System.out.println(ipInfo.getCity()
					+ ipInfo.getCounty() );
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static IpInfo getIpInfo(HttpServletRequest request) {
		String ip = getRemoteAddr(request);

		IpInfo ipInfo = getIpInfo(ip);

		if (ipInfo == null || StringUtils.isBlank(ipInfo.getCity())) {
			ipInfo = new IpInfo();
		}

		System.out.println("访问ip:" + ip + "  " + ipInfo.getRegion()
				+ ipInfo.getCity() + ipInfo.getCounty() + "   "
				+ ipInfo.getIsp());
		return ipInfo;
	}

	/**
	 * 获取地址
	 * 
	 * @param ip
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	public static IpInfo getIpInfo(String ip) {
		String path = "http://ip.taobao.com/service/getIpInfo.php";
		String params = "ip=" + ip;
		String returnStr = doGet(path, params, "utf-8");
		if (returnStr != null) {
			Gson gson = new Gson();
			JsonParser parser = new JsonParser();
			JsonObject json = parser.parse(returnStr).getAsJsonObject();
			if ("0".equals(json.get("code").toString())) {
				return gson.fromJson(json.get("data"), IpInfo.class);
			}
		}
		return null;
	}

	/**
	 * 从url获取结果
	 * 
	 * @param path
	 * @param params
	 * @param encoding
	 * @return
	 */
	public static String doGet(String path, String params, String encoding) {
		URL url = null;
		HttpURLConnection connection = null;
		try {
			url = new URL(path);
			connection = (HttpURLConnection) url.openConnection();// 新建连接实例
			connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒
			connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒
			connection.setDoInput(true);// 是否打开输入流true|false
			connection.setDoOutput(true);// 是否打开输出流true|false
			connection.setRequestMethod("GET");// 提交方法POST|GET
			connection.setUseCaches(false);// 是否缓存true|false
			connection.connect();// 打开连接端口
			DataOutputStream out = new DataOutputStream(
					connection.getOutputStream());
			out.writeBytes(params);
			out.flush();
			out.close();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					connection.getInputStream(), encoding));
			StringBuffer buffer = new StringBuffer();
			String line = "";
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			reader.close();
			return buffer.toString();
		} catch (SocketTimeoutException socketTimeoutException) {
			return null;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.disconnect();// 关闭连接
			}
		}
		return null;
	}

}

html页面

var opentime;//打开页面的时间
var closetime;//关闭页面的时间
Date.prototype.Format = function (fmt) { //author: meizz 
    var o = {
        "M+": this.getMonth() + 1, //月份 
        "d+": this.getDate(), //日 
        "h+": this.getHours(), //小时 
        "m+": this.getMinutes(), //分 
        "s+": this.getSeconds(), //秒 
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
        "S": this.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

	function checkLeave(){ 
		closetime = new Date().Format("yyyy-MM-dd hh:mm:ss");  
		 var html=window.location.href;
		/*  event.returnValue="确定离开当前页面吗?"+html;  */
$.ajax({
	url:"${ctx}/api/shop/logtime!addLogtime.do?ajax=yes",
	dataType:"json",
	cache: true,
	data:{
		opentime:opentime,
		closetime:closetime,
		html:html
	},
	success:function(result){
		if(result.result==1){
		}else{
			/* layer.msg("出错了", { icon: 7,time: 2000 }, function(){});  */
		}	
		/* layer.close(index);  */
	},
	error:function(){
		/* layer.close(index);  */
		/* layer.msg("出错了:(", { icon: 7,time: 2000 }, function(){});  */
	}
});
}
	$(function(){
		opentime = new Date().Format("yyyy-MM-dd hh:mm:ss");  
	});

  

原文地址:https://www.cnblogs.com/nbkyzms/p/5116459.html