/*** * Copyright (c) 2008, Endless Loop Software, Inc. * * This file is part of EgoNet. * * EgoNet is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * EgoNet is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.egonet.util; import java.text.ParseException; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ELSCalendar extends GregorianCalendar implements Comparable<Calendar> { final private static byte[] QUARTERS = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3}; final private static byte[] QUARTER_STARTS = {Calendar.JANUARY, Calendar.APRIL, Calendar.JULY, Calendar.OCTOBER}; final private static byte[] QUARTER_ENDS = {Calendar.MARCH, Calendar.JUNE, Calendar.SEPTEMBER, Calendar.DECEMBER}; final private static Logger logger = LoggerFactory.getLogger(ELSCalendar.class); /** * <p>Instantiates an ELSCalendar representing the current date</p> * @return ELSCalendar for current date */ public ELSCalendar() { this(Calendar.getInstance()); } /** * <p>Instantiates an ELSCalendar for date represented by Date param</p> * @param date Date to which to initialize ELSCalendar * @return ELSCalendar for param date */ public ELSCalendar(Date date) { super(); Calendar cal = Calendar.getInstance(); cal.setTime(date); this.clear(); this.set(Calendar.YEAR, cal.get(Calendar.YEAR)); this.set(Calendar.MONTH, cal.get(Calendar.MONTH)); this.set(Calendar.DATE, cal.get(Calendar.DATE)); } /** * <p>Instantiates an ELSCalendar a given year/month/day triplet</p> * @param year * @param month * @param date * @return ELSCalendar for param date */ public ELSCalendar(int year, int month, int date) { super(); this.set(Calendar.YEAR, year); this.set(Calendar.MONTH, month); this.set(Calendar.DATE, date); } /** * <p>Instantiates an ELSCalendar for date represented by Calendar param</p> * @param calendar date to which to initialize ELSCalendar * @return ELSCalendar for param date */ public ELSCalendar(Calendar calendar) { this(calendar.getTime()); } /** * <p>Instantiates an ELSCalendar representing the current date</p> * @return ELSCalendar for current date */ public static ELSCalendar now() { return new ELSCalendar(); } /** * <p>Sets date to that of another ELSCalendar</p> * @param ELSCalendar for desired date */ public void setTime(ELSCalendar cal) { this.clear(); this.set(Calendar.YEAR, cal.get(Calendar.YEAR)); this.set(Calendar.MONTH, cal.get(Calendar.MONTH)); this.set(Calendar.DATE, cal.get(Calendar.DATE)); } /** * <p>Sets date to that of another ELSCalendar</p> * @param ELSCalendar for desired date */ public static ELSCalendar mySQLCalendar(String dateString) throws ParseException { if ("0000-00-00".equals(dateString)) return null; else return new ELSCalendar(DateUtils.parseMySQLDateString(dateString)); } /** * <p>Compares this to another date.</p> * @return -1 if this before, 0 if equal to, and 1 if after param Calendar */ public int compareTo(Calendar that) { if (this.before(that)) { return -1; } else if (this.after(that)) { return 1; } else { return 0; } } /** * <p>Routine which finds the Date matching the previous day matching * the param Day of Week. </p> * @param dow Day of Week to find * @param checkToday consider today as a possible match * @return ELSCalendar of previous day matching param Day of Week */ public ELSCalendar getPriorWeekdayInstance(int dow, boolean checkToday) { int thisdow = this.get(Calendar.DAY_OF_WEEK); ELSCalendar cal = (ELSCalendar) this.clone(); if (thisdow > dow) { cal.add(Calendar.DATE, dow - thisdow); } else if (thisdow < dow) { cal.add(Calendar.DATE, dow - thisdow - 7); } else { cal.add(Calendar.DATE, checkToday ? 0 : -7); } return cal; } /** * <p>Routine which determines if this is a given day of week</p> * @param dow Day of Week to check * @return true iff this is param dow */ public boolean isWeekdayInstance(int dow) { return (this.get(Calendar.DAY_OF_WEEK) == dow); } /** * <p>Routine which finds the Date matching the next day matching * the param Day of Week. </p> * @param dow Day of Week to find * @param checkToday consider today as a possible match * @return ELSCalendar of previous day matching param Day of Week */ public ELSCalendar getNextWeekdayInstance(int dow, boolean checkToday) { int thisdow = this.get(Calendar.DAY_OF_WEEK); ELSCalendar cal = (ELSCalendar) this.clone(); /* Calculate start and end of work week */ if (thisdow > dow) { cal.add(Calendar.DATE, 7 - (thisdow - dow)); } else if (thisdow < dow) { cal.add(Calendar.DATE, dow - thisdow); } else { cal.add(Calendar.DATE, checkToday ? 0 : 7); } return cal; } /** * <p>Routine which finds the Calendar for the first day of this quarter </p> * @return ELSCalendar of first day of the this quarter */ public ELSCalendar getQuarterStart() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.set(Calendar.DATE, 1); cal.set(Calendar.MONTH, QUARTER_STARTS[QUARTERS[this.get(Calendar.MONTH)]]); return cal; } /** * <p>Routine which finds the Calendar for the last day of this quarter </p> * @return ELSCalendar of last day of this quarter */ public ELSCalendar getQuarterEnd() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.set(Calendar.MONTH, QUARTER_ENDS[QUARTERS[this.get(Calendar.MONTH)]]); cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE)); return cal; } /** * <p>Routine which finds the Calendar for the first day of the prior quarter </p> * @return ELSCalendar of first day of the prior quarter */ public ELSCalendar getPriorQuarterStart() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.add(Calendar.MONTH, -3); return cal.getQuarterStart(); } /** * <p>Routine which finds the Calendar for the last day of the prior quarter </p> * @return ELSCalendar of last day of the prior quarter */ public ELSCalendar getPriorQuarterEnd() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.add(Calendar.MONTH, -3); return cal.getQuarterEnd(); } /** * <p>Routine which finds the Calendar for the first day of this quarter </p> * @return ELSCalendar of first day of the this quarter */ public ELSCalendar getYearStart() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.set(Calendar.DATE, 1); cal.set(Calendar.MONTH, Calendar.JANUARY); return cal; } /** * <p>Routine which finds the Calendar for the last day of this quarter </p> * @return ELSCalendar of last day of this quarter */ public ELSCalendar getYearEnd() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.set(Calendar.MONTH, Calendar.DECEMBER); cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE)); return cal; } /** * <p>Routine which finds the Calendar for the first day of the prior quarter </p> * @return ELSCalendar of first day of the prior quarter */ public ELSCalendar getPriorYearStart() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.add(Calendar.MONTH, -12); return cal.getYearStart(); } /** * <p>Routine which finds the Calendar for the last day of the prior quarter </p> * @return ELSCalendar of last day of the prior quarter */ public ELSCalendar getPriorYearEnd() { ELSCalendar cal = (ELSCalendar) this.clone(); cal.add(Calendar.MONTH, -12); return cal.getYearEnd(); } /** * <p>Checks if start <= this <= end</p> * @param start first day of period to match * @param end last day of period to match * @return true iff start <= now <= end */ public boolean isInPeriod(ELSCalendar start, ELSCalendar end) { return ((!start.after(this)) && (!this.after(end))); } /** * <p>Returns the interval between two dates as an ELS Calendar. The * year field indicates the years between the dates, etc.. The order of * dates is irrelevant</p> * @param date1 one end of interval * @param date2 the other end of the interval * @return ELSCalendar of interval */ public static Interval getInterval(ELSCalendar date1, ELSCalendar date2) { Interval interval = new Interval(); /* Assure date2 follows date1 */ if (date1.after(date2)) { ELSCalendar date3 = date1; date1 = date2; date2 = date3; } int year1 = date1.get(Calendar.YEAR); int year2 = date2.get(Calendar.YEAR); int month1 = date1.get(Calendar.MONTH); int month2 = date2.get(Calendar.MONTH); int day1 = date1.get(Calendar.DATE); int day2 = date2.get(Calendar.DATE); interval.setYears(year2 - year1); if ((month1 > month2) || ((month1 == month2) && (day1 > day2))) { interval.setYears(interval.getYears() - 1); } interval.setMonths(interval.getYears() * 12); if (month2 >= month1) { interval.setMonths(interval.getMonths() + (month2 - month1)); } else { interval.setMonths(interval.getMonths() + (12 - (month1 - month2))); } long deltamillis = date2.getTimeInMillis() - date1.getTimeInMillis(); interval.setDays((int) ELSMath.ceilingQuotient(deltamillis, 1000 * 60 * 60 * 24)); return interval; } /** * <p>Returns java.sql.Date for midnight of date represented by this ELSCalendar</p> * @return sql date for midnight of this date */ public java.sql.Date toSqlDate() { return new java.sql.Date(this.getTimeInMillis()); } /** * <p>Returns java.sql.Date for midnight of date represented by param Calendar</p> * @param cal Calendar to convert to an sqlDate * @return sql date for midnight of param date */ public static java.sql.Date parseSqlDate(Calendar cal) { return new ELSCalendar(cal).toSqlDate(); } /** * <p>Returns java.sql.Date for midnight of date represented by param Date</p> * @param date java.util.Date to convert to an sqlDate * @return sql date for midnight of param date */ public static java.sql.Date parseSqlDate(java.util.Date date) { return new ELSCalendar(date).toSqlDate(); } /** * <p>Returns string representation of date in format mm/dd/yyyy</p> * @return string representation of this date */ public String toString() { return DateUtils.getDateString(this.getTime()); } /** * <p>Returns string representation of date in parameter format</p> * @param format String format in SimpleDateFormat style * @return string representation of this date */ public String toString(String format) { return DateUtils.getDateString(this.getTime(), format); } /** * Returns a java.sql.Timestamp for the current time, useful when timestamping stuff * @return timestamp for now */ public static java.sql.Timestamp timestamp() { return (new java.sql.Timestamp(new java.util.Date().getTime())); } public static void main(String[] args) { logger.info(new ELSCalendar().toString()); logger.info(new ELSCalendar(Calendar.getInstance()).toString()); logger.info(new ELSCalendar(Calendar.getInstance().getTime()).toString()); ELSCalendar lastSunday = new ELSCalendar().getPriorWeekdayInstance(Calendar.SUNDAY, false); ELSCalendar lastMonday = new ELSCalendar().getPriorWeekdayInstance(Calendar.MONDAY, false); ELSCalendar nextSunday = new ELSCalendar().getNextWeekdayInstance(Calendar.SUNDAY, true); ELSCalendar nextMonday = new ELSCalendar().getNextWeekdayInstance(Calendar.MONDAY, true); logger.info(lastSunday.toString()); logger.info(lastMonday.toString()); logger.info(lastSunday.isWeekdayInstance(Calendar.SUNDAY) + " --> Expects true"); logger.info(lastSunday.isWeekdayInstance(Calendar.MONDAY) + " --> Expects false"); logger.info(ELSCalendar.getInterval(lastSunday, nextSunday).toString()); logger.info(ELSCalendar.getInterval(nextMonday, lastMonday).toString()); logger.info(lastMonday.isInPeriod(lastSunday, nextSunday) + " --> Expects true"); logger.info(lastMonday.isInPeriod(lastMonday, nextMonday) + " --> Expects true"); logger.info(nextMonday.isInPeriod(lastSunday, nextSunday) + " --> Expects false"); logger.info("Year/Quarter Calculations"); ELSCalendar now = ELSCalendar.now(); logger.info(now.getPriorYearStart().toString()); logger.info(now.getPriorYearEnd().toString().toString()); logger.info(now.getPriorQuarterStart().toString()); logger.info(now.getPriorQuarterEnd().toString()); logger.info(now.getYearStart().toString()); logger.info(now.getQuarterStart().toString()); logger.info(now.getQuarterEnd().toString()); logger.info(now.getYearEnd().toString()); } } /** * $Log: ELSCalendar.java,v $ * Revision 1.1.1.1 2005/10/23 16:21:25 schoaff * Checking from IntelliJ IDEA * * Revision 1.1.1.1 2005/03/23 13:22:21 schoaff * New CVS Repository * * Revision 1.4 2003/12/03 18:08:23 admin * Adding Gif Encoders * * Revision 1.3 2003/09/16 15:26:32 admin * Improved DateChooser and PhoneBean * * Revision 1.2 2003/09/13 18:44:42 admin * Adding Header * */