/**
*
*/
package src.com;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
public class CalendarUtil {
private static final int AP_DAILY_START_TIME_HOUR_OF_DAY = 1;
private static final int EU_DAILY_START_TIME_HOUR_OF_DAY = 9;
private static final int NA_DAILY_START_TIME_HOUR_OF_DAY = 17;
private static final int AP_WEEKLY_START_TIME_HOUR_OF_DAY = 1;
private static final int EU_WEEKLY_START_TIME_HOUR_OF_DAY = 7;
private static final int NA_WEEKLY_START_TIME_HOUR_OF_DAY = 16;
// Timezone key
public static final String ASIA_PACIFIC = "AP";
public static final String EUROPE = "EU";
public static final String NORTH_AMERICA = "NA";
public static final String GLOBAL_DATE_FORMAT = "dd MMM yyyy";
public static final String DATE_TIME_FORMAT = "dd/MM/yyyy HH:mm:ss";
private CalendarUtil() {
}
/**
* Get Monday for the specified date
* @param inputDate The specified date
* @return Calendar Monday for the specified date
*/
public static Calendar getMonday(Date inputDate) {
Calendar monday = null;
if (inputDate != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(inputDate);
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
if (weekday != Calendar.MONDAY) {
// Calculate how much to add
// The 2 is the difference between Saturday and Monday
int days = (Calendar.SATURDAY - weekday + 2) % 7;
calendar.add(Calendar.DAY_OF_YEAR, days);
}
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
monday = calendar;
}
return monday;
}
/**
* Get Saturday for the specified date
* @param inputDate The specified date
* @return Calendar Saturday for the specified date
*/
public static Calendar getSaturday(Date inputDate) {
Calendar saturday = null;
if (inputDate != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(inputDate);
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
if (weekday != Calendar.SATURDAY) {
// Calculate how much to add
// The 7 is the difference between Saturday and next Saturday
int days = (Calendar.SATURDAY - weekday + 7) % 7;
calendar.add(Calendar.DAY_OF_YEAR, days);
}
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
saturday = calendar;
}
return saturday;
}
/**
* Get Sunday for the specified date
* @param inputDate The specified date
* @return Calendar Sunday for the specified date
*/
public static Calendar getSunday(Date inputDate) {
Calendar sunday = null;
if (inputDate != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(inputDate);
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
if (weekday != Calendar.SUNDAY) {
// Calculate how much to add
// The 1 is the difference between Saturday and Sunday
int days = (Calendar.SATURDAY - weekday + 1) % 7;
calendar.add(Calendar.DAY_OF_YEAR, days);
}
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
sunday = calendar;
}
return sunday;
}
/**
* Get the 1st weekday day of month for the specified date
* @param inputDate The specified date
* @return Calendar The 1st weekday day of month for the specified date
*/
public static Calendar getFirstWeekdayOfMonth(Date inputDate) {
Calendar firstWeekdayOfMonth = null;
if (inputDate != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(inputDate);
// Get the 1st weekday of current month
calendar.set(Calendar.DAY_OF_MONTH, 1);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.SATURDAY) {
calendar.add(Calendar.DATE, 2);
} else if (dayOfWeek == Calendar.SUNDAY) {
calendar.add(Calendar.DATE, 1);
}
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
firstWeekdayOfMonth = calendar;
}
return firstWeekdayOfMonth;
}
public static Calendar setAsiaPacificDailyJobStartTime(Calendar calendar) {
if (calendar != null) {
calendar.set(Calendar.HOUR_OF_DAY, AP_DAILY_START_TIME_HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
return calendar;
}
public static Calendar setEuropeDailyJobStartTime(Calendar calendar) {
if (calendar != null) {
calendar.set(Calendar.HOUR_OF_DAY, EU_DAILY_START_TIME_HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
return calendar;
}
public static Calendar setNorthAmericaDailyJobStartTime(Calendar calendar) {
if (calendar != null) {
calendar.set(Calendar.HOUR_OF_DAY, NA_DAILY_START_TIME_HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
return calendar;
}
public static Calendar setAsiaPacificWeeklyJobStartTime(Calendar calendar) {
if (calendar != null) {
calendar.set(Calendar.HOUR_OF_DAY, AP_WEEKLY_START_TIME_HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
return calendar;
}
public static Calendar setEuropeWeeklyJobStartTime(Calendar calendar) {
if (calendar != null) {
calendar.set(Calendar.HOUR_OF_DAY, EU_WEEKLY_START_TIME_HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
return calendar;
}
public static Calendar setNorthAmericaWeeklyJobStartTime(Calendar calendar) {
if (calendar != null) {
calendar.set(Calendar.HOUR_OF_DAY, NA_WEEKLY_START_TIME_HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
return calendar;
}
public static Date calculateDailyJobNextTriggeringDate(Date startDate, String timezone) {
Date nextTriggeringDate = null;
if (startDate != null) {
Calendar specifiedStartTime = Calendar.getInstance();
specifiedStartTime.setTime(startDate);
// Get specified time zone daily job triggering time for the start date
Calendar startDateTriggeringTime = Calendar.getInstance();
startDateTriggeringTime.setTime(specifiedStartTime.getTime());
if (EUROPE.equals(timezone)) {
startDateTriggeringTime = setEuropeDailyJobStartTime(startDateTriggeringTime);
} else if (NORTH_AMERICA.equals(timezone)) {
startDateTriggeringTime = setNorthAmericaDailyJobStartTime(startDateTriggeringTime);
} else {
startDateTriggeringTime = setAsiaPacificDailyJobStartTime(startDateTriggeringTime);
}
int weekday = specifiedStartTime.get(Calendar.DAY_OF_WEEK);
/*
* If the specified start time is greater than the specified timezone daily triggering time,
* and the week day is between Moday and Firday,
* the next triggering date should be the next day for the specified start time,
* otherwise the next triggering date should be the same day with the specified start time.
*/
if (weekday >= Calendar.MONDAY
&& weekday <= Calendar.FRIDAY
&& specifiedStartTime.after(startDateTriggeringTime)) {
startDateTriggeringTime.add(Calendar.DAY_OF_YEAR, 1);
}
/*
* If the week day is Saturday or Sunday,
* the next triggering date should be the next Monday.
*/
weekday = startDateTriggeringTime.get(Calendar.DAY_OF_WEEK);
if (weekday == Calendar.SATURDAY
|| weekday == Calendar.SUNDAY) {
startDateTriggeringTime = getMonday(startDateTriggeringTime.getTime());
}
nextTriggeringDate = startDateTriggeringTime.getTime();
}
return nextTriggeringDate;
}
public static Date calculateWeeklyJobNextTriggeringDate(Date startDate, String timezone) {
Date nextTriggeringDate = null;
if (startDate != null) {
Calendar specifiedStartTime = Calendar.getInstance();
specifiedStartTime.setTime(startDate);
// Get specified time zone weekly job triggering time for the start date
Calendar startDateTriggeringTime = Calendar.getInstance();
startDateTriggeringTime.setTime(specifiedStartTime.getTime());
if (EUROPE.equals(timezone)) {
startDateTriggeringTime = getSunday(startDateTriggeringTime.getTime());
startDateTriggeringTime = setEuropeWeeklyJobStartTime(startDateTriggeringTime);
} else if (NORTH_AMERICA.equals(timezone)) {
startDateTriggeringTime = getSunday(startDateTriggeringTime.getTime());
startDateTriggeringTime = setNorthAmericaWeeklyJobStartTime(startDateTriggeringTime);
} else {
startDateTriggeringTime = getSaturday(startDateTriggeringTime.getTime());
startDateTriggeringTime = setAsiaPacificWeeklyJobStartTime(startDateTriggeringTime);
}
if (specifiedStartTime.after(startDateTriggeringTime)) {
startDateTriggeringTime.add(Calendar.DAY_OF_YEAR, 7);
}
nextTriggeringDate = startDateTriggeringTime.getTime();
}
return nextTriggeringDate;
}
public static Date calculateBiWeeklyJobNextTriggeringDate(Date startDate, String timezone) {
Date nextTriggeringDate = null;
if (startDate != null) {
Calendar specifiedStartTime = Calendar.getInstance();
specifiedStartTime.setTime(startDate);
// Get specified time zone weekly job triggering time for the start date
Calendar startDateTriggeringTime = Calendar.getInstance();
startDateTriggeringTime.setTime(specifiedStartTime.getTime());
if (EUROPE.equals(timezone)) {
startDateTriggeringTime = getSunday(startDateTriggeringTime.getTime());
startDateTriggeringTime = setEuropeWeeklyJobStartTime(startDateTriggeringTime);
} else if (NORTH_AMERICA.equals(timezone)) {
startDateTriggeringTime = getSunday(startDateTriggeringTime.getTime());
startDateTriggeringTime = setNorthAmericaWeeklyJobStartTime(startDateTriggeringTime);
} else {
startDateTriggeringTime = getSaturday(startDateTriggeringTime.getTime());
startDateTriggeringTime = setAsiaPacificWeeklyJobStartTime(startDateTriggeringTime);
}
if (specifiedStartTime.after(startDateTriggeringTime)) {
startDateTriggeringTime.add(Calendar.DAY_OF_YEAR, 7);
}
// For Bi-Weekly logic
//int weekOfYear = startDateTriggeringTime.get(Calendar.WEEK_OF_YEAR);
int weekOfYear = getWeekOfYear(startDateTriggeringTime.getTime());
if (weekOfYear % 2 == 1) {
startDateTriggeringTime.add(Calendar.DAY_OF_YEAR, 7);
}
nextTriggeringDate = startDateTriggeringTime.getTime();
}
return nextTriggeringDate;
}
public static Date calculateMonthlyJobNextTriggeringDate(Date startDate, String timezone) {
Date nextTriggeringDate = null;
if (startDate != null) {
Calendar specifiedStartTime = Calendar.getInstance();
specifiedStartTime.setTime(startDate);
// Get specified time zone monthly job triggering time for the start date
Calendar startDateTriggeringTime = Calendar.getInstance();
startDateTriggeringTime.setTime(specifiedStartTime.getTime());
if (EUROPE.equals(timezone)) {
startDateTriggeringTime = getFirstWeekdayOfMonth(startDateTriggeringTime.getTime());
startDateTriggeringTime = setEuropeDailyJobStartTime(startDateTriggeringTime);
} else if (NORTH_AMERICA.equals(timezone)) {
startDateTriggeringTime = getFirstWeekdayOfMonth(startDateTriggeringTime.getTime());
startDateTriggeringTime = setNorthAmericaDailyJobStartTime(startDateTriggeringTime);
} else {
startDateTriggeringTime = getFirstWeekdayOfMonth(startDateTriggeringTime.getTime());
startDateTriggeringTime = setAsiaPacificDailyJobStartTime(startDateTriggeringTime);
}
if (specifiedStartTime.after(startDateTriggeringTime)) {
// Get the 1st weekday of next month
startDateTriggeringTime.set(Calendar.DAY_OF_MONTH, 1);
startDateTriggeringTime.add(Calendar.MONTH, 1);
startDateTriggeringTime = getFirstWeekdayOfMonth(startDateTriggeringTime.getTime());
}
nextTriggeringDate = startDateTriggeringTime.getTime();
}
return nextTriggeringDate;
}
public static int getWeekOfYear(Date date) {
Calendar specifiedDate = Calendar.getInstance();
specifiedDate.setTime(date);
specifiedDate.set(Calendar.HOUR_OF_DAY, 0);
specifiedDate.set(Calendar.MINUTE, 0);
specifiedDate.set(Calendar.SECOND, 0);
specifiedDate.set(Calendar.MILLISECOND, 0);
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
specifiedDate.setFirstDayOfWeek(Calendar.SUNDAY);
int weekday = specifiedDate.get(Calendar.DAY_OF_WEEK);
int differenceDays = 4 - (weekday - 1);
specifiedDate.add(Calendar.DAY_OF_YEAR, differenceDays);
// Date date2 = specifiedDate.getTime();
// Get first day of year
Calendar firstDayOfYear = Calendar.getInstance();
firstDayOfYear.setTime(specifiedDate.getTime());
firstDayOfYear.set(Calendar.MONTH, Calendar.JANUARY);
firstDayOfYear.set(Calendar.DAY_OF_MONTH, 1);
// Date date1 = firstDayOfYear.getTime();
// Calculate full weeks to nearest Thursday
long differenceValue = specifiedDate.getTime().getTime() - firstDayOfYear.getTime().getTime();
int weekOfYear = (int) Math.ceil(( (double)(differenceValue / 86400000 ) + 1) / 7);
return weekOfYear;
}
public static Date convertStringToDate(String date) {
Date dateTime = null;
try {
if (!isEmpty(date)
&& validateDate(date, GLOBAL_DATE_FORMAT)) {
DateFormat dateFormat =
new SimpleDateFormat(GLOBAL_DATE_FORMAT);
dateTime = dateFormat.parse(date);
}
} catch (Exception e) {
e.printStackTrace();
}
return dateTime;
}
public static String convertDateToString(Date dateTime) {
String date = null;
try {
if (dateTime != null) {
DateFormat dateFormat =
new SimpleDateFormat(GLOBAL_DATE_FORMAT);
date = dateFormat.format(dateTime);
}
} catch(Exception e){
e.printStackTrace();
}
if (date == null) {
date = "";
} else {
date = date.toUpperCase();
}
return date;
}
/**
* Check if the object is null.<p>
* If the object is an instance of String, empty String triggers returning true
* @param object
* @return
*/
public static boolean isEmpty(Object object){
boolean result = false;
if(object == null){
result = true;
} else if(object instanceof String){
if(((String)object).trim().equals("")){
result = true;
}
} else if(object instanceof HashMap){
if(((HashMap)object).size() == 0){
result = true;
}
} else if(object instanceof ArrayList){
if(((ArrayList)object).size() == 0){
result = true;
}
}
return result;
}
/**
* Validation Rule: Validate the input text whether it is valid date string or not by using specified date format
* @param inputText Input string text
* @return boolean Return true when the input text is valid date string or not by using specified date format,
* otherwise return false.
*/
private static boolean validateDate(String inputText, String format) {
boolean isValid = false;
try {
if (!Util.isEmpty(inputText)) {
DateFormat formatter = new SimpleDateFormat(format);
Date date = formatter.parse(inputText);
if (formatter.format(date).equalsIgnoreCase(inputText)) {
isValid = true;
} else {
isValid = false;
}
} else {
isValid = true;
}
} catch (Exception e) {
isValid = false;
}
return isValid;
}
}