package com.fuzamei.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

/**
 * @author zhouzk
 * @time   2013-03-04
 */
public abstract class DateUtil {
	/**
	 * desc：Date转换为String
	 * 
	 * @param date
	 *            需要转换的date
	 * @param format
	 *            格式字符串
	 * @return 返回按照格式转化后的字符串 DateUtil.toString(new Date(),"yyyy-MM-dd HH:mm:ss SSS")
	 */
	public static String toString(Date date, String format) {
		if (date != null) {
			SimpleDateFormat dateformatter = new SimpleDateFormat(format);
			String dateString = dateformatter.format(date);
			return dateString;
		} else {
			return null;
		}
	}

	/**
	 * desc：String时间转换为格式化Date时间
	 * 
	 * @param date
	 *            需要转换的String
	 * @param format
	 *            格式字符串
	 * @return 返回按照格式转化后的Date 如：DateUtil.getDate("2007-11-01","yyyy-MM-dd")
	 * @throws ParseException 
	 */
	public static Date getDate(String dateStr, String format) throws ParseException{
		SimpleDateFormat dateformatter = new SimpleDateFormat(format);
		return dateformatter.parse(dateStr);
	}
	
	/**
	 * desc：Date时间转换为格式化后的Date时间
	 * 
	 * @param date
	 *            需要转换的date
	 * @param format
	 *            格式字符串
	 * @return 返回按照格式转化后的Date 如：DateUtil.getDate(new Date(),"yyyy-MM-dd")
	 */
	public static Date getDate(Date date, String format) throws ParseException {
		if (date == null)
			return null;
		SimpleDateFormat dateformatter = new SimpleDateFormat(format);
		return dateformatter.parse(dateformatter.format(date));
	}

    /**
     * 获取前m天的日期
     * @param nowDate
     * @param m
     * @return
     */
    public static Date getBeforDay(Date nowDate, int m) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        calendar.add(Calendar.DAY_OF_MONTH, -m);
        return calendar.getTime();
    }
    /**
     * 得到指定月的最后一天的日期
     * */
    public static Date getMonthLastDay(int year, int month)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, 0);//把日期设置为当月第一天
        return calendar.getTime();
    }
	/**
	 * 得到指定月的天数
	 * */
	public static int getMonthLastDays(int year, int month)
	{
		Calendar a = Calendar.getInstance();
		a.set(Calendar.YEAR, year);
		a.set(Calendar.MONTH, month - 1);
		a.set(Calendar.DATE, 1);//把日期设置为当月第一天
		a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}
	
	/**
	 * 取得当月天数
	 * */
	public static int getCurrentMonthLastDays()
	{
		Calendar a = Calendar.getInstance();
		a.set(Calendar.DATE, 1);//把日期设置为当月第一天
		a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}
	
	/**
	 * 判断当前日期是星期几
	 * @param pTime
	 *            修要判断的时间
	 * @return dayForWeek 判断结果
	 */
	public static int dayForWeek(String pTime) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		try{
			return dayForWeek(format.parse(pTime));
		}catch(Exception e){
			e.printStackTrace();
		}
		return -1;
	}
	
	/**
	 * 判断当前日期是星期几
	 * @param pTime
	 *            修要判断的时间
	 * @return dayForWeek 判断结果
	 */
	public static int dayForWeek(Date pTime) {
		try{
			Calendar c = Calendar.getInstance();
			c.setTime(pTime);
			int dayForWeek = 0;
			if (c.get(Calendar.DAY_OF_WEEK) == 1) {
				dayForWeek = 7;
			} else {
				dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
			}
			return dayForWeek;
		}catch(Exception e){
			e.printStackTrace();
		}
		return -1;
	}
	
	/**
	 * 返回本周第N天的日期（按中国周算）
	 * 
	 * @throws ParseException
	 */
	public static Date getWeekByDate(Date date,int week){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		if (c.get(Calendar.DAY_OF_WEEK) == 1) {
			c.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
			c.setTime(c.getTime());
		}
//		c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);// 把日期设置为当月第一天
		c.set(Calendar.DAY_OF_WEEK, week);// 把日期设置为当月第一天
		return c.getTime();
	}

    /**
     * 返回 yyyy年m月第n周（周二为一周第一天），如：2016年01月第1周。
     * @param date
     * @return
     */
	public static String getChineseInfo(Date date){
		Date tuesday = getWeekByDate(date,Calendar.TUESDAY);//获取周二
		Calendar c = Calendar.getInstance();
		c.setTime(tuesday);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH)+1;
		int day = c.get(Calendar.DATE);
		int num = 0;
		for(int i = 1;i<= day;i++){
			String dd = String.valueOf(i);
			if(i<10){
				dd = "0"+i;
			}
			int week = dayForWeek(year + "-"+month+"-"+dd);
			if(week == (Calendar.TUESDAY-1)){
				num ++;
			}
		}
		return year + "年" + month + "月第"+num + "周";
	}
    /**
     * 返回 201601_1 的中文格式，2016年01月第1周
     * @param statCycle 201602_1 or 201602
     * @return
     */
	public static String getChineseInfo(String statCycle){
        String year = statCycle.substring(0, 4);
        String monthStr = "0";
        String weekDesc = "";
        int endIndex = statCycle.indexOf('_');
        if(endIndex > -1) {
            monthStr = statCycle.substring(4, endIndex);
            String num = statCycle.substring(7);
            weekDesc = "第" + num + "周";
        } else {
            monthStr = statCycle.substring(4);
        }
        int month = Integer.parseInt(monthStr);
        return year + "年" + month + "月" + weekDesc;
	}

    /**
     * 返回 yyyyMM_w 的时间格式（周二为一周第一天），如：201601_1
     * @param date
     * @return
     */
	public static String getEnglishInfo(Date date){
		Date tuesday = getWeekByDate(date,Calendar.TUESDAY);//获取周二
		Calendar c = Calendar.getInstance();
		c.setTime(tuesday);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH)+1;
		int day = c.get(Calendar.DATE);
		int num = 0;
		for(int i = 1;i<= day;i++){
			String dd = String.valueOf(i);
			if(i<10){
				dd = "0"+i;
			}
			int week = dayForWeek(year + "-"+month+"-"+dd);
			if(week == (Calendar.TUESDAY-1)){
				num ++;
			}
		}
		return year + "" + (month<10?"0":"")+ month + "_"+num;
	}
    /**
     * 返回上个月 yyyy年mm月，如：2016年01月
     * @param date
     * @return
     */
	public static String getChineseMonthInfo(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
        if(month == 0) {
            year = year - 1;
            month = 12;
        }
		return year + "年" + month + "月";
	}
    /**
     * 返回上个月 yyyyMM 的时间格式，如：201601
     * @param date
     * @return
     */
	public static String getEnglishMonthInfo(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
		if(month == 0) {
			year = year - 1;
			month = 12;
		}
		return year + "" + (month<10?"0":"")+ month;
	}

	/**
	 * 判断当前时间是否在   周二8点 ~ 周六的0点
	 */
	public static boolean isWorkDay(Date date) {
		// 获取周二上午8点
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 8);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND,0);
		Date tuesday = getWeekByDate(calendar.getTime(), Calendar.TUESDAY); // 周二
		
		// 获取周六的0点
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND,0);
		Date saturday = getWeekByDate(calendar.getTime(), Calendar.SATURDAY);  // 周六
		
		// 判断
		long time = date.getTime();
		if(time >= tuesday.getTime() && time < saturday.getTime()) {
			return true;
		}
		return false;
	}
	
	
	/**
	 * 获取strYYYYMMDD为第N周
	 */
	public static int getWeekByDate(String strYYYYMMDD){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date date = sdf.parse(strYYYYMMDD);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
			return weekOfMonth;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return -1;
	}
	
	/**
	 * 判断用户输入的是否是时间
	 * @param str 时间
	 * @author WangBin
	 * */
	public static boolean isValidDate(String str) {
	      boolean convertSuccess=true;
	       // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
	       SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
	       try {
	    	  // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
	          format.setLenient(false);
	          format.parse(str);
	       } catch (ParseException e) {
	           // e.printStackTrace();
	    	   // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
	           convertSuccess=false;
	       } 
	       return convertSuccess;
	}
	
	/**  
     * 计算两个日期之间相差的天数  
     * @param smdate 较小的时间 
     * @param bdate  较大的时间 
     * @return 相差天数 
     * @throws ParseException  
     * @author WangBin
     */    
    public static int daysBetween(String smdate,String bdate) throws ParseException    
    {    
              
       SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
       long to = df.parse(smdate).getTime();
       long from = df.parse(bdate).getTime();
       String dateValue = String.valueOf(((from - to) / (1000 * 60 * 60 * 24) + 1));
       int timeDifference = Integer.parseInt(dateValue);
       return timeDifference; 
    }
    
    
    
    /**
     * 取北京时间
     * @param currentTime utc时间
     * @param rule 日期格式
     * @return
     * @author WangBin
     */
    public static String getBeijingTime(long currentTime, String rule){
        return getFormatedDateString(8, currentTime, rule);
    }
    
    /**
     * 取班加罗尔时间
     * @param currentTime utc时间
     * @param rule 日期格式
     * @return
     * @author WangBin
     */
    public static String getBangaloreTime(long currentTime, String rule){
        return getFormatedDateString(5.5f, currentTime, rule);
    }
    
    /**
     * 取纽约时间
     * @param currentTime utc时间
     * @param rule 日期格式
     * @return
     * @author WangBin
     */
    public static String getNewyorkTime(long currentTime, String rule){
        return getFormatedDateString(-5, currentTime, rule);
    }
    
    /**
     * 此函数非原创，从网上搜索而来，timeZoneOffset原为int类型，为班加罗尔调整成float类型
     * timeZoneOffset表示时区，如中国一般使用东八区，因此timeZoneOffset就是8
     * @param timeZoneOffset
     * @param currentTime utc时间
     * @param rule 日期格式
     * @return
     * @author WangBin
     */
    public static String getFormatedDateString(float timeZoneOffset, long currentTime, String rule){
        if (timeZoneOffset > 13 || timeZoneOffset < -12) {
            timeZoneOffset = 0;
        }
        
        int newTime=(int)(timeZoneOffset * 60 * 60 * 1000);
        TimeZone timeZone;
        String[] ids = TimeZone.getAvailableIDs(newTime);
        if (ids.length == 0) {
            timeZone = TimeZone.getDefault();
        } else {
            timeZone = new SimpleTimeZone(newTime, ids[0]);
        }
        
        SimpleDateFormat sdf = new SimpleDateFormat(rule);
        sdf.setTimeZone(timeZone);
        return sdf.format(new Date(currentTime));
    }
    
    /**
     * 获取utc时间
     * @param date  时间
     * @param rule  日期格式
     * @throws ParseException 
     * @author WangBin
     */
    public static long getUTCTime(String date,String rule) throws ParseException{
    	
    	SimpleDateFormat sdf=new SimpleDateFormat(rule);
		Date d=sdf.parse(date);
    	return d.getTime();
    } 
    public static void main(String[] args) {
		/*String str = getChineseInfo(new Date());
		String str1 = getEnglishInfo(new Date());
		System.out.println(str);
		System.out.println(str1);
		// 月
		Date date = new Date();
		String statCycle = DateUtil.getEnglishMonthInfo(date);
		System.out.println(statCycle);
		String monthInfo = DateUtil.getChineseMonthInfo(date);
		System.out.println(monthInfo);*/
    	/*System.out.println("!!!!111");
    	//拿到当前时间的时间戳
    	long cutime = System.currentTimeMillis();
    	System.out.println("当前时间的时间戳："+cutime);
    	//时间戳得到时间
    	String time1 = getBeijingTime(cutime,"yyyy-MM-dd hh:mm:ss");
    	System.out.println("时间戳转换成时间："+time1);
    	
    	long longtime = Long.parseLong("1510282927202");
    	String time2 = getBeijingTime(longtime,"yyyy-MM-dd hh:mm:ss");
    	System.out.println("1510282927202转换成时间："+time2);
    	//两天后的时间戳
    	long time3 = 24*60*60*1000*2+longtime;
    	String time4 = getBeijingTime(time3,"yyyy-MM-dd hh:mm:ss");
    	System.out.println("1510282927202两天后的时间为："+time4);
    	
    	
    	String time = "2017-11-10 11:02:07";
		
		try {
			Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(time);
			System.out.println("data:"+getUTCTime("2017-11-10 11:02:07", "yyyy-MM-dd hh:mm:ss")/1000);
			long unixTimestamp = date.getTime()/1000;
			System.out.println(unixTimestamp);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		
    	long longtime = Long.parseLong("1511761418044");
    	String time2 = getBeijingTime(longtime,"yyyy-MM-dd hh:mm:ss");
    	System.out.println("1510282927202转换成时间："+time2);
    	
    	
    	//24*60*60*2+
    }
}
