Java/Development Class/Day

Материал из Java эксперт
Перейти к: навигация, поиск

A class representing a moment in time

   <source lang="java">

/*

* This code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 
* License as published by the Free Software Foundation; either 
* version 2.1 of the License, or (at your option) any later version.
*
* This code 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public 
* License along with this program; if not, write to the Free 
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
* MA  02111-1307, USA.
*/

//package no.geosoft.cc.util; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; /**

* A class representing a moment in time. Extends Day which represents the day
* of the moment, and defines the time within the day to millisecond accuracy.
* 
* @author Jacob Dreyer ()
*/

public class Time extends Day {

 /**
  * Instantiate a Time object. The time is lenient meaning that illegal day
  * parameters can be specified and results in a recomputed day with legal
  * month/day values.
  * 
  * @param year
  *          Year of this time
  * @param month
  *          Month of this time
  * @param dayOfMonth
  *          Day of month of this time.
  * @param hours
  *          Hours of this time [0-23]
  * @param minutes
  *          Minutes of this time [0-23]
  * @param seconds
  *          Seconds of this time [0-23]
  */
 public Time(int year, int month, int dayOfMonth, int hours, int minutes, int seconds) {
   super(year, month, dayOfMonth);
   setHours(hours);
   setMinutes(minutes);
   setSeconds(seconds);
 }
 public Time(Day day, int hours, int minutes, int seconds) {
   this(day.getYear(), day.getMonth(), day.getDayOfMonth(), hours, minutes, seconds);
 }
 public Time(int hours, int minutes, int seconds) {
   this(new Day(), hours, minutes, seconds);
 }
 public Time() {
   calendar_ = new GregorianCalendar(); // Now
 }
 public void setDay(Day day) {
   setYear(day.getYear());
   setMonth(day.getMonth());
   setDayOfMonth(day.getDayOfMonth());
 }
 public void setHours(int hours) {
   calendar_.set(Calendar.HOUR_OF_DAY, hours);
 }
 public int getHours() {
   return calendar_.get(Calendar.HOUR_OF_DAY);
 }
 public void setMinutes(int minutes) {
   calendar_.set(Calendar.MINUTE, minutes);
 }
 public int getMinutes() {
   return calendar_.get(Calendar.MINUTE);
 }
 public void setSeconds(int seconds) {
   calendar_.set(Calendar.SECOND, seconds);
 }
 public int getSeconds() {
   return calendar_.get(Calendar.SECOND);
 }
 public void setMilliSeconds(int milliSeconds) {
   calendar_.set(Calendar.MILLISECOND, milliSeconds);
 }
 public int getMilliSeconds() {
   return calendar_.get(Calendar.MILLISECOND);
 }
 public boolean isAfter(Time time) {
   return calendar_.after(time.calendar_);
 }
 public boolean isBefore(Time time) {
   return calendar_.before(time.calendar_);
 }
 public boolean equals(Time time) {
   return calendar_.equals(time.calendar_);
 }
 public void addHours(int nHours) {
   calendar_.add(Calendar.HOUR_OF_DAY, nHours);
 }
 public void addMinutes(int nMinutes) {
   calendar_.add(Calendar.MINUTE, nMinutes);
 }
 public void addSeconds(int nSeconds) {
   calendar_.add(Calendar.SECOND, nSeconds);
 }
 public void addMilliSeconds(int nMilliSeconds) {
   calendar_.add(Calendar.MILLISECOND, nMilliSeconds);
 }
 public long milliSecondsBetween(Time time) {
   long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
   return millisBetween;
 }
 public double secondsBetween(Time time) {
   long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
   return millisBetween / 1000;
 }
 public double minutesBetween(Time time) {
   long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
   return millisBetween / (1000 * 60);
 }
 public double hoursBetween(Time time) {
   long millisBetween = calendar_.getTime().getTime() - time.calendar_.getTime().getTime();
   return millisBetween / (1000 * 60 * 60);
 }
 public String toString() {
   StringBuffer string = new StringBuffer();
   string.append(super.toString());
   string.append(" ");
   if (getHours() < 10)
     string.append("0");
   string.append(getHours());
   string.append(":");
   if (getMinutes() < 10)
     string.append("0");
   string.append(getMinutes());
   string.append(":");
   if (getSeconds() < 10)
     string.append("0");
   string.append(getSeconds());
   string.append(",");
   string.append(getMilliSeconds());
   return string.toString();
 }
 public static void main(String args[]) {
   Time time = new Time(12, 00, 00);
   System.out.println(time);
 }

} class Day implements Comparable, Cloneable, Serializable {

 protected Calendar calendar_;
 /**
  * Initialize the internal calendar instance.
  * 
  * @param year
  *          Year of new day.
  * @param month
  *          Month of new day.
  * @param dayOfMonth
  *          Day of month of new day.
  */
 private void initialize(int year, int month, int dayOfMonth) {
   calendar_ = Calendar.getInstance();
   calendar_.setLenient(true);
   calendar_.setFirstDayOfWeek(Calendar.MONDAY);
   calendar_.setTimeZone(TimeZone.getTimeZone("GMT"));
   set(year, month, dayOfMonth);
 }
 /**
  * Create a new day. The day is lenient meaning that illegal day parameters
  * can be specified and results in a recomputed day with legal month/day
  * values.
  * 
  * @param year
  *          Year of new day.
  * @param month
  *          Month of new day (0-11)
  * @param dayOfMonth
  *          Day of month of new day (1-31)
  */
 public Day(int year, int month, int dayOfMonth) {
   initialize(year, month, dayOfMonth);
 }
 /**
  * Create a new day, specifying the year and the day of year. The day is
  * lenient meaning that illegal day parameters can be specified and results in
  * a recomputed day with legal month/day values.
  * 
  * @param year
  *          Year of new day.
  * @param dayOfYear
  *          1=January 1, etc.
  */
 public Day(int year, int dayOfYear) {
   initialize(year, Calendar.JANUARY, 1);
   calendar_.set(Calendar.DAY_OF_YEAR, dayOfYear);
 }
 /**
  * Create a new day representing the day of creation (according to the setting
  * of the current machine).
  */
 public Day() {
   // Now (in the currenct locale of the client machine)
   Calendar calendar = Calendar.getInstance();
   // Prune time part
   initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar
       .get(Calendar.DAY_OF_MONTH));
 }
 /**
  * Create a new day based on a java.util.Calendar instance. NOTE: The time
  * component from calendar will be pruned.
  * 
  * @param calendar
  *          Calendar instance to copy.
  */
 public Day(Calendar calendar) {
   this(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar
       .get(Calendar.DAY_OF_MONTH));
 }
 /**
  * Create a new day based on a java.util.Date instance. NOTE: The time
  * component from date will be pruned.
  * 
  * @param date
  *          Date instance to copy.
  */
 public Day(Date date) {
   // Create a calendar based on given date
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   // Extract date values and use these only
   initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar
       .get(Calendar.DAY_OF_MONTH));
 }
 /**
  * Create a new day based on a time value. Time is milliseconds since "the
  * Epoch" (1.1.1970). NOTE: The time component from time will be pruned.
  * 
  * @param time
  *          Milliseconds since "the Epoch".
  */
 public Day(long time) {
   this(new Date(time));
 }
 /**
  * Create a new day as a copy of the specified day.
  * 
  * @param day
  *          Day to clone.
  */
 public Day(Day day) {
   this(day.getYear(), day.getMonth(), day.getDayOfMonth());
 }
 /**
  * Create a clone of this day.
  * 
  * @return This day cloned.
  */
 public Object clone() {
   return new Day(this);
 }
 /**
  * A more explicit front-end to the Day() constructor which return a day
  * object representing the day of creation.
  * 
  * @return A day instance representing today.
  */
 public static Day today() {
   return new Day();
 }
 /**
  * Return a Calendar instance representing the same day as this instance. For
  * use by secondary methods requiring java.util.Calendar as input.
  * 
  * @return Calendar equivalent representing this day.
  */
 public Calendar getCalendar() {
   return (Calendar) calendar_.clone();
 }
 /**
  * Return a Date instance representing the same date as this instance. For use
  * by secondary methods requiring java.util.Date as input.
  * 
  * @return Date equivalent representing this day.
  */
 public Date getDate() {
   return getCalendar().getTime();
 }
 /**
  * Compare this day to the specified day. If object is not of type Day a
  * ClassCastException is thrown.
  * 
  * @param object
  *          Day object to compare to.
  * @return
  * @see Comparable#compareTo(Object)
  * @throws ClassCastException
  *           If object is not of type Day.
  */
 public int compareTo(Object object) {
   Day day = (Day) object;
   return calendar_.getTime().rupareTo(day.calendar_.getTime());
 }
 /**
  * Return true if this day is after the specified day.
  * 
  * @param date
  *          Day to compare to.
  * @return True if this is after day, false otherwise.
  */
 public boolean isAfter(Day day) {
   return calendar_.after(day.calendar_);
 }
 /**
  * Return true if this day is before the specified day.
  * 
  * @param date
  *          Day to compare to.
  * @return True if this is before day, false otherwise.
  */
 public boolean isBefore(Day day) {
   return calendar_.before(day.calendar_);
 }
 /**
  * Return true if this day equals (represent the same date) as the specified
  * day.
  * 
  * @param date
  *          Day to compare to.
  * @return True if this equals day, false otherwise.
  */
 public boolean equals(Day day) {
   return calendar_.equals(day.calendar_);
 }
 /**
  * Overload required as default definition of equals() has changed.
  * 
  * @return A hash code value for this object.
  */
 public int hashCode() {
   return calendar_.hashCode();
 }
 /**
  * Set date of this day. The day is lenient meaning that illegal day
  * parameters can be specified and results in a recomputed day with legal
  * month/day values.
  * 
  * @param year
  *          Year of this day.
  * @param month
  *          Month of this day (0-11).
  * @param dayOfMonth
  *          Day of month of this day (1-31).
  */
 public void set(int year, int month, int dayOfMonth) {
   setYear(year);
   setMonth(month);
   setDayOfMonth(dayOfMonth);
 }
 /**
  * Return year of this day.
  * 
  * @return Year of this day.
  */
 public int getYear() {
   return calendar_.get(Calendar.YEAR);
 }
 /**
  * Set year of this day.
  * 
  * @param year
  *          New year of this day.
  */
 public void setYear(int year) {
   calendar_.set(Calendar.YEAR, year);
 }
 /**
  * Return month of this day. The result must be compared to Calendar.JANUARY,
  * Calendar.FEBRUARY, etc.
  * 
  * @return Month of this day.
  */
 public int getMonth() {
   return calendar_.get(Calendar.MONTH);
 }
 /**
  * Return the 1-based month number of the month of this day. 1 = January, 2 =
  * February and so on.
  * 
  * @return Month number of this month
  */
 public int getMonthNo() {
   // It is tempting to return getMonth() + 1 but this is conceptually
   // wrong, as Calendar month is an enumeration and the values are tags
   // only and can be anything.
   switch (getMonth()) {
   case Calendar.JANUARY:
     return 1;
   case Calendar.FEBRUARY:
     return 2;
   case Calendar.MARCH:
     return 3;
   case Calendar.APRIL:
     return 4;
   case Calendar.MAY:
     return 5;
   case Calendar.JUNE:
     return 6;
   case Calendar.JULY:
     return 7;
   case Calendar.AUGUST:
     return 8;
   case Calendar.SEPTEMBER:
     return 9;
   case Calendar.OCTOBER:
     return 10;
   case Calendar.NOVEMBER:
     return 11;
   case Calendar.DECEMBER:
     return 12;
   }
   // This will never happen
   return 0;
 }
 /**
  * Set month of this day. January = 0, February = 1, etc. Illegal month values
  * will result in a recomputation of year and a resetting of month to a valid
  * value. I.e. setMonth(20), will add 1 year to day and set month to 8.
  * 
  * @param month
  *          New month of this day.
  */
 public void setMonth(int month) {
   calendar_.set(Calendar.MONTH, month);
 }
 /**
  * Return day of month of this day. NOTE: First day of month is 1 (not 0).
  * 
  * @return Day of month of this day.
  */
 public int getDayOfMonth() {
   return calendar_.get(Calendar.DAY_OF_MONTH);
 }
 /**
  * Set day of month of this date. 1=1st 2=2nd, etc. Illegal day values will
  * result in a recomputation of month/year and a resetting of day to a valid
  * value. I.e. setDayOfMonth(33), will add 1 month to date and set day to 5,
  * 4, 3 or 2 depending on month/year.
  * 
  * @param dayOfMonth
  *          New day of month of this day.
  */
 public void setDayOfMonth(int dayOfMonth) {
   calendar_.set(Calendar.DAY_OF_MONTH, dayOfMonth);
 }
 /**
  * Return the day number of year this day represents. January 1 = 1 and so on.
  * 
  * @return day number of year.
  */
 public int getDayOfYear() {
   return calendar_.get(Calendar.DAY_OF_YEAR);
 }
 /**
  * Return the day of week of this day. NOTE: Must be compared to
  * Calendar.MONDAY, TUSEDAY etc.
  * 
  * @return Day of week of this day.
  */
 public int getDayOfWeek() {
   return calendar_.get(Calendar.DAY_OF_WEEK);
 }
 /**
  * Return the day number of week of this day, where Monday=1, Tuesday=2, ...
  * Sunday=7.
  * 
  * @return Day number of week of this day.
  */
 public int getDayNumberOfWeek() {
   return getDayOfWeek() == Calendar.SUNDAY ? 7 : getDayOfWeek() - Calendar.SUNDAY;
 }
 /**
  * Return the week number of year, this day belongs to. 1st=1 and so on.
  * 
  * @return Week number of year of this day.
  */
 public int getWeekOfYear() {
   return calendar_.get(Calendar.WEEK_OF_YEAR);
 }
 /**
  * Add a number of days to this day. Subtracting a number of days can be done
  * by a negative argument to addDays() or calling subtractDays() explicitly.
  * 
  * @param nDays
  *          Number of days to add.
  */
 public void addDays(int nDays) {
   calendar_.add(Calendar.DAY_OF_MONTH, nDays);
 }
 /**
  * Subtract a number of days from this day
  * 
  * @param nDays
  *          Number of days to subtract.
  */
 public void subtractDays(int nDays) {
   addDays(-nDays);
 }
 /**
  * Add a number of months to this day. The actual number of days added depends
  * on the staring day. Subtracting a number of months can be done by a
  * negative argument to addMonths() or calling subtactMonths() explicitly.
  * NOTE: addMonth(n) m times will in general give a different result than
  * addMonth(m*n). Add 1 month to January 31, 2005 will give February 28, 2005.
  * 
  * @param nMonths
  *          Number of months to add.
  */
 public void addMonths(int nMonths) {
   calendar_.add(Calendar.MONTH, nMonths);
 }
 /**
  * Subtract a number of months from this day
  * 
  * @see #addMonths(int).
  * 
  * @param nDays
  *          Number of days to subtract.
  */
 public void subtractMonths(int nMonths) {
   addMonths(-nMonths);
 }
 /**
  * Add a number of years to this day. The actual number of days added depends
  * on the starting day. Subtracting a number of years can be done by a
  * negative argument to addYears() or calling subtractYears explicitly.
  * 
  * @param nYears
  *          Number of years to add.
  */
 public void addYears(int nYears) {
   calendar_.add(Calendar.YEAR, nYears);
 }
 /**
  * Subtract a number of years from this day
  * 
  * @see #addYears(int).
  * 
  * @param nYears
  *          Number of years to subtract.
  */
 public void subtractYears(int nYears) {
   addYears(-nYears);
 }
 /**
  * Return the number of days in the year of this day.
  * 
  * @return Number of days in this year.
  */
 public int getDaysInYear() {
   return calendar_.getActualMaximum(Calendar.DAY_OF_YEAR);
 }
 /**
  * Return true if the year of this day is a leap year.
  * 
  * @return True if this year is a leap year, false otherwise.
  */
 public boolean isLeapYear() {
   return getDaysInYear() == calendar_.getMaximum(Calendar.DAY_OF_YEAR);
 }
 /**
  * Return true if the specified year is a leap year.
  * 
  * @param year
  *          Year to check.
  * @return True if specified year is leap year, false otherwise.
  */
 public static boolean isLeapYear(int year) {
   return (new Day(year, Calendar.JANUARY, 1)).isLeapYear();
 }
 /**
  * Return the number of days in the month of this day.
  * 
  * @return Number of days in this month.
  */
 public int getDaysInMonth() {
   return calendar_.getActualMaximum(Calendar.DAY_OF_MONTH);
 }
 /**
  * Get default locale name of this day ("Monday", "Tuesday", etc.
  * 
  * @return Name of day.
  */
 public String getDayName() {
   switch (getDayOfWeek()) {
   case Calendar.MONDAY:
     return "Monday";
   case Calendar.TUESDAY:
     return "Tuesday";
   case Calendar.WEDNESDAY:
     return "Wednesday";
   case Calendar.THURSDAY:
     return "Thursday";
   case Calendar.FRIDAY:
     return "Friday";
   case Calendar.SATURDAY:
     return "Saturday";
   case Calendar.SUNDAY:
     return "Sunday";
   }
   // This will never happen
   return null;
 }
 /**
  * Return number of days between two days. The method always returns a
  * positive number of days.
  * 
  * @param date
  *          The day to compare to.
  * @return Number of days between this and day.
  */
 public int daysBetween(Day day) {
   long millisBetween = Math
       .abs(calendar_.getTime().getTime() - day.calendar_.getTime().getTime());
   return (int) Math.round(millisBetween / (1000 * 60 * 60 * 24));
 }
 /**
  * Find the n"th xxxxday of s specified month (for instance find 1st sunday of
  * May 2006; findNthOfMonth (1, Calendar.SUNDAY, Calendar.MAY, 2006); Return
  * null if the specified day doesn"t exists.
  * 
  * @param n
  *          Nth day to look for.
  * @param dayOfWeek
  *          Day to look for (Calendar.XXXDAY).
  * @param month
  *          Month to check (Calendar.XXX).
  * @param year
  *          Year to check.
  * @return Required Day (or null if non-existent)
  * @throws ArrayIndexOutOfBoundsException
  *           if dyaOfWeek parameter doesn"t represent a valid day.
  */
 public static Day getNthOfMonth(int n, int dayOfWeek, int month, int year)
     throws ArrayIndexOutOfBoundsException {
   // Validate the dayOfWeek argument
   if (dayOfWeek < 0 || dayOfWeek > 6)
     throw new ArrayIndexOutOfBoundsException(dayOfWeek);
   Day first = new Day(year, month, 1);
   int offset = dayOfWeek - first.getDayOfWeek();
   if (offset < 0)
     offset = 7 + offset;
   int dayNo = (n - 1) * 7 + offset + 1;
   return dayNo > first.getDaysInMonth() ? null : new Day(year, month, dayNo);
 }
 /**
  * Find the first of a specific day in a given month, for instance first
  * Tuesday of May: getFirstOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
  * 
  * @param dayOfWeek
  *          Weekday to get.
  * @param month
  *          Month of day to get.
  * @param year
  *          Year of day to get.
  * @return The requested day.
  */
 public static Day getFirstOfMonth(int dayOfWeek, int month, int year) {
   return Day.getNthOfMonth(1, dayOfWeek, month, year);
 }
 /**
  * Find the last of a specific day in a given month, for instance last Tuesday
  * of May: getLastOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
  * 
  * @param dayOfWeek
  *          Weekday to get.
  * @param month
  *          Month of day to get.
  * @param year
  *          Year of day to get.
  * @return The requested day.
  */
 public static Day getLastOfMonth(int dayOfWeek, int month, int year) {
   Day day = Day.getNthOfMonth(5, dayOfWeek, month, year);
   return day != null ? day : Day.getNthOfMonth(4, dayOfWeek, month, year);
 }
 /**
  * Return a scratch string representation of this day. Used for debugging
  * only. The format of the day is dd/mm-yyyy
  * 
  * @return A string representation of this day.
  */
 public String toString() {
   StringBuffer string = new StringBuffer();
   if (getDayOfMonth() < 10)
     string.append("0");
   string.append(getDayOfMonth());
   string.append("/");
   if (getMonth() < 9)
     string.append("0");
   string.append(getMonth() + 1);
   string.append("-");
   string.append(getYear());
   string.append(" ");
   string.append(getDayName());
   return string.toString();
 }
 /**
  * Testing this class.
  * 
  * @param args
  *          Not used.
  */
 public static void main(String[] args) {
   // This proves that there are 912 days between the two major
   // terrorist attacks, not 911 as is common knowledge.
   Day september11 = new Day(2001, Calendar.SEPTEMBER, 11);
   Day march11 = new Day(2004, Calendar.MARCH, 11);
   System.out.println(september11.daysBetween(march11));
   // This proves that Kennedy was president for 1037 days,
   // not 1000 as is the popular belief nor 1036 which is the
   // bluffers reply. Nerds knows when to add one...
   Day precidency = new Day(1961, Calendar.JANUARY, 20);
   Day assasination = new Day(1963, Calendar.NOVEMBER, 22);
   System.out.println(precidency.daysBetween(assasination) + 1);
   // Niel Armstrong walked the moon on a Sunday
   Day nielOnMoon = new Day(1969, Calendar.JULY, 20);
   System.out.println(nielOnMoon.getDayNumberOfWeek());
   // Find last tuesdays for 2005
   for (int i = 0; i < 12; i++) {
     Day tuesday = Day.getLastOfMonth(Calendar.TUESDAY, i, 2005);
     System.out.println(tuesday);
   }
 }

}


      </source>
   
  
 
  



A time-less Date class for basic date arithmetics

   <source lang="java">

/*

* (C) 2004 - Geotechnical Software Services
* 
* This code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public 
* License as published by the Free Software Foundation; either 
* version 2.1 of the License, or (at your option) any later version.
*
* This code 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public 
* License along with this program; if not, write to the Free 
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
* MA  02111-1307, USA.
*/

//package no.geosoft.cc.util;

import java.util.Date; import java.util.Calendar; import java.util.TimeZone; import java.io.Serializable;

/**

* A time-less Date class for basic date arithmetics.
*
* Thanks to Paul Hill @ xmission.ru for valuable contribution.
*
* @author  Jacob Dreyer ()
*/   

public class Day

 implements Comparable, Cloneable, Serializable

{

 protected Calendar  calendar_;
   
 /**
  * Initialize the internal calendar instance.
  * 
  * @param year        Year of new day.
  * @param month       Month of new day.
  * @param dayOfMonth  Day of month of new day.
  */
 private void initialize (int year, int month, int dayOfMonth)
 {
   calendar_ = Calendar.getInstance();
   calendar_.setLenient (true);
   calendar_.setFirstDayOfWeek (Calendar.MONDAY);
   calendar_.setTimeZone (TimeZone.getTimeZone ("GMT"));
   set (year, month, dayOfMonth);
 }
   
   
 /**
  * Create a new day.
  * The day is lenient meaning that illegal day parameters can be
  * specified and results in a recomputed day with legal month/day
  * values.
  *
  * @param year        Year of new day.
  * @param month       Month of new day (0-11)
  * @param dayOfMonth  Day of month of new day (1-31)
  */
 public Day (int year, int month, int dayOfMonth)
 {
   initialize (year, month, dayOfMonth);
 }
 /**
  * Create a new day, specifying the year and the day of year.
  * The day is lenient meaning that illegal day parameters can be
  * specified and results in a recomputed day with legal month/day
  * values.
  * 
  * @param year       Year of new day.
  * @param dayOfYear  1=January 1, etc.
  */
 public Day (int year, int dayOfYear)
 {
   initialize (year, Calendar.JANUARY, 1);
   calendar_.set (Calendar.DAY_OF_YEAR, dayOfYear);
 }
   
   
 /**
  * Create a new day representing the day of creation
  * (according to the setting of the current machine).
  */
 public Day()
 {
   // Now (in the currenct locale of the client machine)
   Calendar calendar = Calendar.getInstance();
   // Prune time part
   initialize (calendar.get (Calendar.YEAR),
               calendar.get (Calendar.MONTH),
               calendar.get (Calendar.DAY_OF_MONTH));
 }
   
 /**
  * Create a new day based on a java.util.Calendar instance.
  * NOTE: The time component from calendar will be pruned.
  * 
  * @param calendar  Calendar instance to copy.
  */
 public Day (Calendar calendar)
 {
   this (calendar.get (Calendar.YEAR),
         calendar.get (Calendar.MONTH),
         calendar.get (Calendar.DAY_OF_MONTH));
 }
   
   
 /**
  * Create a new day based on a java.util.Date instance.
  * NOTE: The time component from date will be pruned.     
  * 
  * @param date  Date instance to copy.
  */
 public Day (Date date)
 {
   // Create a calendar based on given date
   Calendar calendar = Calendar.getInstance();
   calendar.setTime (date);
   // Extract date values and use these only
   initialize (calendar.get (Calendar.YEAR),
               calendar.get (Calendar.MONTH),
               calendar.get (Calendar.DAY_OF_MONTH));
 }
 /**
  * Create a new day based on a time value.
  * Time is milliseconds since "the Epoch" (1.1.1970).
  * NOTE: The time component from time will be pruned.     
  * 
  * @param time  Milliseconds since "the Epoch".
  */
 public Day (long time)
 {
   this (new Date (time));
 }
   
 /**
  * Create a new day as a copy of the specified day.
  * 
  * @param day  Day to clone.
  */
 public Day (Day day)
 {
   this (day.getYear(), day.getMonth(), day.getDayOfMonth());
 }


 /**
  * Create a clone of this day.
  * 
  * @return  This day cloned.
  */
 public Object clone()
 {
   return new Day (this);
 }
 /**
  * A more explicit front-end to the Day() constructor which return a day
  * object representing the day of creation.
  * 
  * @return  A day instance representing today.
  */
 public static Day today()
 {
   return new Day();
 }
       
 /**
  * Return a Calendar instance representing the same day
  * as this instance. For use by secondary methods requiring
  * java.util.Calendar as input.
  * 
  * @return  Calendar equivalent representing this day.
  */
 public Calendar getCalendar()
 {
   return (Calendar) calendar_.clone();
 }


 /**
  * Return a Date instance representing the same date
  * as this instance. For use by secondary methods requiring
  * java.util.Date as input.
  * 
  * @return  Date equivalent representing this day.
  */
 public Date getDate()
 {
   return getCalendar().getTime();
 }
   
   
 /**
  * Compare this day to the specified day. If object is
  * not of type Day a ClassCastException is thrown.
  * 
  * @param object  Day object to compare to.
  * @return        @see Comparable#compareTo(Object)
  * @throws ClassCastException  If object is not of type Day.
  */
 public int compareTo (Object object)
 {
   Day day = (Day) object;
   return calendar_.getTime().rupareTo (day.calendar_.getTime());
 }
   
 /**
  * Return true if this day is after the specified day.
  * 
  * @param date  Day to compare to.
  * @return      True if this is after day, false otherwise.
  */
 public boolean isAfter (Day day)
 {
   return calendar_.after (day.calendar_);
 }
   
 /**
  * Return true if this day is before the specified day.
  * 
  * @param date  Day to compare to.
  * @return      True if this is before day, false otherwise.
  */
 public boolean isBefore (Day day)
 {
   return calendar_.before (day.calendar_);
 }
 /**
  * Return true if this day equals (represent the same date)
  * as the specified day.
  * 
  * @param date  Day to compare to.
  * @return      True if this equals day, false otherwise.
  */
 public boolean equals (Day day)
 {
   return calendar_.equals (day.calendar_);
 }
 /**
  * Overload required as default definition of equals() has changed.
  * 
  * @return  A hash code value for this object.
  */
 public int hashCode()
 {
   return calendar_.hashCode();
 }
 
 
 /**
  * Set date of this day.
  * The day is lenient meaning that illegal day parameters can be
  * specified and results in a recomputed day with legal month/day
  * values.
  * 
  * @param year        Year of this day.
  * @param month       Month of this day (0-11).
  * @param dayOfMonth  Day of month of this day (1-31).
  */
 public void set (int year, int month, int dayOfMonth)
 {
   setYear (year);
   setMonth (month);
   setDayOfMonth (dayOfMonth);
 }
   
   
   
 /**
  * Return year of this day.
  * 
  * @return  Year of this day.
  */
 public int getYear()
 {
   return calendar_.get (Calendar.YEAR);
 }
 /**
  * Set year of this day.
  * 
  * @param year  New year of this day.
  */
 public void setYear (int year)
 {
   calendar_.set (Calendar.YEAR, year);
 }
 /**
  * Return month of this day. The result must be compared to Calendar.JANUARY,
  * Calendar.FEBRUARY, etc.
  * 
  * @return  Month of this day.
  */
 public int getMonth()
 {
   return calendar_.get (Calendar.MONTH);
 }


 /**
  * Return the 1-based month number of the month of this day.
  * 1 = January, 2 = February and so on.
  * 
  * @return Month number of this month
  */
 public int getMonthNo()
 {
   // It is tempting to return getMonth() + 1 but this is conceptually
   // wrong, as Calendar month is an enumeration and the values are tags
   // only and can be anything.
   switch (getMonth()) {
     case Calendar.JANUARY   : return 1;
     case Calendar.FEBRUARY  : return 2;
     case Calendar.MARCH     : return 3;                
     case Calendar.APRIL     : return 4;
     case Calendar.MAY       : return 5;                
     case Calendar.JUNE      : return 6;
     case Calendar.JULY      : return 7;                
     case Calendar.AUGUST    : return 8;
     case Calendar.SEPTEMBER : return 9;                
     case Calendar.OCTOBER   : return 10;
     case Calendar.NOVEMBER  : return 11;                
     case Calendar.DECEMBER  : return 12;
   }
   // This will never happen
   return 0;
 }
 
   
 /**
  * Set month of this day. January = 0, February = 1, etc.
  * Illegal month values will result in a recomputation of
  * year and a resetting of month to a valid value.
  * I.e. setMonth(20), will add 1 year to day and set month
  * to 8.
  * 
  * @param month  New month of this day.
  */
 public void setMonth (int month)
 {
   calendar_.set (Calendar.MONTH, month);
 }
 /**
  * Return day of month of this day.
  * NOTE: First day of month is 1 (not 0).
  * 
  * @return  Day of month of this day.
  */
 public int getDayOfMonth()
 {
   return calendar_.get (Calendar.DAY_OF_MONTH);
 }


 /**
  * Set day of month of this date. 1=1st  2=2nd, etc.
  * Illegal day values will result in a recomputation of
  * month/year and a resetting of day to a valid value.
  * I.e. setDayOfMonth(33), will add 1 month to date and
  * set day to 5, 4, 3 or 2 depending on month/year.
  * 
  * @param dayOfMonth  New day of month of this day.
  */
 public void setDayOfMonth (int dayOfMonth)
 {
   calendar_.set (Calendar.DAY_OF_MONTH, dayOfMonth);
 }


 /**
  * Return the day number of year this day represents.
  * January 1 = 1 and so on.
  * 
  * @return day number of year.
  */
 public int getDayOfYear()
 {
   return calendar_.get (Calendar.DAY_OF_YEAR);
 }
 /**
  * Return the day of week of this day.
  * NOTE: Must be compared to Calendar.MONDAY, TUSEDAY etc.
  * 
  * @return  Day of week of this day.
  */
 public int getDayOfWeek()
 {
   return calendar_.get (Calendar.DAY_OF_WEEK);
 }
   
   
 /**
  * Return the day number of week of this day, where
  * Monday=1, Tuesday=2, ... Sunday=7.
  * 
  * @return  Day number of week of this day.
  */
 public int getDayNumberOfWeek()
 {
   return getDayOfWeek() == Calendar.SUNDAY ?
                          7 : getDayOfWeek() - Calendar.SUNDAY;
 }
   
   
 /**
  * Return the week number of year, this day
  * belongs to. 1st=1 and so on.
  * 
  * @return  Week number of year of this day.
  */
 public int getWeekOfYear()
 {
   return calendar_.get (Calendar.WEEK_OF_YEAR);
 }
   
   
 /**
  * Add a number of days to this day. Subtracting a number of
  * days can be done by a negative argument to addDays() or calling
  * subtractDays() explicitly.
  * 
  * @param nDays  Number of days to add.
  */
 public void addDays (int nDays)
 {
   calendar_.add (Calendar.DAY_OF_MONTH, nDays);
 }
 
 /**
  * Subtract a number of days from this day
  * 
  * @param nDays  Number of days to subtract.
  */
 public void subtractDays (int nDays)
 {
   addDays (-nDays);
 }
 
   
 /**
  * Add a number of months to this day. The actual number of days added
  * depends on the staring day. Subtracting a number of months can be done
  * by a negative argument to addMonths() or calling subtactMonths()
  * explicitly.
  * NOTE: addMonth(n) m times will in general give a different result
  * than addMonth(m*n). Add 1 month to January 31, 2005 will give
  * February 28, 2005.
  * 
  * @param nMonths  Number of months to add.
  */
 public void addMonths (int nMonths)
 {
   calendar_.add (Calendar.MONTH, nMonths);
 }
   
   
 /**
  * Subtract a number of months from this day
  * @see #addMonths(int).
  * 
  * @param nDays  Number of days to subtract.
  */
 public void subtractMonths (int nMonths)
 {
   addMonths (-nMonths);
 }
 
   
 /**
  * Add a number of years to this day. The actual 
  * number of days added depends on the starting day.
  * Subtracting a number of years can be done by a negative argument to
  * addYears() or calling subtractYears explicitly.
  * 
  * @param nYears  Number of years to add.
  */
 public void addYears (int nYears)
 {
   calendar_.add (Calendar.YEAR, nYears);
 }
   
 /**
  * Subtract a number of years from this day
  * @see #addYears(int).
  * 
  * @param nYears  Number of years to subtract.
  */
 public void subtractYears (int nYears)
 {
   addYears (-nYears);
 }
 
   
 /**
  * Return the number of days in the year of this day.
  * 
  * @return  Number of days in this year.
  */
 public int getDaysInYear()
 {
   return calendar_.getActualMaximum (Calendar.DAY_OF_YEAR);
 }
 /**
  * Return true if the year of this day is a leap year.
  * 
  * @return  True if this year is a leap year, false otherwise.
  */
 public boolean isLeapYear()
 {
   return getDaysInYear() == calendar_.getMaximum (Calendar.DAY_OF_YEAR);
 }
 /**
  * Return true if the specified year is a leap year.
  * 
  * @param year  Year to check.
  * @return      True if specified year is leap year, false otherwise.
  */
 public static boolean isLeapYear (int year)
 {
   return (new Day (year, Calendar.JANUARY, 1)).isLeapYear();
 }
 
 
 /**
  * Return the number of days in the month of this day.
  * 
  * @return  Number of days in this month.
  */
 public int getDaysInMonth()
 {
   return calendar_.getActualMaximum (Calendar.DAY_OF_MONTH);
 }
 
 /**
  * Get default locale name of this day ("Monday", "Tuesday", etc.
  * 
  * @return  Name of day.
  */
 public String getDayName()
 {
   switch (getDayOfWeek()) {
     case Calendar.MONDAY    : return "Monday";
     case Calendar.TUESDAY   : return "Tuesday";        
     case Calendar.WEDNESDAY : return "Wednesday";
     case Calendar.THURSDAY  : return "Thursday";        
     case Calendar.FRIDAY    : return "Friday";
     case Calendar.SATURDAY  : return "Saturday";        
     case Calendar.SUNDAY    : return "Sunday";
   }
   // This will never happen
   return null;
 }
 
 
   
 /**
  * Return number of days between two days.
  * The method always returns a positive number of days.
  *
  * @param date  The day to compare to.
  * @return      Number of days between this and day.
  */
 public int daysBetween (Day day)
 {
   long millisBetween = Math.abs (calendar_.getTime().getTime() -
                                  day.calendar_.getTime().getTime());
   return (int) Math.round (millisBetween / (1000 * 60 * 60 * 24));
 }
 /**
  * Find the n"th xxxxday of s specified month (for instance find 1st sunday
  * of May 2006; findNthOfMonth (1, Calendar.SUNDAY, Calendar.MAY, 2006);
  * Return null if the specified day doesn"t exists.
  * 
  * @param n          Nth day to look for.
  * @param dayOfWeek  Day to look for (Calendar.XXXDAY).
  * @param month      Month to check (Calendar.XXX).
  * @param year       Year to check.
  * @return           Required Day (or null if non-existent)
  * @throws           ArrayIndexOutOfBoundsException if dyaOfWeek parameter
  *                   doesn"t represent a valid day.
  */
 public static Day getNthOfMonth (int n, int dayOfWeek, int month, int year)
   throws ArrayIndexOutOfBoundsException
 {
   // Validate the dayOfWeek argument
   if (dayOfWeek < 0 || dayOfWeek > 6)
     throw new ArrayIndexOutOfBoundsException (dayOfWeek);
   
   Day first = new Day (year, month, 1);
   
   int offset = dayOfWeek - first.getDayOfWeek();
   if (offset < 0) offset = 7 + offset;
   
   int dayNo = (n - 1) * 7 + offset + 1;
   
   return dayNo > first.getDaysInMonth() ? null : new Day (year, month, dayNo);
 }


 /**
  * Find the first of a specific day in a given month, for instance
  * first Tuesday of May:
  * getFirstOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
  * 
  * @param dayOfWeek  Weekday to get.
  * @param month      Month of day to get.
  * @param year       Year of day to get.
  * @return           The requested day.
  */
 public static Day getFirstOfMonth (int dayOfWeek, int month, int year)
 {
   return Day.getNthOfMonth (1, dayOfWeek, month, year);
 }
 
 
 /**
  * Find the last of a specific day in a given month, for instance
  * last Tuesday of May:
  * getLastOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
  * 
  * @param dayOfWeek  Weekday to get.
  * @param month      Month of day to get.
  * @param year       Year of day to get.
  * @return           The requested day.
  */
 public static Day getLastOfMonth (int dayOfWeek, int month, int year)
 {
   Day day = Day.getNthOfMonth (5, dayOfWeek, month, year);
   return day != null ? day : Day.getNthOfMonth (4, dayOfWeek, month, year);
 }
 
 /**
  * Return a scratch string representation of this day.
  * Used for debugging only. The format of the
  * day is dd/mm-yyyy
  * 
  * @return  A string representation of this day.
  */
 public String toString()
 {
   StringBuffer string = new StringBuffer();        
   if (getDayOfMonth() < 10) string.append ("0");
   string.append (getDayOfMonth());
   string.append ("/");
   if (getMonth() < 9) string.append ("0");
   string.append (getMonth()+1);
   string.append ("-");
   string.append (getYear());
   string.append (" ");
   string.append (getDayName());        
   return string.toString();
 }


 /**
  * Testing this class.
  * 
  * @param args  Not used.
  */
 public static void main (String[] args)
 {
   // This proves that there are 912 days between the two major
   // terrorist attacks, not 911 as is common knowledge.
   Day september11 = new Day (2001, Calendar.SEPTEMBER, 11);
   Day march11     = new Day (2004, Calendar.MARCH,     11);
   System.out.println (september11.daysBetween (march11));
   // This proves that Kennedy was president for 1037 days,
   // not 1000 as is the popular belief nor 1036 which is the
   // bluffers reply. Nerds knows when to add one...
   Day precidency   = new Day (1961, Calendar.JANUARY,  20);
   Day assasination = new Day (1963, Calendar.NOVEMBER, 22);
   System.out.println (precidency.daysBetween (assasination) + 1);
   // Niel Armstrong walked the moon on a Sunday
   Day nielOnMoon = new Day (1969, Calendar.JULY, 20);
   System.out.println (nielOnMoon.getDayNumberOfWeek());
   // Find last tuesdays for 2005
   for (int i = 0; i < 12; i++) {
     Day tuesday = Day.getLastOfMonth (Calendar.TUESDAY, i, 2005);
     System.out.println (tuesday);
   }
 }

}


      </source>