/*
 * $Id: DateUtil.java 27 2014-07-01 03:11:10Z guyejun $
 */

package com.fr.tx.common.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 擔晅娭楢儐乕僥傿儕僥傿僋儔僗
 * @version 1.0
 * @author guga
 */
public final class DateUtil {

    /**
     * 僐儞僗僩儔僋僞
     */
    private DateUtil() {

    }

    /** 僷僞乕儞(yyyyMMdd) */
    public static final String DATE_PATTERN_0 = "yyyyMMdd";

    /** 僷僞乕儞(yyyyMMddHHmmssSSS) */
    public static final String DATE_PATTERN_1 = "yyyyMMddHHmmssSSS";

    /** 僷僞乕儞(yyyy/MM/dd) */
    public static final String DATE_PATTERN_2 = "yyyy/MM/dd";

    /** 僷僞乕儞(yyyy/MM/dd HH:mm:ss) */
    public static final String DATE_PATTERN_3 = "yyyy/MM/dd HH:mm:ss";

    /** 僷僞乕儞(yy/MM/dd) */
    public static final String DATE_PATTERN_4 = "yy/MM/dd";

    /** 僷僞乕儞(yyyy/MM/dd HH:mm:ss.SSS) */
    public static final String DATE_PATTERN_5 = "yyyy/MM/dd HH:mm:ss.SSS";

    /** 僷僞乕儞(yyyyMM) */
    public static final String DATE_PATTERN_6 = "yyyyMM";

    /** 僷僞乕儞(yyMMdd) */
    public static final String DATE_PATTERN_7 = "yyMMdd";

    /** 僷僞乕儞(yyyy-MM-dd HH:mm:ss.SSS) */
    public static final String DATE_PATTERN_8 = "yyyy-MM-dd HH:mm:ss.SSS";

    /** 僷僞乕儞(yyyy/MM/dd HH:mm) */
    public static final String DATE_PATTERN_9 = "yyyy/MM/dd HH:mm";

    /** 僷僞乕儞(yyyy/MM) */
    public static final String DATE_PATTERN_10 = "yyyy/MM";

    /** 僷僞乕儞(yyyyMMddHHmmss) */
    public static final String DATE_PATTERN_11 = "yyyyMMddHHmmss";

    /** 僷僞乕儞(yyyy擭MM寧dd擔) */
    public static final String DATE_PATTERN_12 = "yyyy擭MM寧dd擔";

    /** 僷僞乕儞(yy/MM) */
    public static final String DATE_PATTERN_13 = "yy/MM";

    /** 僷僞乕儞(yy/MM/dd HH:mm:ss) */
    public static final String DATE_PATTERN_14 = "yy/MM/dd HH:mm:ss";

    /** 僷僞乕儞(yy擭MM寧dd擔) */
    public static final String DATE_PATTERN_15 = "yy擭MM寧dd擔";

    /** 僷僞乕儞(yy/MM/dd HH:mm) */
    public static final String DATE_PATTERN_16 = "yy/MM/dd HH:mm";

    /** 僷僞乕儞(yyyy-MM-dd) */
    public static final String DATE_PATTERN_17 = "yyyy-MM-dd";

    /** 僷僞乕儞(MMM. dd, yyyy) */
    public static final String DATE_PATTERN_18 = "MMM.  dd, yyyy";

    /** 僷僞乕儞(yyyy.MM.dd) */
    public static final String DATE_PATTERN_19 = "yyyy.MM.dd";

    /** 僷僞乕儞(yy.MM.dd) */
    public static final String DATE_PATTERN_20 = "yy.MM.dd";

    /** 僷僞乕儞(MMMMM dd, yyyy) */
    public static final String DATE_PATTERN_21 = "MMMMM dd, yyyy";

    /** 僷僞乕儞(yyyy-MM-dd.HH.mm.ss.SSS) */
    public static final String DATE_PATTERN_22 = "yyyy-MM-dd HH:mm:ss";

    /** 僷僞乕儞(MMM dd HH:mm:ss yyyy z) */
    public static final String DATE_PATTERN_23 = "MMM dd HH:mm:ss yyyy z";
    
    /** 僷僞乕儞(yyyyMMddHHmmss) */
    public static final String DATE_PATTERN_24 = "yyyyMMddHHmm";
    /** 僷僞乕儞(yyyy-MM-dd HH:mm) */
    public static final String DATE_PATTERN_25 = "yyyy-MM-dd HH:mm";
    /** 僷僞乕儞(yyyyMMddHH) */
    public static final String DATE_PATTERN_26 = "yyyyMMddHH";

    /** Locale(US) */
    public static final Locale LOCALE_US = Locale.US;

    /** 僔僗僥儉擔帪娫 */
    private static Timestamp curTimestamp = null;

    /**
     * 悢帤寧傪庢摼偡傞丅
     */
    private static Map<String, String> formatMonths = new HashMap<String, String>();

    static {
        formatMonths.put("JAN. ", "01");
        formatMonths.put("FEB. ", "02");
        formatMonths.put("MARCH", "03");
        formatMonths.put("APR. ", "04");
        formatMonths.put("MAY  ", "05");
        formatMonths.put("JUNE ", "06");
        formatMonths.put("JULY ", "07");
        formatMonths.put("AUG. ", "08");
        formatMonths.put("SEPT.", "09");
        formatMonths.put("OCT. ", "10");
        formatMonths.put("NOV. ", "11");
        formatMonths.put("DEC. ", "12");
    }

    /**
     * 悢帤寧儅僢僾傪庢摼偡傞丅
     * @return 悢帤寧儅僢僾
     */
    public static Map<String, String> getFormatMonths() {

        return formatMonths;
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄擔晅傪僼僅乕儅僢僩偡傞.
     * <p>
     * 擖椡偱偒傞僼僅乕儅僢僩: <br>
     * &quot;yyyyMMdd&quot; <br>
     * &quot;yyyy/MM/dd HH:mm:ss.SSS&quot; <br>
     * 偦偺懠僼僅乕儅僢僩偼java.text.SimpleDateFormat傪嶲徠偟偰偔偩偝偄丅 <br>
     * 巊梡椺丗 <br>
     * DateUtil.toString(DateUtil.toDate(&quot;20030918&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyyMMdd&quot;)偺寢壥偼 20030918
     * DateUtil.toString(DateUtil.toDate(&quot;20030918&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyy/MM/dd&quot;)偺寢壥偼 2003/09/18
     * DateUtil.toString(DateUtil.toDate(&quot;17000101&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyy-MM-dd HH:mm:ss.SSS&quot;)偺寢壥偼
     * 1700-01-01 00:00:00.0
     * @param date 擖椡偟偨擔晅
     * @param format 擖椡偟偨僼僅乕儅僢僩
     * @return 拝懼偊傞僗僩儕儞僌
     * @see java.text.SimpleDateFormat
     */
    public static String formatDate(java.util.Date date, String format) {

        if (null == date) {
            return null;
        }
        SimpleDateFormat sdFromat = new SimpleDateFormat(format);
        return sdFromat.format(date);
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偲Locale偵傛偭偰丄擔晅傪僼僅乕儅僢僩偡傞.
     * <p>
     * 擖椡偱偒傞僼僅乕儅僢僩: <br>
     * &quot;yyyyMMdd&quot; <br>
     * &quot;yyyy/MM/dd HH:mm:ss.SSS&quot; <br>
     * 偦偺懠僼僅乕儅僢僩偼java.text.SimpleDateFormat傪嶲徠偟偰偔偩偝偄丅 <br>
     * 巊梡椺丗 <br>
     * DateUtil.toString(DateUtil.toDate(&quot;20030918&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyyMMdd&quot;)偺寢壥偼 20030918
     * DateUtil.toString(DateUtil.toDate(&quot;20030918&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyy/MM/dd&quot;)偺寢壥偼 2003/09/18
     * DateUtil.toString(DateUtil.toDate(&quot;17000101&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyy-MM-dd HH:mm:ss.SSS&quot;)偺寢壥偼
     * 1700-01-01 00:00:00.0
     * @param date 擖椡偟偨擔晅
     * @param format 擖椡偟偨僼僅乕儅僢僩
     * @param locale 擖椡偟偨尵岅嬫暘
     * @return 拝懼偊傞僗僩儕儞僌
     * @see java.text.SimpleDateFormat
     */
    public static String formatDate(java.util.Date date, String format, Locale locale) {

        if (null == date) {
            return null;
        }
        SimpleDateFormat sdFromat = new SimpleDateFormat(format, locale);
        return sdFromat.format(date);
    }

    /**
     * 僔僗僥儉擔帪傪庢摼偡傞丅
     * @return 僔僗僥儉擔帪
     */
    public static Timestamp currentTimestamp() {

        if (null == curTimestamp) {
            return new Timestamp(System.currentTimeMillis());
        } else {
            return curTimestamp;
        }
    }
    
    /**
     * 僔僗僥儉擔帪傪庢摼偡傞丅
     * @return 僔僗僥儉擔帪
     */
    public static Timestamp currentTimestamp1(long time) {

        if (null == curTimestamp) {
            return new Timestamp(time);
        } else {
            return curTimestamp;
        }
    }
    
    /**
     * 僔僗僥儉擔帪傪庢摼偡傞丅
     * @return 僔僗僥儉擔帪
     */
    public static Timestamp currentTimestampFt() {

        if (null == curTimestamp) {
            
            return new Timestamp(toDate(getCurrentDate(DATE_PATTERN_22), DATE_PATTERN_22).getTime());
        } else {
            return curTimestamp;
        }
    }
    
    /**
     * 僔僗僥儉擔帪傪庢摼偡傞丅
     * @return 僔僗僥儉擔帪
     */
    public static Date currentDate() {

        Date date = new Date();
        return date;
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄僔僗僥儉擔晅庢摼丅
     * @param format 僼僅乕儅僢僩
     * @return 擔晅
     */
    public static String getCurrentDate(String format) {

        return formatDate(currentTimestamp(), format);
    }
    
    public static String getCurrentDate1(long time,String format) {

        return formatDate(currentTimestamp1(time), format);
    }

    /**
     * 巜掕偝傟偨擔晅偵傛偭偰丄僔僗僥儉擔晅墘嶼婡擻(yyyyMMdd)
     * @param date 巜掕擔晅
     * @param days 捛壛偝傟傞擔晅
     * @return String 擔晅
     */
    public static String addDays(String date, int days) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateUtil.toDate(date, DATE_PATTERN_0));
        calendar.add(Calendar.DATE, days);
        return DateUtil.formatDate(calendar.getTime(), DATE_PATTERN_0);
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄僔僗僥儉擔晅墘嶼婡擻
     * @param date 巜掕擔晅
     * @param days 捛壛偝傟傞擔晅
     * @param pattern 僷僞乕儞
     * @return String 擔晅
     */
    public static String addDays(String date, int days, String pattern) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateUtil.toDate(date, pattern));
        calendar.add(Calendar.DATE, days);
        return DateUtil.formatDate(calendar.getTime(), pattern);
    }

    /**
     * 巜掕偝傟偨擔晅偵傛偭偰丄僔僗僥儉擔晅墘嶼婡擻
     * @param date 巜掕擔晅
     * @param days 捛壛偝傟傞擔晅
     * @return Timestamp 擔晅
     */
    public static Timestamp addDays(Timestamp date, int days) {

        if (null != date) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE, days);
            return new Timestamp(calendar.getTime().getTime());
        } else {
            return null;
        }
    }

    /**
     * 擖椡偟偨僗僩儕儞僌偼擖椡僼僅乕儅僢僩偵拝懼偊傞丅
     * @param date 擖椡偟偨僗僩儕儞僌(NULL嬛巭)
     * @param format 擖椡偟偨僼僅乕儅僢僩(NULL嬛巭)
     * @return 拝懼偊傞擔晅
     */
    public static Date toDate(String date, String format) {

        if (StringUtil.isEmpty(date)) {
            return null;
        }
        try {
            return new SimpleDateFormat(format).parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄擔晅傪僼僅乕儅僢僩偡傞丅
     * @param dateStr 擔晅
     * @param smft 僼僅乕儅僢僩
     * @return Timestamp 擔晅
     */
    public static Timestamp formatStrTOStampBySmt(String dateStr, String smft) {

        if (StringUtil.isEmpty(dateStr) || StringUtil.isEmpty(smft)) {
            return null;
        }
        Timestamp rs = null;
        try {
            SimpleDateFormat formatter = new SimpleDateFormat(smft);
            rs = new Timestamp(formatter.parse(dateStr).getTime());
            return rs;
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄擔晅傪僼僅乕儅僢僩偡傞丅
     * @param gmtStr 擔晅
     * @param smft 僼僅乕儅僢僩
     * @return Timestamp 擔晅
     */
    public static Timestamp formatGMTStrTOStampBySmt(String gmtStr, String smft) {

        if (StringUtil.isEmpty(gmtStr) || StringUtil.isEmpty(smft)) {
            return null;
        }
        Timestamp rs = null;
        try {
            Timestamp sysDate = DateUtil.currentTimestamp();
            Calendar c = Calendar.getInstance();
            c.setTime(sysDate);
            int offset = Calendar.getInstance().getTimeZone().getRawOffset();
            SimpleDateFormat formatter = new SimpleDateFormat(smft, LOCALE_US);
            rs = new Timestamp(formatter.parse(gmtStr).getTime() - offset);
            return rs;
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 乽YYYYMM乿偲偺僼僅乕儅僢僩偐傜YYYY/MM擔晅暥帤楍偵曄姺偡傞丅
     * @param strDateYYYYMM 僆儕僕僫儖擔晅暥帤楍
     * @return 曄姺屻擔晅暥帤楍
     */
    public static String formatDateYYYYMM(String strDateYYYYMM) {

        if (StringUtil.isEmpty(strDateYYYYMM)) {
            return StringUtil.BLANK;
        }
        if (strDateYYYYMM.trim().length() == 6) {
            String yyyy = strDateYYYYMM.substring(0, 4);
            String mm = strDateYYYYMM.substring(4);
            return yyyy + StringUtil.OBLIQUELINE + mm;
        }
        return strDateYYYYMM;
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄擔晅傪僼僅乕儅僢僩偡傞.
     * <p>
     * 擖椡偱偒傞僼僅乕儅僢僩: <br>
     * &quot;yyyyMMdd&quot; <br>
     * &quot;yyyy/MM/dd HH:mm:ss.SSS&quot; <br>
     * 偦偺懠僼僅乕儅僢僩偼java.text.SimpleDateFormat傪嶲徠偟偰偔偩偝偄丅 <br>
     * 巊梡椺丗 <br>
     * DateUtil.toString(DateUtil.toDate(&quot;20030918&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyyMMdd&quot;)偺寢壥偼 20030918
     * DateUtil.toString(DateUtil.toDate(&quot;20030918&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyy/MM/dd&quot;)偺寢壥偼 2003/09/18
     * DateUtil.toString(DateUtil.toDate(&quot;17000101&quot;,
     * &quot;yyyyMMdd&quot;), &quot;yyyy-MM-dd HH:mm:ss.SSS&quot;)偺寢壥偼
     * 1700-01-01 00:00:00.0
     * @param date 擖椡偟偨擔晅
     * @param format 擖椡偟偨僼僅乕儅僢僩
     * @return 拝懼偊傞僗僩儕儞僌
     * @see java.text.SimpleDateFormat
     */
    public static String formatDate(Timestamp date, String format) {

        if (null == date) {
            return null;
        }
        SimpleDateFormat sdFromat = new SimpleDateFormat(format);
        return sdFromat.format(date);
    }

    /**
     * 巜掕擭寧偲巜掕寧悢傪壛嶼偟偰丄壛嶼偝傟偨擔晅偺寧偺嵟屻偺擔傪曉偡
     * @param dt 巜掕擔晅
     * @param iMonth 巜掕寧悢
     * @return 寁嶼偟偨擔晅
     */
    public static Date getAddMonthEnday(Date dt, int iMonth) {

        if (null != dt) {
            Calendar c = Calendar.getInstance();
            c.setTime(dt);
            c.add(Calendar.MONTH, iMonth + 1);
            c.set(Calendar.DATE, 1);
            c.add(Calendar.DAY_OF_MONTH, -1);
            return new Date(c.getTime().getTime());
        } else {
            return null;
        }
    }

    /**
     * 巜掕擭寧擔偲巜掕擔悢傪壛嶼偡傞丅
     * @param dt 巜掕擔晅
     * @param iDay 巜掕寧悢
     * @return 寁嶼偟偨擔晅
     */
    public static Date getAddDay(Date dt, int iDay) {

        if (null != dt) {
            Calendar c = Calendar.getInstance();
            c.setTime(dt);
            c.add(Calendar.DAY_OF_YEAR, iDay);
            return new Date(c.getTime().getTime());
        } else {
            return null;
        }
    }

    /**
     * 巜掕擭寧擔偲巜掕寧悢傪壛嶼偡傞丅
     * @param dt 巜掕擔晅
     * @param iMonth 巜掕寧悢
     * @return 寁嶼偟偨擔晅
     */
    public static Date getAddMonth(Date dt, int iMonth) {

        if (null != dt) {
            Calendar c = Calendar.getInstance();
            c.setTime(dt);
            c.add(Calendar.MONTH, iMonth);
            return new Date(c.getTime().getTime());
        } else {
            return null;
        }
    }

    /**
     * 巜掕擭寧擔偲巜掕擭悢傪壛嶼偡傞丅
     * @param dt 巜掕擭寧擔
     * @param iYear 巜掕擭悢
     * @return 寁嶼偟偨擔晅
     */
    public static Date getAddYear(Date dt, int iYear) {

        if (null != dt) {
            Calendar c = Calendar.getInstance();
            c.setTime(dt);
            c.add(Calendar.YEAR, iYear);
            return new Date(c.getTime().getTime());
        } else {
            return null;
        }
    }

    /**
     * 巜掕偝傟偨僼僅乕儅僢僩偵傛偭偰丄僔僗僥儉擔晅墘嶼婡擻
     * @param date 巜掕擔晅(YYYYMM)
     * @param months 捛壛偝傟傞擔晅
     * @return String 擔晅(YYYYMM + 1)
     */
    public static String addMonth(String date, int months) {

        if (StringUtil.isEmpty(date)) {
            return StringUtil.BLANK;
        }

        try {

            // 僼僅乕儅僢僩偺弶婜壔
            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERN_6);

            // 杮寧偺僇儗儞僟乕傪愝掕偡傞
            Calendar calendar = dateFormat.getCalendar();
            calendar.setTime(dateFormat.parse(date));

            // 師偺寧暘偺嵟屻擔傪庢摼偟偰丄巜掕偟偨寧暘傪愝掕偡傞
            calendar.add(Calendar.MONTH, months);
            return dateFormat.format(calendar.getTime()).substring(0, 6);

        } catch (ParseException ex) {
            return StringUtil.BLANK;
        }
    }

    /**
     * 乽YYYY/MM/DD乿偲偺僼僅乕儅僢僩偐傜YYYYMMDD擔晅暥帤楍偵曄姺偡傞丅
     * @param strDateYYYYMMDD 僆儕僕僫儖擔晅暥帤楍
     * @return 曄姺屻擔晅暥帤楍
     */
    public static String formatDateYYYYMMDD(String strDateYYYYMMDD) {

        if (StringUtil.isEmpty(strDateYYYYMMDD)) {
            return StringUtil.BLANK;
        }
        if (strDateYYYYMMDD.trim().length() == 10) {
            String yyyy = strDateYYYYMMDD.substring(0, 4);
            String mm = strDateYYYYMMDD.substring(5, 7);
            String dd = strDateYYYYMMDD.substring(8);
            return yyyy + mm + dd;
        }
        return strDateYYYYMMDD;
    }

    /**
     * 乽YYYYMMDD乿偲偺僼僅乕儅僢僩偐傜YYYY/MM/DD擔晅暥帤楍偵曄姺偡傞丅
     * @param strYMD 僆儕僕僫儖擔晅暥帤楍
     * @return 曄姺屻擔晅暥帤楍
     */
    public static String formatDateYMD(String strYMD) {

        if (StringUtil.isEmpty(strYMD)) {
            return StringUtil.BLANK;
        }
        if (strYMD.trim().length() == 8) {
            String yyyy = strYMD.substring(0, 4);
            String mm = strYMD.substring(4, 6);
            String dd = strYMD.substring(6, 8);
            return yyyy + StringUtil.OBLIQUELINE + mm + StringUtil.OBLIQUELINE + dd;
        }
        return strYMD;
    }

    /**
     * 帪暘昩傪僋儕傾乕偟偰丄擔晅傪僼僅乕儅僢僩偡傞.
     * @param date 擖椡偟偨擔晅
     * @return 帪暘昩傪僋儕傾乕偝傟偨擔晅
     * @see java.text.SimpleDateFormat
     */
    public static Date formatDateDeleteHMS(java.util.Date date) {

        if (null == date) {
            return null;
        }
        return toDate(formatDate(date, DATE_PATTERN_2), DATE_PATTERN_2);
    }
    /**
	 * 得到当前时间的前N小时
	 * 
	 * @param d
	 * @param day
	 * @return
	 */
	public static String getBeforeByHourTime(int ihour){
		String returnstr = "";
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - ihour);
		SimpleDateFormat df = new SimpleDateFormat(DateUtil.DATE_PATTERN_26);
		returnstr = df.format(calendar.getTime());
		return returnstr;
	}
}
