Dates.java
package com.tradecloud.domain.common;
import org.apache.commons.lang.StringUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Utility class for routines related to dates (and to java.util.Date and
* Calendar in particular).
* <p>
* Ronan - March 7th. I just brought this in from BB as is. We can tidy or
* remove methods as required. I just thought there might be some useful stuff
* in here. You never know!!
*/
public class Dates {
// Extremes
public static final Date FIRST_DATE = new Date(Long.MIN_VALUE);
public static final Date LAST_DATE = new Date(Long.MAX_VALUE);
private static final SimpleDateFormat FULL_DAY_OF_WEEK_FORMAT = new SimpleDateFormat("EEEE");
private static final SimpleDateFormat ABBR_DAY_OF_WEEK_FORMAT = new SimpleDateFormat("E");
private static final DateFormat DEF_SHORT_DATE_FORMAT = DateFormat.getDateInstance(DateFormat.SHORT);
private static final SimpleDateFormat ZA_LONG_DATE_FORMAT = new SimpleDateFormat("d MMMM yyyy");
private static final SimpleDateFormat ZA_YMD_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
private static final SimpleDateFormat ZA_YMDHMS_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
private static final SimpleDateFormat ZA_HMS_FORMAT = new SimpleDateFormat("HH:mm:ss");
private static final SimpleDateFormat ZA_HM_FORMAT = new SimpleDateFormat("HH:mm");
/*
* Used only as a class-level singleton, so prevent instantiation.
*/
private Dates() {
}
/**
* Returns an array containing two <code>Date</code> objects: the 1st of
* which contains a date representing the first millisecond; and the 2nd of
* which contains a date representing the last millisecond of the day
* represented by the given date.
*/
public static Date[] getStartAndEndOfDay(Date date) {
Date[] results = new Date[2];
if (date == null)
return results;
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
results[0] = cal.getTime();
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
results[1] = cal.getTime();
return results;
}
public static Date getStartOfDay(Date date) {
if (date == null)
return null;
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
public static Date getEndOfDay(Date date) {
if (date == null)
return null;
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}
public static void setToStartOfDay(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
date.setTime(cal.getTime().getTime());
}
public static void setToEndOfDay(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
date.setTime(cal.getTime().getTime());
}
/**
* Truncates the time part to the level specified. Usefull if comparison to
* these levels are needed.
*
* @param date object to be truncated
* @param calendarField to what accuracy the Date object should be trucated.
*/
public static void truncateTimeTo(Date date, int calendarField) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
switch (calendarField) {
case Calendar.DAY_OF_YEAR:
cal.set(Calendar.HOUR_OF_DAY, 0);
case Calendar.HOUR:
cal.set(Calendar.MINUTE, 0);
case Calendar.MINUTE:
cal.set(Calendar.SECOND, 0);
case Calendar.SECOND:
cal.set(Calendar.MILLISECOND, 0);
}
date.setTime(cal.getTime().getTime());
}
public static java.sql.Date toSQLDate(Date date) {
if (date == null)
return null;
if (date instanceof java.sql.Date)
return (java.sql.Date) date;
else
return new java.sql.Date(date.getTime());
}
public static java.sql.Time toSQLTime(Date date) {
if (date == null)
return null;
if (date instanceof java.sql.Time)
return (java.sql.Time) date;
else
return new java.sql.Time(date.getTime());
}
public static java.sql.Timestamp toSQLTimestamp(Date date) {
if (date == null)
return null;
if (date instanceof java.sql.Timestamp)
return (java.sql.Timestamp) date;
else
return new java.sql.Timestamp(date.getTime());
}
/**
* Calculates the difference in days between the given start and end dates.
*/
public static int getDaysBetween(Date first, Date last) {
if (first == null || last == null)
throw new IllegalArgumentException("Neither first nor last date can be null.");
Calendar calFirst = new GregorianCalendar();
calFirst.setTime(first);
Calendar calLast = new GregorianCalendar();
calLast.setTime(last);
int doyFirst, doyLast, yFirst, yLast;
int sign;
if (first.after(last)) {
sign = -1;
yFirst = calLast.get(Calendar.YEAR);
doyFirst = calLast.get(Calendar.DAY_OF_YEAR);
yLast = calFirst.get(Calendar.YEAR);
doyLast = calFirst.get(Calendar.DAY_OF_YEAR);
} else {
sign = 1;
yFirst = calFirst.get(Calendar.YEAR);
doyFirst = calFirst.get(Calendar.DAY_OF_YEAR);
yLast = calLast.get(Calendar.YEAR);
doyLast = calLast.get(Calendar.DAY_OF_YEAR);
}
if (yFirst == yLast) {
return sign * (doyLast - doyFirst);
} else {
int days = doyLast;
int year = yLast - 1;
do {
days += getDaysInYear(year--);
} while (year >= yFirst);
return sign * (days - doyFirst);
}
}
public static long getDaysDifferenceBetweenDates(Date beginningDate, Date endDate) {
if (beginningDate == null && endDate == null) {
return 0;
}
Calendar date1 = Calendar.getInstance();
date1.setTime(beginningDate);
// need to add a day as the calculations should include the current day.
date1.add(Calendar.DAY_OF_MONTH, -1);
Calendar date2 = Calendar.getInstance();
date2.setTime(endDate);
// need to add a day as the calculations should include the current day.
date2.add(Calendar.DAY_OF_MONTH, 1);
long timeDiffInMillis = date2.getTimeInMillis() - date1.getTimeInMillis();
int totalHours = 24;
int totalMinutes = 60;
int totalSecs = 60;
int totalMilliSecs = 1000;
long diffDays = timeDiffInMillis / (totalHours * totalMinutes * totalSecs * totalMilliSecs);
if (beginningDate.after(endDate))
diffDays = 0;
return diffDays;
}
public static int getDaysInYear(int year) {
Calendar cal = new GregorianCalendar(year, Calendar.DECEMBER, 31);
return cal.get(Calendar.DAY_OF_YEAR);
}
public static Date addDays(Date date, int days) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.add(Calendar.DATE, days);
return cal.getTime();
}
public static Date add(Date date, int calendarField, int amount) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.add(calendarField, amount);
return cal.getTime();
}
public static boolean fallsBetween(Date date, Date startDate, Date endDate) {
if (date == null)
return false;
return date.equals(startDate) || date.equals(endDate) || (date.after(startDate) && date.before(endDate));
}
public static boolean isWeekDay(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
int dow = cal.get(Calendar.DAY_OF_WEEK);
return dow != Calendar.SATURDAY && dow != Calendar.SUNDAY;
}
public static boolean isWeekDay(Date date, Locale locale, TimeZone timeZone) {
Calendar cal = new GregorianCalendar(timeZone, locale);
cal.setTime(date);
int dow = cal.get(Calendar.DAY_OF_WEEK);
return dow != Calendar.SATURDAY && dow != Calendar.SUNDAY;
}
public static int getCurrentYear() {
return new GregorianCalendar().get(Calendar.YEAR);
}
public static int getCurrentMonth() {
return new GregorianCalendar().get(Calendar.MONTH);
}
public static int getCurrentDay() {
return new GregorianCalendar().get(Calendar.DAY_OF_MONTH);
}
public static int[] getYearMonthDay(Date date) {
int[] ymd = new int[3];
Calendar cal = new GregorianCalendar();
cal.setTime(date);
ymd[0] = cal.get(Calendar.YEAR);
ymd[1] = cal.get(Calendar.MONTH);
ymd[2] = cal.get(Calendar.DAY_OF_MONTH);
return ymd;
}
public static String[] getZeroPaddedYearMonthDay(Date date) {
String[] ymd = new String[3];
Calendar cal = new GregorianCalendar();
cal.setTime(date);
ymd[0] = "" + cal.get(Calendar.YEAR);
int m = cal.get(Calendar.MONTH) + 1;
if (m < 10)
ymd[1] = "0" + m;
else
ymd[1] = "" + m;
int d = cal.get(Calendar.DAY_OF_MONTH);
if (d < 10)
ymd[2] = "0" + d;
else
ymd[2] = "" + d;
return ymd;
}
public static int[] getHourMinuteSecond(Date date) {
int[] hms = new int[3];
Calendar cal = new GregorianCalendar();
cal.setTime(date);
hms[0] = cal.get(Calendar.HOUR_OF_DAY);
hms[1] = cal.get(Calendar.MINUTE);
hms[2] = cal.get(Calendar.SECOND);
return hms;
}
public static int[] getYMDHMS(Date date) {
int[] ymdhms = new int[6];
Calendar cal = new GregorianCalendar();
cal.setTime(date);
ymdhms[0] = cal.get(Calendar.YEAR);
ymdhms[1] = cal.get(Calendar.MONTH);
ymdhms[2] = cal.get(Calendar.DAY_OF_MONTH);
ymdhms[3] = cal.get(Calendar.HOUR_OF_DAY);
ymdhms[4] = cal.get(Calendar.MINUTE);
ymdhms[5] = cal.get(Calendar.SECOND);
return ymdhms;
}
public static String[] getMonths() {
SimpleDateFormat formatter = new SimpleDateFormat();
return formatter.getDateFormatSymbols().getMonths();
}
public static int getLastDayOfMonth(Date date) {
// Set to the first of the given month
Calendar lastDayOfMonth = new GregorianCalendar();
lastDayOfMonth.setTime(date);
lastDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
// Roll back around to end of same month
lastDayOfMonth.roll(Calendar.DAY_OF_MONTH, false);
// or alternatively:
// lastDayOfMonth.add( Calendar.MONTH, 1 );
// lastDayOfMonth.add( Calendar.DAY_OF_MONTH, -1 );
return lastDayOfMonth.get(Calendar.DAY_OF_MONTH);
}
public static int getLastDayOfMonth(int year, int month) {
// Set to the first of the given month
GregorianCalendar lastDayOfMonth = new GregorianCalendar(year, month, 1);
// Roll back around to end of same month
lastDayOfMonth.roll(Calendar.DAY_OF_MONTH, false);
// or alternatively:
// lastDayOfMonth.add( Calendar.MONTH, 1 );
// lastDayOfMonth.add( Calendar.DAY_OF_MONTH, -1 );
return lastDayOfMonth.get(Calendar.DAY_OF_MONTH);
}
public static int getDayOfWeek(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
return cal.get(Calendar.DAY_OF_WEEK);
}
public static char getDayOfWeek1stLetterOnly(Date date) {
String dow = getDayOfWeekAsString(date);
if (dow == null)
return '\0';
return Character.toUpperCase(dow.charAt(0));
}
public static String getDayOfWeekAbbreviated(Date date) {
return ABBR_DAY_OF_WEEK_FORMAT.format(date);
}
public static String getDayOfWeekAsString(Date date) {
return FULL_DAY_OF_WEEK_FORMAT.format(date);
}
public static String toShortFormat(Date date) {
if (date == null)
return null;
return DEF_SHORT_DATE_FORMAT.format(date);
}
public static String toZALongFormat(Date date) {
if (date == null)
return null;
return ZA_LONG_DATE_FORMAT.format(date);
}
public static String toZA_YMDFormat(Date date) {
if (date == null)
return null;
return ZA_YMD_FORMAT.format(date);
}
public static String toZA_YMDHMSFormat(Date date) {
if (date == null)
return null;
return ZA_YMDHMS_FORMAT.format(date);
}
public static String toZA_HMSFormat(Date date) {
if (date == null)
return null;
return ZA_HMS_FORMAT.format(date);
}
public static String toZA_HMFormat(Date date) {
if (date == null)
return null;
return ZA_HM_FORMAT.format(date);
}
public static Date clone(Date date) {
if (date == null)
return null;
return new Date(date.getTime());
}
/**
* Returns an array containing two <code>Date</code> objects: the 1st of
* which contains a date representing the first millisecond of the first day
* of the month; and the 2nd of which contains a date representing the last
* millisecond of the last day of the month in which the given date falls.
*/
public static Date[] getStartAndEndOfMonth(Date date) {
Date[] results = new Date[2];
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
results[0] = cal.getTime();
cal.set(Calendar.DAY_OF_MONTH, getLastDayOfMonth(date));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
results[1] = cal.getTime();
return results;
}
public static Date getStartOfMonth(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
public static Date getEndOfMonth(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, getLastDayOfMonth(date));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}
/**
* Combines the year, month and day fields of the given date with the hour,
* minute, second and millisecond fields of the given time and returns the
* resulting <code>Date</code> instance. If either date or time is null, a
* null Date will be returned.
*/
public static Date combine(Date date, Date time) {
if (date == null || time == null)
return null;
Calendar cal = new GregorianCalendar();
cal.setTime(date);
Calendar cal2 = new GregorianCalendar();
cal2.setTime(time);
cal.set(Calendar.HOUR_OF_DAY, cal2.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal2.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal2.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal2.get(Calendar.MILLISECOND));
return cal.getTime();
}
/**
* Converts the given date into a "standardized" / "normalized" time
* relative to the epoch. Returns a new <code>java.sql.Time</code> instance
* based on the given date's hour, minute, second and millisecond fields
* combined with the date fields of the "epoch" (i.e. January 1st 1970).
*/
public static java.sql.Time toEpochTime(Date dateTime) {
if (dateTime == null)
return null;
Calendar cal = new GregorianCalendar();
cal.setTime(dateTime);
cal.set(Calendar.YEAR, 1970);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
return new java.sql.Time(cal.getTime().getTime());
}
/**
* Converts the given date into a "standardized" / "normalized" time
* relative to the epoch. Returns a new <code>java.sql.Time</code> instance
* based on the given date's hour, minute, second and millisecond fields
* combined with the date fields of the "epoch" (i.e. January 1st 1970).
* <p>
* Synonym for <code>toEpochTime( Date )</code>.
*/
public static java.sql.Time toNormalizedTime(Date dateTime) {
return toEpochTime(dateTime);
}
/**
* Converts the given date into a "standardized" / "normalized" date with
* its hours, minutes, seconds and milliseconds all set to zero.
* <p>
* Returns a new <code>java.sql.Date</code> instance based on the given
* date's year, month and day fields combined with zeroised time fields.
*/
public static java.sql.Date toNormalizedSqlDate(Date dateTime) {
if (dateTime == null)
return null;
return new java.sql.Date(getStartOfDay(dateTime).getTime());
}
/**
* Converts the given date into a "standardized" / "normalized" date with
* its hours, minutes, seconds and milliseconds all set to zero.
* <p>
* Returns a new <code>java.util.Date</code> instance based on the given
* date's year, month and day fields combined with zeroised time fields.
*/
public static java.util.Date toNormalizedDate(Date dateTime) {
if (dateTime == null)
return null;
return new java.util.Date(getStartOfDay(dateTime).getTime());
}
public static Date toDate(int year, int month, int day) {
return new GregorianCalendar(year, month - 1, day).getTime();
}
/**
* Strict validation, that is the given year, month and day values must
* represent an actual date, i.e. given 2001, 1 and 33 this method would
* return false. This validation differs from the approach taken by
* <code>new GregorianCalendar(y,m,d)</code> and
* <code>DateFormate.parse(s)</code>, which accept almost any year, month
* and day values and simply end up with a possibly different valid date,
* for example 2001/01/33 would be converted to 2001/02/02.
*/
public static boolean isValid(int year, int month, int day) {
if (year < 0)
return false;
if (month < 1 || month > 12)
return false;
if (day < 1 || day > 31)
return false;
Calendar c = new GregorianCalendar(year, month - 1, day);
return (c.get(Calendar.DAY_OF_MONTH) == day && c.get(Calendar.MONTH) + 1 == month && c.get(Calendar.YEAR) == year);
}
/**
* Strict validation, that is the given year, month and day values must
* represent an actual date, i.e. given 2001, 1 and 33, or given empty
* Strings, this method would return false.
*/
public static boolean isValid(String year, String month, String day) {
if (year.equalsIgnoreCase("") || month.equalsIgnoreCase("") || day.equalsIgnoreCase(""))
return false;
int y = Integer.parseInt(year);
int m = Integer.parseInt(month);
int d = Integer.parseInt(day);
return isValid(y, m, d);
}
public static String getDaySuffix(Date date) {
String suffix = null;
if (date.getDate() > 9 && date.getDate() < 20) {
suffix = "th";
} else {
switch (date.getDate() % 10) {
case 1:
suffix = "st";
break;
case 2:
suffix = "nd";
break;
case 3:
suffix = "rd";
break;
default:
suffix = "th";
}
}
return suffix;
}
/**
* @return the first day of every month of the current year
*/
public static Date[] getStartDaysOfAllMonths() {
final Date[] startDays = new Date[12];
Calendar cal = Calendar.getInstance();
cal.setTime(getStartOfMonth(new Date()));
int[] monthconstants = {
Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY,
Calendar.AUGUST, Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER, Calendar.DECEMBER};
for (int i = 0; i < monthconstants.length; i++) {
cal.set(Calendar.MONTH, monthconstants[i]);
startDays[i] = cal.getTime();
}
return startDays;
}
public static String getYear(Date date) {
int[] ymd = date == null ? null : Dates.getYearMonthDay(date);
return ymd == null ? null : StringUtils.leftPad(String.valueOf(ymd[0]), 4, "0");
}
public static String getMonth(Date date) {
int[] ymd = date == null ? null : Dates.getYearMonthDay(date);
return ymd == null ? null : StringUtils.leftPad(String.valueOf(ymd[1] + 1), 2, "0");
}
public static String getDay(Date date) {
int[] ymd = date == null ? null : Dates.getYearMonthDay(date);
return ymd == null ? null : StringUtils.leftPad(String.valueOf(ymd[2]), 2, "0");
}
}