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

    /**
     * @param date
     * @return
     * @author renmb
     * @time 2016年10月1日
     */
    public static Date toUTCTimeZone(Date date) {
        try {
            TimeZone oldZone = TimeZone.getTimeZone("GMT+08:00");
            TimeZone newZone = TimeZone.getTimeZone("UTC");

            return changeTimeZone(date, oldZone, newZone);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }

    /**
     * 时区转换
     *
     * @param date
     * @param oldZone
     * @param newZone
     * @return
     * @author renmb
     * @time 2016年10月1日
     */
    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());

        } catch (Exception e) {
            e.printStackTrace();
        }
        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) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date stringToDate(String str) {
        if (null == str || str.equals("")) {
            return null;
        }
        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;
        }
        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 date
     * @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 date    - 日期对象
     * @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 date
     * @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));
            //月份加num
            calendar.add(Calendar.MONTH, 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   日期
     * @param 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    日期
     * @param offset  时间偏移量
     * @param 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   日期
     * @param 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   日期
     * @param 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;
    }

    /**
     * 取日期字符串
     *
     * @param date
     * @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;
    }


}
