package com.foc.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

import org.apache.commons.lang3.StringUtils;

public class DateUtil {
    
    //默认显示日期的格式
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String TIMEF_FORMAT = "yyyy-MM-dd HH:mm:ss";
    //默认显示日期时间毫秒格式
    public static final String MSEL_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
    //默认显示简体中文日期的格式
    public static final String ZHCN_DATE_FORMAT = "yyyy年MM月dd日";
    //默认显示简体中文日期时间的格式
    public static final String ZHCN_TIME_FORMAT = "yyyy年MM月dd日HH时mm分ss秒";
    //默认显示简体中文日期时间毫秒格式
    public static final String ZHCN_MSEL_FORMAT = "yyyy年MM月dd日HH时mm分ss秒SSS毫秒";
    //获取日期串格式
    public static final String DATE_STR_FORMAT = "yyyyMMdd";
    //获取日期时间串格式
    public static final String TIME_STR_FORMAT = "yyyyMMddHHmmss";
    //获取日期时间毫秒串格式
    public static final String MSEL_STR_FORMAT = "yyyyMMddHHmmssSSS";
    
    private static DateFormat dateFormat = null;
    private static DateFormat dateTimeFormat = null;
    private static DateFormat zhcnDateFormat = null;
    private static DateFormat zhcnDateTimeFormat = null;
    private static DateFormat zhcnDateStrFormat = null;
    
    public static enum TimeType{
        HOUR_TO_MINUTE
    }
    
    static {
        zhcnDateStrFormat = new java.text.SimpleDateFormat(DATE_STR_FORMAT);
        dateFormat = new SimpleDateFormat(DATE_FORMAT);
        dateTimeFormat = new SimpleDateFormat(TIMEF_FORMAT);
        zhcnDateFormat = new SimpleDateFormat(ZHCN_DATE_FORMAT);
        zhcnDateTimeFormat = new SimpleDateFormat(ZHCN_TIME_FORMAT);
    }
    
    //每小时的毫秒数
    public static int HOUR_MILLI_SECOND = 60 * 60 *1000;
    public static int MINUTE_MILLI_SECOND = 60 * 1000;
    
    public static String getDateTime(){
        DateFormat format = new SimpleDateFormat(TIMEF_FORMAT);
        return format.format(System.currentTimeMillis());
    }
    public static String getDateTime(Date time){
        DateFormat format = new SimpleDateFormat(TIMEF_FORMAT);
        return format.format(time);
    }
    public static String getDurationTime(long time){
        
        String buffer = "";
        buffer = ":"+time%1000+"纳秒";
        time   = time/1000;//微秒
        buffer = ":"+time%1000+"微秒"+buffer;
        time   = time/1000;//毫秒
        buffer = ":"+time%1000+"毫秒"+buffer;
        time   = time/1000;//毫秒
        buffer = ":"+time%60+"秒"+buffer;
        time   = time/60;//秒
        buffer =time+"分钟"+buffer;
        return buffer;
    }
    /**
     * 
     * 
     * @author renmb
     * @time  2016年10月1日
     * @param date
     * @return
     */
    public static Date toUTCTimeZone(Date date) {
        try {
//            TimeZone bjtz = TimeZone.getTimeZone("Asia/Shanghai");
//            TimeZone bjtz = TimeZone.getDefault();
            TimeZone oldZone = TimeZone.getTimeZone("GMT+08:00");
            TimeZone newZone = TimeZone.getTimeZone("UTC");
//            int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
            
            return changeTimeZone(date, oldZone, newZone);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    /**
     * 时区转换
     * 
     * @author renmb
     * @time  2016年10月1日
     * @param date
     * @param oldZone
     * @param newZone
     * @return
     */
    public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone) {
        try {
            
            GregorianCalendar localGregorianCalendar1 = new GregorianCalendar(oldZone);
            localGregorianCalendar1.setTime(date);
            
            GregorianCalendar localGregorianCalendar2 = new GregorianCalendar(newZone);
            localGregorianCalendar2.setTimeInMillis(localGregorianCalendar1.getTimeInMillis());
            
            return new Date(localGregorianCalendar2.getTimeInMillis());
            
//            Date dateTmp = null;
//            if (date != null && oldZone != null && newZone != null) {
//                int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
//                dateTmp = new Date(date.getTime() - timeOffset);
//            }
//            return dateTmp;
        } catch (Exception e) {
            // TODO: handle exception
        }
        return date;
    }
    /**
     * @param formatStr
     * @return
     */
    public static DateFormat getDateFormat(String formatStr) {
        if (formatStr.equalsIgnoreCase(DATE_FORMAT)) {
            return dateFormat;
        } else if (formatStr.equalsIgnoreCase(TIMEF_FORMAT)) {
            return dateTimeFormat;
        } else if (formatStr.equalsIgnoreCase(ZHCN_DATE_FORMAT)) {
            return zhcnDateFormat;
        } else if (formatStr.equalsIgnoreCase(ZHCN_TIME_FORMAT)) {
            return zhcnDateTimeFormat;
        } else if(formatStr.equalsIgnoreCase(DATE_STR_FORMAT)){
            return zhcnDateStrFormat;
        }else {
            return new SimpleDateFormat(formatStr);
        }
    }
    
    /**
     * 按照默认formatStr的格式，转化dateTimeStr为Date类型
     * dateTimeStr必须是formatStr的形式
     * @param dateTimeStr
     * @param formatStr
     * @return
     */
    public static Date parse(String dateTimeStr, String formatStr) {
        try {
            if (dateTimeStr == null || dateTimeStr.equals("")) {
                return null;
            }
            DateFormat sdf = getDateFormat(formatStr);
            java.util.Date d = sdf.parse(dateTimeStr);
            return d;
        } catch (ParseException e) {
            //throw new LangException(e);
        }
        return null;
    }

    public static Date stringToDate(String str) {
        if (null == str || str.equals(""))
            return null;
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
        // modify by shizhongwen 2009-05-21 针对香港所传过来的String 如: Wed Feb 23
        // 10:12:34 CST 2009
        if (0 < str.indexOf("CST")) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
                Date d = sdf.parse(str);
                return d;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    
    public static Date stringToDatetwo(String str) {
        if (null == str || str.equals(""))
            return null;
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
        // modify by shizhongwen 2009-05-21 针对香港所传过来的String 如: Wed Feb 23
        // 10:12:34 CST 2009
        if (0 < str.indexOf("CST")) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
                Date d = sdf.parse(str);
                return d;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.CHINA);
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    
    public static Date stringToDateThree(String str) {
        if (null == str || str.equals(""))
            return null;
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
        // modify by shizhongwen 2009-05-21 针对香港所传过来的String 如: Wed Feb 23
        // 10:12:34 CST 2009
        if (0 < str.indexOf("CST")) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
                Date d = sdf.parse(str);
                return d;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy", Locale.CHINA);
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 得到几天前的时间 
     * @param d
     * @param day 天数
     * @return
     */
    public static Date getDateBefore(Date date, int day) {  
        if(null == date)
            return null;
        Calendar now = Calendar.getInstance();  
        now.setTime(date);  
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);  
        return now.getTime();  
    }  
    
    /**
     * 获取指定日后之后几天的日期
     * 
     * @param date
     * @param i
     * @return
     */
    public static Date getDate(Date date, int i) {

        if (null == date)
            return null;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, i);

        return calendar.getTime();

    }
    
    public static Date getSystemDate(){
        return Calendar.getInstance().getTime();
    }
    
    /**
     * 把日期对象转换成指定格式的字符串
     * 
     * @param dDate
     *            - 日期对象
     * @param sFormat
     *            - 日期格式@return String yyyy-MM-dd HH:mm:ss
     */
    public static String dateToStr(Date date, String sFormat) {        
        if (null == date)
            return "";
        
        SimpleDateFormat df = new SimpleDateFormat(sFormat);
        return df.format(date);
    }
    
    public static String dateToStrLocal(Date date, String sFormat) {
        if (null == date)
            return "";
        
        SimpleDateFormat df = new SimpleDateFormat(sFormat,new Locale("US"));
        return df.format(date);
    }
    
    
    
    /** 
    *得到当前月份的第一天和最后一天 
    **/ 
    public static String getMonthEndDay(Date date){ 
        Calendar cal = Calendar.getInstance(); 
        cal.setTime(date);
        // 当前月＋1
        cal.add(cal.MONTH, 1);
        // 将下个月1号作为日期初始化
        cal.set(cal.DATE, 1); 
        // 下个月1号减去一天，即得到当前月最后一天 
        cal.add(cal.DATE, -1); 
        java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd"); 
        return df.format(cal.getTime()); 
    } 
    
    

    /**
     * 根据年月得到输入月份的天数
     * */
     public static int getDays(int m, int n) {
      int allday;
      int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
      Calendar cal = Calendar.getInstance();
      cal.set(Calendar.YEAR, m);
      cal.set(Calendar.MONTH, n - 1);
      cal.set(Calendar.DATE, 1);
      if ((m % 4 == 0 && m % 100 != 0 || m % 400 == 0) && n == 2)
       days[1]++;
      allday = days[n - 1];
      
      return allday;
     }
     
     /**
      * 字符串转Date
      * @param dateStr
      * @return
      */
     public static Date getStringToDate(String dateStr){
         Date date = new Date();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
         try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
         return date;
     }
     
          
     public static Date dateToDate(Date date, String sFormat){
            if (null == date)
                return null;
            
            SimpleDateFormat df = new SimpleDateFormat(sFormat);
            try {
                return df.parse(df.format(date));
            } catch (ParseException e) {
                e.printStackTrace();
                return null;
            }
    }
     
     /**
      * 获取当月第一天
      * @param sFormat
      * @return Date
      */
     public static Date getFirstDay(Date date ){
         Calendar cal = Calendar.getInstance();
         cal.setTime(date);
         cal.set(cal.DATE, 1);
         return  cal.getTime();
     }
     
    /**
     *  获取当月第一天
     * @param date
     * @param sFormat
     * @return String date
     */
     public static String getFirstDay(String date,String sFormat ){
        try {
            SimpleDateFormat df = new SimpleDateFormat(sFormat);
             Calendar cal = Calendar.getInstance();
             cal.setTime(df.parse(date));
             cal.set(cal.DATE, 1);
             return  df.format(cal.getTime());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
     }
     
     /**
      * 获取当月最后一天
      * @param date
      * @param sFormat
      * @return String date
      */
     public static String getEndDay(String date,String sFormat  ){
        try {
            SimpleDateFormat df = new SimpleDateFormat(sFormat);
            Calendar cal = Calendar.getInstance();
            cal.setTime(df.parse(date));
            // 当前月＋1，即下个月
            cal.add(cal.MONTH, 1);
            // 将下个月1号作为日期初始zhii
            cal.set(cal.DATE, 1);
            // 下个月1号减去一天，即得到当前月最后一天
            cal.add(cal.DATE, -1);
            
            return  df.format(cal.getTime());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return  null;
        }
     }
     
     /**
      * 获取当月最后一天
      * @param date
      * @return   date
      */
     public static Date getEndDay(Date date ){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 当前月＋1，即下个月
        cal.add(cal.MONTH, 1);
        // 将下个月1号作为日期初始zhii
        cal.set(cal.DATE, 1);
        // 下个月1号减去一天，即得到当前月最后一天
        cal.add(cal.DATE, -1);
        
        return  cal.getTime();
     }
     public static Date stringToDate(String str,String format) {
            if (null == str || str.equals(""))
                return null;
            
            if(format==null || format.equals("")){
                format="yyyy-MM-dd HH:mm:SS";
            }
            
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            
            try {
                return sdf.parse(str);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            
            return null;
    }
     
    /**
     * date 为指定时间  2012-12-12 14:23:00,N为获取时间为N小时之后的时间
     * @param date
     * @param n
     * @return
     */
    public static Date getDateAffterHour(Date date,int n) {
        if(null == date) return null;
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(date.getTime() + n * DateUtil.HOUR_MILLI_SECOND);
        return c.getTime();
    }
    
    /**
     * date 为指定时间  2012-12-12 14:23:00,N为获取时间为N小时之后的时间
     * @param date
     * @param n
     * @return
     */
    public static Date getDateAffterMinute(Date date,int n) {
        if(null == date) return null;
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(date.getTime() + n * DateUtil.MINUTE_MILLI_SECOND);
        return c.getTime();
    }
    
    public static Date stringToDateHH(String str) {
        if (null == str || str.equals(""))
            return null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static Date dateToDateFormat(Date date,String format){
        if(null == date) return null;
        if(format==null || format.equals("")){
            format="yyyy-MM-dd HH:mm:SS";
        }
        SimpleDateFormat df = new SimpleDateFormat(format, Locale.CHINA);

        try {
            return df.parse(df.format(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        
        return null;
        
    }
    
    /**
     * 日期格式转换
     * 
     * @param date 要转换的日期
     * @param oriPattern date原来的日期格式
     * @param destPattern 要转换成的日期格式
     * @return
     */
    public static String transferDate(String date,String oriPattern,String destPattern){
        if(StringUtils.isBlank(date)){
            return "";
        }
        SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat.getDateInstance(0,Locale.ENGLISH);
        sdf.applyPattern(oriPattern);
        
        try {
            Date parse = sdf.parse(date);
            sdf.applyPattern(destPattern);
            
            return sdf.format(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        finally{
            sdf = null;
        }
        return "";
    }
    /**
     * 获得
     * @param date 
     * @param format 
     * @param num 获得num个月之后的日期 
     * @return
     */
    public static String getNextMonth(String date,String format,Integer num){
          try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);//格式化对象
              Calendar calendar = Calendar.getInstance();//日历对象
              calendar.setTime(sdf.parse(date));//设置当前日期
              calendar.add(Calendar.MONTH, num);//月份加num
             return sdf.format(calendar.getTime());//输出格式化的日期
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    
    /** 
        * 判断给定日期是否为月末的一天 
        * 
        * @param date 
        * @return true:是|false:不是 
        */ 
        public static boolean isLastDayOfMonth(Date date) { 
            Calendar calendar = Calendar.getInstance(); 
            calendar.setTime(date); 
            calendar.set(Calendar.DATE, (calendar.get(Calendar.DATE) + 1)); 
            if (calendar.get(Calendar.DAY_OF_MONTH) == 1) { 
                return true; 
            } 
            return false; 
        } 
        
        /** 
            * 判断给定日期是否为月初的一天 
            * 
            * @param date 
            * @return true:是|false:不是 
            */    
        public static boolean isFirstDayOfMonth(Date date){
             Calendar calendar = Calendar.getInstance(); 
                calendar.setTime(date); 
                if (calendar.get(Calendar.DAY_OF_MONTH) == 1) { 
                    return true; 
                } 
                return false; 
        }
        
        /**
         * 获得日期的年月 
         * @param date
         * @param format
         * @return 返回的年月格式为 yyyyMM 例如：201504
         */
        public static String getYearMonth(String date,String format){
            try {
                String yyyyMM="";
                SimpleDateFormat sdf = new SimpleDateFormat(format);//格式化对象
                 Calendar cal=Calendar.getInstance();//使用日历类
                 cal.setTime(sdf.parse(date));
                  int year=cal.get(Calendar.YEAR);//得到年
                  int month=cal.get(Calendar.MONTH)+1;//得到月，因为从0开始的，所以要加1
                  if(month<10){//月份格式 yyyyMM
                      yyyyMM= year+"0"+month;
                  }else{
                      yyyyMM=year+""+month;
                  }
                 return yyyyMM;
            } catch (ParseException e) {
                e.printStackTrace();
                return null;
            }
        } 
        
        /**
         * 获取date + offset 日期加上offset偏移天数凌晨的时间
         * @param Date date 日期
         * @param int offset 时间偏移量
         * @return
         * @author panjianlin
         * @date 2015-09-08
         */
        public static Date getOffsetDawn(Date date,int offset){
            Date offsetDate = offsetDate(date, offset);
            String dateStr = dateFormat.format(offsetDate);
            String dateTimeStr = dateStr + " 00:00:00";
            Date dateTime = null;
            try {
                dateTime = dateTimeFormat.parse(dateTimeStr);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return dateTime;
        }
        
        /**
         * 获取date + offset 日期加上offset偏移天数的时间
         * @param Date date 日期
         * @param int offset 时间偏移量
         * @param String subTime 小时到秒的时间字符串 如  " 11:59:15"
         * @return
         * @author panjianlin
         * @date 2015-09-08
         */
        public static Date getOffsetDate(Date date,int offset,String subTime){
            Date offsetDate = offsetDate(date, offset);
            String dateStr = dateFormat.format(offsetDate);
            String dateTimeStr = dateStr + subTime;
            Date dateTime = null;
            try {
                dateTime = dateTimeFormat.parse(dateTimeStr);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return dateTime;
        }
        
        /**
         * 获取date + offset 日期加上offset偏移天数的时间
         * @param Date date 日期
         * @param int offset 时间偏移量
         * @return Date
         * @author panjianlin
         * @date 2015-09-08
         */
        public static Date offsetDate(Date date,int offset){
            Calendar cal = Calendar.getInstance();
            //转换成Calendar类型
            cal.setTime(date);
            //添加偏移时间
            cal.add(Calendar.DATE, offset);
            //转换成date类型
            Date goalDate =  cal.getTime();
            return goalDate;
        }
        
        /**
         * 获取date + offset 日期加上offset偏移分钟数
         * @param Date date 日期
         * @param int offset 时间偏移量
         * @return Date
         * @author panjianlin
         * @date 2015-09-08
         */
        public static Date offsetMinute(Date date,int offset){
            Calendar cal = Calendar.getInstance();
            //转换成Calendar类型
            cal.setTime(date);
            //添加偏移时间
            cal.add(Calendar.MINUTE, offset);
            //转换成date类型
            Date goalDate =  cal.getTime();
            return goalDate;
        }
    
    public static void main(String args[]){
        System.out.println(offsetMinute(new Date(), -10));
    
    }

    /**
     * 取日期字符串
     * @param atd
     * @param timeType 时间段  比如hh:mm则为枚举型 HOUR_TO_MINUTE
     * @return
     */
    public static String splitDateToStrSub(Date date, TimeType timeType) {
        
        String dateSubStr = null;
        if(date == null){
            return null;
        }
        
        String dateStr = dateToStr(date,TIMEF_FORMAT);
        
        if(timeType == TimeType.HOUR_TO_MINUTE){
            dateSubStr = dateStr.substring(11, 16);
        }
        
        return dateSubStr;
    }

    /**
     * 从一种日期格式转换到另一种日期格式
     * 比如  2015-01-02 12:01:21  -----  2015-01-02
     * 或  2015-01-02   ---- 2015/01/02
     * @param date
     * @param format
     * @return
     */
    public static Date getDateToDate(Date date, String format) {
        Date tdate = null;
        if(date == null){
            return null;
        }
        try{
            DateFormat sdf = getDateFormat(format);
            date = sdf.parse(sdf.format(date));
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
                
        return tdate;
    }
    
    

}
