package com.bizofficer.util.system;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

public class MakeDate {
	
	
	public Date getCurrentDate(String format) { // for can be "yyyy-MM-dd" / "MM-dd-yyyy" / "dd-MM-yyyy"
		DateFormat dateformat = new SimpleDateFormat(format);
		Date dateToDB = null;
		try {
			dateToDB = dateformat.parse(dateformat.format(new Date()));
		} catch (ParseException e) {			
			e.printStackTrace();
		}
		return dateToDB;
	}

	public String getCurrentDateOwnFormat(String format) { // for can be "yyyy-MM-dd" / "MM-dd-yyyy" / "dd-MM-yyyy"
		DateFormat dateformat = new SimpleDateFormat(format);
		String date = null;
		try {
			date = dateformat.format(new Date()).toString();
		} catch (Exception e) {			
			e.printStackTrace();
		}
		return date;
	}

/************************************************************
	CHANGE DATE FORMAT
	//for all three thing just pass format dd/MM/yyyy HH:mm:ss Z
************************************************************/	
	
	public String changeDateTimeFormat(Date date, String format) { // for can be "yyyy-MM-dd" / "MM-dd-yyyy" / "dd-MM-yyyy"
		
		String dateReturn = null;

		try {
			
			if(date==null || format==null) {
				return dateReturn;
			}
			
		    //create SimpleDateFormat object with desired date format
		    SimpleDateFormat sdf = new SimpleDateFormat(format);	
		    sdf.setTimeZone(TimeZone.getTimeZone("Etc/IST"));
		    dateReturn = sdf.format(date);
		    
		} catch (Exception e) {			
			e.printStackTrace();
		}
		
		return dateReturn;
	}

	public Date getStringToDate(String dateStr, String newPattern) { 
		
		Date dateReturn = null;

		try {
			
			if(dateStr==null || newPattern==null) {
				return dateReturn;
			}
			///System.out.println("A dateStr > "+dateStr);
			///dateReturn = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse("31/12/2026 20:21:22");
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(newPattern);	
			simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Etc/IST"));
		    dateReturn = simpleDateFormat.parse(dateStr);
			///System.out.println("B dateReturn > "+dateReturn);
		} catch (Exception e) {			
			e.printStackTrace();
		}
		
		return dateReturn;
	}
	
	public Date changeDateFormat(Date date, String format) { // for can be "yyyy-MM-dd" / "MM-dd-yyyy" / "dd-MM-yyyy"
		
		Date dateReturn = null;

		try {
			//create SimpleDateFormat object with source string date format
			///DateFormat dateFormatSource = new SimpleDateFormat(formatSource);
			
			//parse the string into Date object
		    ///Date date = dateFormatSource.parse(strDate);

		    //create SimpleDateFormat object with desired date format
		    SimpleDateFormat dateFormat = new SimpleDateFormat(format);		    
		    dateReturn = dateFormat.parse(dateFormat.format(date));
		    
		} catch (ParseException e) {			
			e.printStackTrace();
		}
		
		return dateReturn;
	}

	public String changeDateFormat(String strDate, String oldFormat, String newFormat) { 
		
		String dateReturn = null;

		try {

			Date date = new SimpleDateFormat(oldFormat).parse(strDate);
			
			dateReturn = new SimpleDateFormat(newFormat).format(date);
			
		} catch (Exception e) {			
			e.printStackTrace();
		}
		
		return dateReturn;
	}

	public String changeMysqlFormat(String strDate) throws ParseException { 
		String dateReturn = null;
		if(strDate!=null && strDate.length()>0){
			String[] strDateArr = strDate.trim().split(" ");
			String[] darr = {};
			if(strDateArr[0].indexOf("-")>-1){
				darr = strDateArr[0].split("-");
			}else if(strDateArr[0].indexOf("/")>-1){
				darr = strDateArr[0].split("/");
			}
			dateReturn = darr[2]+"-"+darr[1]+"-"+darr[0];
			if(strDateArr.length==2 && strDateArr[1]!=null && strDateArr[1].length()>0) {
				dateReturn+=" "+strDateArr[1];				
			}
			
		}
		return dateReturn;
	}
	
//	public Date stringToDate(String strDate, String format) { // for can be "yyyy-MM-dd" / "MM-dd-yyyy" / "dd-MM-yyyy"
//		
//		Date dateReturn = null;
//		
//		try {
//			if(strDate!=null && strDate.length()>0 ){
//				//create SimpleDateFormat object with source string date format
//				DateFormat dateFormat = new SimpleDateFormat(format);	
//				//parse the string into Date object
//				dateReturn = dateFormat.parse(strDate);
//			}
//		} catch (ParseException e) {			
//			e.printStackTrace();
//		}
//		
//		return dateReturn;
//	}

	public String dateToString(Date date, String format) throws ParseException { 
		
		String dateReturn = null;

		DateFormat dateFormat = new SimpleDateFormat(format);	

		dateReturn = dateFormat.format(date);
		
		return dateReturn;
	}

/************************************************************
	GET CURRENT DATE TIME ZONE
	//for all three thing just pass format dd/MM/yyyy HH:mm:ss Z
************************************************************/	
	public String getCurrentDateTimeZone(String FormatStr) {
		try{
			Date now = new Date();  
			DateFormat df = new SimpleDateFormat(FormatStr);  
			  
			//Print the date in the default timezone  
			//System.out.println(df.format(now));  
			  
			// Set a specific timezone  
			//df.setTimeZone(TimeZone.getTimeZone("UTC"));  
			//System.out.println(df.format(now)); 
			return df.format(now);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;		
	}	
	
/************************************************************
	GET CURRENT TIME
	//for current Time pass HH:mm:ss time format
************************************************************/	
	public java.sql.Time getCurrentTime(String FormatStr) {
			try{
				Date now = new Date();  
				DateFormat df = new SimpleDateFormat(FormatStr);  
				return java.sql.Time.valueOf(df.format(now));
			}catch(Exception e){
				e.printStackTrace();
			}
			return null;		
	}	
	
	public String getCurrentTimeActivity(String FormatStr) {
		try{
			String time;
			Date now = new Date();  
			DateFormat df = new SimpleDateFormat(FormatStr); 
			String[] timeArr = java.sql.Time.valueOf(df.format(now)).toString().split(":");
			if(Integer.valueOf(timeArr[1])<30){
				time = timeArr[0]+":30:00";
			}else{
				time = (Integer.valueOf(timeArr[0])+1)+":00:00";
			}
			return time;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;		
	}	
	

/************************************************************
	GET CURRENT Time stamp 2010-03-08 14:59:30.252
	
************************************************************/	
	
	public java.sql.Timestamp getCurrentTimeStamp(){
		java.util.Date date= new java.util.Date();
		return new Timestamp(date.getTime());
	}
	
/************************************************************
	GET Number of Day / Month / Year from Date	
************************************************************/	
	
	public Integer getMonthDayYearNumOfCurrentDate(String opt){

		java.util.Date date= new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int month = cal.get(Calendar.MONTH);
	    int day = cal.get(Calendar.DAY_OF_MONTH);
	    int year = cal.get(Calendar.YEAR);
	    
	    Integer reTurn=null;
	    
	    if(opt.equals("m")){
	    	reTurn=	month;    	
	    }else if(opt.equals("d")){
	    	reTurn=	day;
	    }else if(opt.equals("y")){
	    	reTurn=	year;
	    }
		return reTurn;
	}


/************************************************************
	GET Name of Day / Month / Year from Current Date	
************************************************************/	
	
	public String getMonthDayName(String opt){

		Calendar cal = Calendar.getInstance();

		String reTurn=null;
		if(opt.equals("m")){
			reTurn= cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH );  	
	    }else if(opt.equals("d")){
	    	reTurn= cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH );
	    }
	    	    
		return reTurn;
	}

	public int getNumDayOfWeekDate(String inputDate) throws ParseException{ 
		
		SimpleDateFormat format1=new SimpleDateFormat("dd/MM/yyyy");
		Date dt1=format1.parse(inputDate);
		
		Calendar calendar = Calendar.getInstance();
 
		calendar.setTime(dt1);
		
		int finalDay=calendar.get(Calendar.DAY_OF_WEEK);
		
		return finalDay;
	}

	public int getCurrentDayOfWeek(String code) throws ParseException{ 
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.setTimeZone(TimeZone.getTimeZone(code));
		int dayOfWeek=calendar.get(Calendar.DAY_OF_WEEK);
		
		return dayOfWeek;
	}

/************************************************************
	GET dayFormat = "EEEE" Wednesday / "E" for Wed / MMMM for January / MMM for Sep / MM for 01 / GGG for AD 
	Date format extample "dd/MM/yyyy"
************************************************************/	
	
	public String getNameOfDate(String dayFormat, String inputDate,String dateFormat){ 
		String finalDay=null;
		try {
			SimpleDateFormat format1=new SimpleDateFormat(dateFormat);
			Date dt1=format1.parse(inputDate);
			DateFormat format2=new SimpleDateFormat(dayFormat); 
			finalDay=format2.format(dt1);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return finalDay;
	}

	public String getMonthNameOfDate(String dayFormat, Date inputDate) throws ParseException{ 
		String finalDay=null;
		DateFormat format2=new SimpleDateFormat(dayFormat); 
		finalDay=format2.format(inputDate);
		return finalDay;
	}

/************************************************************
	GET Days of Month / Year from Date	
************************************************************/	
	
	public Integer getDaysOfMonth(Integer year, Integer month){

		Integer days = null;
		
		YearMonth ym = YearMonth.of(year, month);
		days=ym.lengthOfMonth();
		
		////System.out.println("days >> "+days);
	    	    
		return days;
	}

/************************************************************
	GET Yesterday Date, Create Before and After Date from a Specific Date in the String Format of MM/DD/YYYY	
************************************************************/	
	public Timestamp addMinuteToTime(String inputDate, Integer minutes) throws ParseException{ 
//		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");	
//		simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Etc/IST"));
//		Date inputDate = simpleDateFormat.parse(myDate.toString());
	    
		 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		 df.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
		 Date d = df.parse(inputDate); //"2022-06-24 14:00:00" 
		 Calendar cal = Calendar.getInstance();
		 cal.setTime(d);		 
		 cal.add(Calendar.MINUTE, minutes);
		 ///String newTime = df.format(cal.getTime());
		 java.util.Date newdate = cal.getTime();
		 return new Timestamp(newdate.getTime());
		 
//		GregorianCalendar gc = new GregorianCalendar();
//		///gc.setTimeZone(TimeZone.getTimeZone("Etc/IST"));
//		gc.setTime(inputDate);
//		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
//		gc.roll(Calendar.MINUTE, 0);
//		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
//		if(dayAfter < dayBefore) {
//		    gc.roll(Calendar.YEAR, 1);
//		}
//		gc.get(Calendar.DATE);
//		java.util.Date newdate = gc.getTime();
	    	    
		///return new Timestamp(newdate.getTime());
	}

	public Timestamp getAfterHoursDate(Date inputDate, Integer hours) throws ParseException{ 

		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(inputDate);
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		gc.roll(Calendar.HOUR_OF_DAY, hours);
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		if(dayAfter < dayBefore) {
		    gc.roll(Calendar.YEAR, 1);
		}
		gc.get(Calendar.DATE);
		java.util.Date newdate = gc.getTime();
	    	    
		return new Timestamp(newdate.getTime());
	}
	
	public Timestamp getAfterDaysDate(Date inputDate, Integer days) throws ParseException{ 

		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(inputDate);
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		gc.roll(Calendar.DAY_OF_YEAR, days);
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		if(dayAfter < dayBefore) {
		    gc.roll(Calendar.YEAR, 1);
		}
		gc.get(Calendar.DATE);
		java.util.Date newdate = gc.getTime();
	    	    
		return new Timestamp(newdate.getTime());
	}

	public Timestamp getBeforeHoursDate(Date inputDate, Integer hours) throws ParseException{ 

		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(inputDate);
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		gc.roll(Calendar.HOUR_OF_DAY, -hours);
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		if(dayAfter < dayBefore) {
		    gc.roll(Calendar.YEAR, 1);
		}
		gc.get(Calendar.DATE);
		java.util.Date newdate = gc.getTime();
	    	    
		return new Timestamp(newdate.getTime());
	}
	public Timestamp getBeforeDaysDate(Date inputDate, Integer days) throws ParseException{ 

		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(inputDate);
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		gc.roll(Calendar.DAY_OF_YEAR, -days);
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		if(dayAfter < dayBefore) {
		    gc.roll(Calendar.YEAR, 1);
		}
		gc.get(Calendar.DATE);
		java.util.Date newdate = gc.getTime();
	    	    
		return new Timestamp(newdate.getTime());
	}
	
	public String getBeforeDaysDate(String inputDate, Integer days,String dateFormat){ 
		String specificDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		    GregorianCalendar gc = new GregorianCalendar();
		    java.util.Date d = sdf.parse(inputDate);
		    gc.setTime(d);
		    ///////System.out.println("Input Date = " + sdf.format(d));
		    int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		    gc.roll(Calendar.DAY_OF_YEAR, days);
		    int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		    if(dayAfter > dayBefore) {
		        gc.roll(Calendar.YEAR, -1);
		    }
		    gc.get(Calendar.DATE);
		    java.util.Date yesterday = gc.getTime();
		    //System.out.println("Yesterdays Date = " + sdf.format(yesterday));
		    specificDate=sdf.format(yesterday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    	    
		return specificDate;
	}

	public String getAfterDaysDate(String inputDate, Integer days,String dateFormat){ 
		String specificDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		    GregorianCalendar gc = new GregorianCalendar();
		    java.util.Date d = sdf.parse(inputDate);
		    gc.setTime(d);
		    ///////System.out.println("Input Date = " + sdf.format(d));
		    int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		    gc.roll(Calendar.DAY_OF_YEAR, days);
		    int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		    if(dayAfter < dayBefore) {
		        gc.roll(Calendar.YEAR, 1);
		    }
		    gc.get(Calendar.DATE);
		    java.util.Date yesterday = gc.getTime();
		    //System.out.println("Yesterdays Date = " + sdf.format(yesterday));
		    specificDate=sdf.format(yesterday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    	    
		return specificDate;
	}
	
	public String getBeforeDaysDate(Integer days,String dateFormat) throws ParseException{ 
		String specificDate=null;
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		GregorianCalendar gc = new GregorianCalendar();
		java.util.Date d = new Date();
		gc.setTime(d);
		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		gc.roll(Calendar.DAY_OF_YEAR, -days);
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		if(dayAfter > dayBefore) {
		    gc.roll(Calendar.YEAR, -1);
		}
		gc.get(Calendar.DATE);
		java.util.Date rollDate = gc.getTime();
		specificDate=sdf.format(rollDate);
	    	    
		return specificDate;
	}

	public Date getAfterDaysDate(Integer days,String dateFormat) throws ParseException{ 

		GregorianCalendar gc = new GregorianCalendar();
		java.util.Date d = new Date();
		gc.setTime(d);

		int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		gc.roll(Calendar.DAY_OF_YEAR, days);
		int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		if(dayAfter < dayBefore) {
		    gc.roll(Calendar.YEAR, 1);
		}
		gc.get(Calendar.DATE);
		java.util.Date rollDate = gc.getTime();
	    	    
		return rollDate;
	}

	public String getDateAfterDays(String inputDate, Integer days,String dateFormat){ 
		String specificDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		    GregorianCalendar gc = new GregorianCalendar();
		    java.util.Date d = sdf.parse(inputDate);
		    gc.setTime(d);
		    int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		    gc.roll(Calendar.DAY_OF_YEAR, days);
		    int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		    if(dayAfter < dayBefore) {
		        gc.roll(Calendar.YEAR, 1);
		    }
		    gc.get(Calendar.DATE);
		    java.util.Date yesterday = gc.getTime();
		    //System.out.println("Yesterdays Date = " + sdf.format(yesterday));
		    specificDate=sdf.format(yesterday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    	    
		return specificDate;
	}
	
	public String getDateAfterMonths(String inputDate, Integer months,String dateFormat){ 
		String specificDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		    GregorianCalendar gc = new GregorianCalendar();
		    java.util.Date d = sdf.parse(inputDate);
		    gc.setTime(d);
		    int dayBefore = gc.get(Calendar.MONTH);
		    gc.roll(Calendar.MONTH, months);
		    int dayAfter = gc.get(Calendar.MONTH);
		    if(dayAfter < dayBefore) {
		        gc.roll(Calendar.YEAR, 1);
		    }
		    gc.get(Calendar.DATE);
		    java.util.Date yesterday = gc.getTime();
		    //System.out.println("Yesterdays Date = " + sdf.format(yesterday));
		    specificDate=sdf.format(yesterday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    	    
		return specificDate;
	}

	public String getDateBeforeMonths(String inputDate, Integer months,String dateFormat){ 
		String specificDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		    GregorianCalendar gc = new GregorianCalendar();
		    java.util.Date d = sdf.parse(inputDate);
		    
		    gc.setTime(d);
		    
		    int monthCurrent = gc.get(Calendar.MONTH);
		    gc.roll(Calendar.MONTH, -months);
		    int monthAfter = gc.get(Calendar.MONTH);
			if(monthAfter > monthCurrent) {
			    gc.roll(Calendar.YEAR, -1);
			}
			
		    gc.get(Calendar.DATE);
		    java.util.Date yesterday = gc.getTime();
		    //System.out.println("Yesterdays Date = " + sdf.format(yesterday));
		    specificDate=sdf.format(yesterday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    	    
		return specificDate;
	}
	
	public String getDateAfterYears(String inputDate, Integer years,String dateFormat){ 
		String specificDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		    GregorianCalendar gc = new GregorianCalendar();
		    java.util.Date d = sdf.parse(inputDate);
		    gc.setTime(d);
		    int dayBefore = gc.get(Calendar.DAY_OF_YEAR);
		    gc.roll(Calendar.YEAR, years);
		    int dayAfter = gc.get(Calendar.DAY_OF_YEAR);
		    if(dayAfter < dayBefore) {
		        gc.roll(Calendar.YEAR, 1);
		    }
		    gc.get(Calendar.DATE);
		    java.util.Date yesterday = gc.getTime();
		    //System.out.println("Yesterdays Date = " + sdf.format(yesterday));
		    specificDate=sdf.format(yesterday);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    	    
		return specificDate;
	}

	public Date getDateAfterYears(Integer years){ 
		Date date = new Date(); /// CURRENT DATE & ADD YEARS
		
		try {			
			Calendar cal = new GregorianCalendar();
			cal.setTime(date);
			cal.add(Calendar.YEAR, years);
			date = cal.getTime();

		} catch (Exception e) {
			e.printStackTrace();
		}
	    	    
		return date;
	}
	
/************************************************************
	Get current Month Last Date	
************************************************************/	
	public String getLastDateCurrentMonth(String dateFormat){ /// dateFormat MM/dd/yyyy
		Date today = new Date();  

		Calendar calendar = Calendar.getInstance();  
		calendar.setTime(today);  

		calendar.add(Calendar.MONTH, 1);  
		calendar.set(Calendar.DAY_OF_MONTH, 1);  
		calendar.add(Calendar.DATE, -1);  

		Date lastDayOfMonth = calendar.getTime();  

		DateFormat sdf = new SimpleDateFormat(dateFormat);  
		///System.out.println("Today            : " + sdf.format(today));  
		///System.out.println("Last Day of Month: " + sdf.format(lastDayOfMonth));
		
		return sdf.format(lastDayOfMonth);
	}
	
	public String getLastDateNextMonth(String dateFormat){ /// dateFormat MM/dd/yyyy
		Date today = new Date();  

		Calendar calendar = Calendar.getInstance();  
		calendar.setTime(today);  

		calendar.add(Calendar.MONTH, 2);  
		calendar.set(Calendar.DAY_OF_MONTH, 1);  
		calendar.add(Calendar.DATE, -1);  

		Date lastDayOfMonth = calendar.getTime();  

		DateFormat sdf = new SimpleDateFormat(dateFormat);  
		///System.out.println("Today            : " + sdf.format(today));  
		///System.out.println("Last Day of Month: " + sdf.format(lastDayOfMonth));
		
		return sdf.format(lastDayOfMonth);
	}
	
	public String getFirstDateNextMonth(String dateFormat){ /// dateFormat MM/dd/yyyy
		Calendar date = Calendar.getInstance();
        date.set(Calendar.DAY_OF_MONTH, 1);
        date.add(Calendar.MONTH, 1);
        DateFormat df = new SimpleDateFormat(dateFormat);
        String startDate=df.format(date.getTime());
		return startDate;
	}

	public String getLastDateOfMonth(String d1, String dateFormat){ /// dateFormat MM/dd/yyyy

		Date date = getDate(d1, "dd-MM-yyyy");

		Calendar calendar = Calendar.getInstance();  
		calendar.setTime(date);  

		calendar.add(Calendar.MONTH, 1);  
		calendar.set(Calendar.DAY_OF_MONTH, 1);  
		calendar.add(Calendar.DATE, -1);  

		Date lastDayOfMonth = calendar.getTime();  

		DateFormat sdf = new SimpleDateFormat(dateFormat);  

		return sdf.format(lastDayOfMonth);
	}

	public String getConvertMinutesToHours(Integer totalMinutes){
		Integer hours = totalMinutes / 60; 
		Integer minutes = totalMinutes % 60;
		return hours+":"+minutes;
	}
	
/************************************************************
	Difference Duration between two Time stamp	
************************************************************/	
	public String getDifferenceTwoTimestamp(Date dt1 , Date dt2){
		
		String returnStr = null;

        long diff = dt2.getTime() - dt1.getTime();
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000);
        int diffInDays = (int) ((dt2.getTime() - dt1.getTime()) / (1000 * 60 * 60 * 24));

        if (diffInDays > 1) {
        	returnStr = diffInDays+" days";
        } else if (diffInDays == 1) {
           	returnStr = diffInDays+" day";
        } else if (diffHours <= 24 && diffHours == 1) {
        	returnStr = diffHours+" hour";
        } else if (diffHours <= 24 && diffHours > 1) {
        	returnStr = diffHours+" hours";
        } else if ((diffHours < 1) && (diffMinutes > 1)) {
        	returnStr = diffMinutes+" minutes";
        } else {
        	returnStr = "1 minute";
        }
        
		return returnStr;
	}

	
/************************************************************
	Get Day/Month/Year from a date  Beware, months start at 0, not 1.	
************************************************************/	
	public Integer[] getDayMonthYear(Date date){
		Integer[] returnArr = new Integer[3];		
		
		try {
			String dateStr = this.dateToString(date, "dd-MM-yyyy");
			String[] dateArr = dateStr.split("-");
			returnArr[0] = Integer.valueOf(dateArr[0]);
			returnArr[1] = Integer.valueOf(dateArr[1]); 
			returnArr[2] = Integer.valueOf(dateArr[2]);				
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    return returnArr;
	}

/************************************************************
	Get Date after some days from a date	
************************************************************/	
	public Date getDateBeforeAfter(Date date, Integer days){
		///Calendar calendar = new GregorianCalendar(/* remember about timezone! */);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, days);
		date = calendar.getTime();
	    return date;
	}

/************************************************************
	Get Opportunity Quarter	
************************************************************/	
	public Integer getQuarter(Integer startFYMonth, Integer currentMonth){
		
		Integer quarterInterval = 3;
		Integer quarterNum = 1;
		Integer j = 1, month=startFYMonth;
		for(Integer i=startFYMonth; i<=startFYMonth+11; i++){
			if(month>12){
				month=1;
			}
			if(month<=currentMonth && month>=currentMonth){
				return quarterNum;
			}
			if(j==quarterInterval){
				quarterNum++;
				j = 0;
			}	
			j++;
			month++;
		}
		return null;
	}
	
/************************************************************
	Get Current Time	
************************************************************/	
	public String getCurrentTime(){
		Calendar calendar = Calendar.getInstance();
		int hours = calendar.get(Calendar.HOUR_OF_DAY);
		int minutes = calendar.get(Calendar.MINUTE);
		int seconds = calendar.get(Calendar.SECOND);
		
		return hours+":"+minutes+":"+seconds; 
	}

	public String getIncrementHoursTime(Integer hour){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.HOUR, hour);

		int hours = calendar.get(Calendar.HOUR_OF_DAY);
		int minutes = calendar.get(Calendar.MINUTE);
		int seconds = calendar.get(Calendar.SECOND);
		
		return hours+":"+minutes+":"+seconds;
	}

	public String getIncrementMinutesTime(Integer min){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.MINUTE, min);

		int hours = calendar.get(Calendar.HOUR_OF_DAY);
		int minutes = calendar.get(Calendar.MINUTE);
		int seconds = calendar.get(Calendar.SECOND);
		
		return hours+":"+minutes+":"+seconds;
	}

	public Long getTimeDifferenceMinutes(String time1, String time2){
		try{

			System.out.println("getTimeDifferenceMinutes time1: "+time1);
			System.out.println("getTimeDifferenceMinutes time2: "+time2);
					
			SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
			Date date1 = format.parse(time1);
			Date date2 = format.parse(time2);
			
			System.out.println("getTimeDifferenceMinutes date1: "+date1);
			System.out.println("getTimeDifferenceMinutes date2: "+date2);
			
			long difference = date2.getTime() - date1.getTime();

			System.out.println("getTimeDifferenceMinutes difference: "+difference);
			
			long minutes = difference/(1000*60);
			if(minutes<0){
				minutes = 0;
			}
			
			return minutes;
			
		}catch(Exception e){
			e.getStackTrace();
		}
		return null;
	}

/************************************************************
	Get Days Between Dates	
************************************************************/	
	public Integer getDaysBetweenDates(String inputDate1, String inputDate2 ){
		SimpleDateFormat myFormat = new SimpleDateFormat("dd-MM-yyyy");
		Integer days = null;
		try {
		    Date date1 = myFormat.parse(inputDate1);
		    Date date2 = myFormat.parse(inputDate2);
		    long diff = date2.getTime() - date1.getTime();
		    days = Integer.valueOf((int)TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
		} catch (ParseException e) {
		    e.printStackTrace();
		}		
		return days;
	}

	public Integer getDaysBetweenDates(Date inputDate1, Date inputDate2 ){
		long diff = inputDate2.getTime() - inputDate1.getTime();
		Integer days = Integer.valueOf((int)TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));		
		return days;
	}
	
	public static Date getDate(String s, String dateFormat) {
	    DateFormat format = new SimpleDateFormat(dateFormat);
	    Date date = null;
	    try {
	        date = format.parse(s);
	    } catch (ParseException e) {
	        e.printStackTrace();
	    }
	    return date;
	}

	public List<String> getDaysBetweenDates(String d1, String d2, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		SimpleDateFormat sdf2 = new SimpleDateFormat("dd MMM, yyyy");
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			datesList.add(sdf2.format(c1.getTime())+"#"+sdf.format(c1.getTime())+"#"+sdf.format(c1.getTime()));
			c1.add(Calendar.DATE, 1);	
		}
		
		return datesList;
	}

	public List<String> getWeeksBetweenDates(String d1, String d2, String dateFormat) throws Exception { 
		List<String> datesList1 = getWeekDayDateList(d1, d2, "Sunday", "yyyy-MM-dd");
		List<String> datesList2 = getWeekDayDateList(d1, d2, "Saturday", "yyyy-MM-dd");

		List<String> datesList = new ArrayList<String>();
		
		for(int i=0; i<datesList2.size()-1; i++){
			datesList.add("Week "+(i+1)+"#"+datesList1.get(i)+"#"+datesList2.get(i+1));
		}
		
		/*System.out.println("Sunday >>>> " + Arrays.asList(datesList1) );
		System.out.println("Saturday >>>> " + Arrays.asList(datesList2) );
		System.out.println("Final >>>> " + Arrays.asList(datesList) );*/
		
		return datesList;
	}

	public List<String> getMonthsBetweenDates(String d1, String d2, String dateFormat) throws Exception { 
		List<String> datesList1 = getFirstDateOfMonthBetweenDates(d1, d2, "yyyy-MM-dd");
		List<String> datesList2 = getLastDateOfMonthBetweenDates(d1, d2, "yyyy-MM-dd");

		List<String> datesList = new ArrayList<String>();
		
		for(int i=0; i<datesList2.size(); i++){
			datesList.add("Month "+(i+1)+"#"+datesList1.get(i)+"#"+datesList2.get(i));
		}
		
		/*System.out.println("datesList1 >>>> " + Arrays.asList(datesList1) );
		System.out.println("datesList2 >>>> " + Arrays.asList(datesList2) );
		System.out.println("Final >>>> " + Arrays.asList(datesList) );*/
		
		return datesList;
	}

	public List<String> getQuarterlyBetweenDates(String d1, String d2, String dateFormat) throws Exception { 
		List<String> datesList1 = getFirstDateOfQuarterBetweenDates(d1, d2, "yyyy-MM-dd");
		List<String> datesList2 = getLastDateOfQuarterBetweenDates(d1, d2, "yyyy-MM-dd");

		List<String> datesList = new ArrayList<String>();
		
		for(int i=0; i<datesList2.size(); i++){
			datesList.add("Quarter "+(i+1)+"#"+datesList1.get(i)+"#"+datesList2.get(i));
		}
		
		/*System.out.println("datesList1 >>>> " + Arrays.asList(datesList1) );
		System.out.println("datesList2 >>>> " + Arrays.asList(datesList2) );
		System.out.println("Final >>>> " + Arrays.asList(datesList) );*/
		
		return datesList;
	}

	public List<String> getYearsBetweenDates(String d1, String d2) {
		Date first = getDate(d1, "dd-MM-yyyy");
		Date second = getDate(d2, "dd-MM-yyyy");
        Calendar firstCal = GregorianCalendar.getInstance();
        Calendar secondCal = GregorianCalendar.getInstance();
        firstCal.setTime(first);
        secondCal.setTime(second);

        Integer startYear = firstCal.get(Calendar.YEAR);
        Integer endYear = secondCal.get(Calendar.YEAR);

        List<String> datesList = new ArrayList<String>();
        
        if(startYear!=null && endYear!=null && startYear<=endYear){
        	Integer j=1;
	        for(Integer i=startYear; i<=endYear; i++){
	        	datesList.add("Year "+j+"#"+i+"-01-01"+"#"+i+"-12-31");
	        	j++;
	        }
        }
        
        return datesList;
    }

	public List<String> getWeekDayDateList(String d1, String d2, String dayName, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		int objDayNum = 0;
		if(dayName.equals("Sunday")){
			objDayNum = Calendar.SUNDAY;
		}else if(dayName.equals("Monday")){
			objDayNum = Calendar.MONDAY;
		}else if(dayName.equals("Tuesday")){
			objDayNum = Calendar.TUESDAY;
		}else if(dayName.equals("Wednesday")){
			objDayNum = Calendar.WEDNESDAY;
		}else if(dayName.equals("Thursday")){
			objDayNum = Calendar.THURSDAY;
		}else if(dayName.equals("Friday")){
			objDayNum = Calendar.FRIDAY;
		}else if(dayName.equals("Saturday")){
			objDayNum = Calendar.SATURDAY;
		}
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_WEEK) == objDayNum) {
				datesList.add(sdf.format(c1.getTime()));
				////System.out.println(c1.getTime().toString() +" == "+ c1.get(Calendar.DAY_OF_MONTH) +" is a " + dayName);
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		return datesList;
	}

	public String getLastWeekDayDateOfMonth(String date, String dayName, String dateFormat) throws Exception { 
		
		int objDayNum = 0;
		if(dayName.equals("Sunday")){
			objDayNum = Calendar.SUNDAY;
		}else if(dayName.equals("Monday")){
			objDayNum = Calendar.MONDAY;
		}else if(dayName.equals("Tuesday")){
			objDayNum = Calendar.TUESDAY;
		}else if(dayName.equals("Wednesday")){
			objDayNum = Calendar.WEDNESDAY;
		}else if(dayName.equals("Thursday")){
			objDayNum = Calendar.THURSDAY;
		}else if(dayName.equals("Friday")){
			objDayNum = Calendar.FRIDAY;
		}else if(dayName.equals("Saturday")){
			objDayNum = Calendar.SATURDAY;
		}
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);

		Date date1 = getDate(this.getLastDateOfMonth(date, "dd-MM-yyyy"), "dd-MM-yyyy");
		
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date1);
		c2.add(Calendar.DATE, 1);
		while (c1.before(c2)) {
			if (c1.get(Calendar.DAY_OF_WEEK) == objDayNum) {
				return sdf.format(c1.getTime());
			}
			c1.add(Calendar.DATE, -1);	
		}
		
		return null;
	}

	public String getPositionWeekDayDateOfMonth(Integer positionNum,String date, String dayName, String dateFormat) throws Exception { 
		
		int objDayNum = 0;
		if(dayName.equals("Sunday")){
			objDayNum = Calendar.SUNDAY;
		}else if(dayName.equals("Monday")){
			objDayNum = Calendar.MONDAY;
		}else if(dayName.equals("Tuesday")){
			objDayNum = Calendar.TUESDAY;
		}else if(dayName.equals("Wednesday")){
			objDayNum = Calendar.WEDNESDAY;
		}else if(dayName.equals("Thursday")){
			objDayNum = Calendar.THURSDAY;
		}else if(dayName.equals("Friday")){
			objDayNum = Calendar.FRIDAY;
		}else if(dayName.equals("Saturday")){
			objDayNum = Calendar.SATURDAY;
		}
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);

		Date date1 = getDate(date, "dd-MM-yyyy");
		
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date1);
		c2.add(Calendar.DATE, -1);
		int pos = 1;
		while (c1.after(c2)) {
			if (c1.get(Calendar.DAY_OF_WEEK) == objDayNum) {
				if(positionNum==pos){
					return sdf.format(c1.getTime());
				}
				pos++;
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		return null;
	}

	public List<String> getMonthDayRepeatBetweenDates(String d1, String d2, Integer dayNum, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_MONTH) == dayNum) {
				datesList.add(sdf.format(c1.getTime()));
				////System.out.println(c1.getTime().toString() +" == "+ c1.get(Calendar.DAY_OF_MONTH) +" is a " + dayName);
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		return datesList;
	}

	public List<String> getMonthNameAndDayRepeatBetweenDates(String d1, String d2, Integer dayNum, String monthName, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		Map<String, String> monthNameMap = new HashMap<String, String>();
		monthNameMap.put("January","0");
		monthNameMap.put("February","1");
		monthNameMap.put("March","2");
		monthNameMap.put("April","3");
		monthNameMap.put("May","4");
		monthNameMap.put("June","5");
		monthNameMap.put("July","6");
		monthNameMap.put("August","7");
		monthNameMap.put("September","8");
		monthNameMap.put("October","9");
		monthNameMap.put("November","10");
		monthNameMap.put("December","11");
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_MONTH) == dayNum && c1.get(Calendar.MONTH) == Integer.valueOf(monthNameMap.get(monthName)) ) {
				datesList.add(sdf.format(c1.getTime()));
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		return datesList;
	}

	public List<String> getFirstDateOfMonthBetweenDates(String d1, String d2, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_MONTH) == 1) {
				datesList.add(sdf.format(c1.getTime()));
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		return datesList;
	}

	public List<String> getLastDateOfMonthBetweenDates(String d1, String d2, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_MONTH) == c1.getActualMaximum(Calendar.DAY_OF_MONTH)) {
				datesList.add(sdf.format(c1.getTime()));
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		return datesList;
	}

	public Date getFirstDayOfQuarter(Date date) {
	    Calendar cal = Calendar.getInstance();
	    cal.setTime(date);
	    cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)/3 * 3);
	    cal.set(Calendar.DAY_OF_MONTH, 1);
	    return cal.getTime();
	}

	public Date getLastDayOfQuarter(Date date) {
	    Calendar cal = Calendar.getInstance();
	    cal.setTime(date);
	    cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)/3 * 3 + 2);
	    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
	    return cal.getTime();
	}

	public List<String> getFirstDateOfQuarterBetweenDates(String d1, String d2, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_MONTH) == 1) {
				datesList.add(sdf.format(getFirstDayOfQuarter(c1.getTime())));
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		/// remove duplicates through Set list
		if(datesList!=null && datesList.size()>0){
			Set<String> hashSet = new HashSet<>();
			hashSet.addAll(datesList);
			datesList.clear();
			datesList.addAll(hashSet);
			Collections.sort(datesList);
		}
		
		return datesList;
	}

	public List<String> getLastDateOfQuarterBetweenDates(String d1, String d2, String dateFormat) throws Exception { 

		Date date1 = getDate(d1, "dd-MM-yyyy");
		Date date2 = getDate(d2, "dd-MM-yyyy");
		
		List<String> datesList = new ArrayList<String>();
		
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		c2.add(Calendar.DATE, 1);
		while (c2.after(c1)) {
			if (c1.get(Calendar.DAY_OF_MONTH) == 1) {
				datesList.add(sdf.format(getLastDayOfQuarter(c1.getTime())));
			}
			c1.add(Calendar.DATE, 1);	
		}
		
		/// remove duplicates through Set list
		if(datesList!=null && datesList.size()>0){
			Set<String> hashSet = new HashSet<>();
			hashSet.addAll(datesList);
			datesList.clear();
			datesList.addAll(hashSet);
			Collections.sort(datesList);
		}
		
		return datesList;
	}

	public int getTotalYearsBetweenDates(String d1, String d2) {
		Date first = getDate(d1, "dd-MM-yyyy");
		Date second = getDate(d2, "dd-MM-yyyy");
        Calendar firstCal = GregorianCalendar.getInstance();
        Calendar secondCal = GregorianCalendar.getInstance();
        firstCal.setTime(first);
        secondCal.setTime(second);
        secondCal.add(Calendar.DAY_OF_YEAR, 1 - firstCal.get(Calendar.DAY_OF_YEAR));

        return secondCal.get(Calendar.YEAR) - firstCal.get(Calendar.YEAR);
    }

	public Integer getAgeInDays(Long oldTime){
		long diff = new Date().getTime() - oldTime;
		Integer days = Integer.valueOf((int)TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));		
		return days;
    }
	
	public Integer getAgeInMinutes(Long oldTime) {
		long diff = new Date().getTime() - oldTime;
		Integer minutes = Integer.valueOf((int)TimeUnit.MINUTES.convert(diff, TimeUnit.MILLISECONDS));		
		return minutes;
    }

	
}
