001 package org.hackystat.utilities.time.period; 002 003 import java.text.SimpleDateFormat; 004 import java.util.ArrayList; 005 import java.util.Calendar; 006 import java.util.Date; 007 import java.util.List; 008 import java.util.Locale; 009 010 import javax.xml.datatype.XMLGregorianCalendar; 011 012 /** 013 * Provides a representation for seven Day instances where the first Day 014 * is always a Sunday and the last Day is always the following Saturday. 015 * <p> 016 * The Calendar is forced to Locale.US to ensure constant week boundaries. 017 * 018 * @author Hongbing Kou 019 */ 020 public class Week implements TimePeriod { 021 /** First day of the week. */ 022 private Day firstDay; 023 /** Last day of the week. */ 024 private Day lastDay; 025 /** A list of days in this week. */ 026 private List<Day> days; 027 028 /** 029 * Create a Week instance that starts on Sunday and ends on Saturday and that includes today. 030 */ 031 public Week() { 032 this(Day.getInstance(new Date())); 033 } 034 035 /** 036 * Create a Week instance that includes the passed date. 037 * @param date The date to be included in the constructed Week. 038 */ 039 public Week (Date date) { 040 this(Day.getInstance(date)); 041 } 042 043 /** 044 * Creates a Week instance that starts on Sunday and ends on Saturday and that includes the 045 * passed day. 046 * @param day A day that identifies the Week to be returned. 047 */ 048 public Week(Day day) { 049 Calendar cal = Calendar.getInstance(Locale.US); 050 cal.setTime(day.getDate()); 051 cal.set(Calendar.DAY_OF_WEEK, 1); 052 053 this.firstDay = Day.getInstance(cal.getTime()); 054 cal.set(Calendar.DAY_OF_WEEK, 7); 055 this.lastDay = Day.getInstance(cal.getTime()); 056 057 // Create days' list. 058 this.days = new ArrayList<Day>(); 059 for (Day weekDay = this.firstDay; weekDay.compareTo(this.lastDay) <= 0; 060 weekDay = weekDay.inc(1)) { 061 this.days.add(weekDay); 062 } 063 } 064 065 /** 066 * Creates a week instance starting on Sunday and ending on Saturday that includes the passed 067 * Day. 068 * @param xmlDay The day. 069 */ 070 public Week(XMLGregorianCalendar xmlDay) { 071 this(Day.getInstance(xmlDay)); 072 } 073 074 /** 075 * Gets first day of this Week, always a Sunday. 076 * 077 * @return First day of the week. 078 */ 079 public Day getFirstDay() { 080 return this.firstDay; 081 } 082 083 /** 084 * Gets the last day of this Week, always a Saturday. 085 * 086 * @return Last day of the week. 087 */ 088 public Day getLastDay() { 089 return this.lastDay; 090 } 091 092 /** 093 * Returns a list with the seven Day instances in this Week. 094 * 095 * @return A list of the Days in this Week. 096 */ 097 public List<Day> getDays() { 098 return this.days; 099 } 100 101 /** 102 * Calculate the hashcode for this Week. 103 * 104 * @return This Week's hashcode. 105 */ 106 @Override 107 public int hashCode() { 108 return this.firstDay.hashCode(); 109 } 110 111 /** 112 * Returns true if the passed object is a Week and is equal to this Week. 113 * 114 * @param obj Any object. 115 * @return True if the two Week instances are the same. 116 */ 117 @Override 118 public boolean equals(Object obj) { 119 return ((obj instanceof Week) && 120 (this.firstDay.equals(((Week) obj).firstDay))); 121 } 122 123 /** 124 * Returns a String representation of this Week. 125 * 126 * @return First day of the week. 127 */ 128 public String getWeekRepresentation() { 129 SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy", Locale.US); 130 return formatter.format(this.firstDay.getDate()) + " to " + 131 formatter.format(this.lastDay.getDate()); 132 } 133 134 /** 135 * First day of the week is chosen to represent the week in toString(). 136 * 137 * @return Week string. 138 */ 139 @Override 140 public String toString() { 141 return (new SimpleDateFormat("dd-MMM-yyyy", Locale.US)).format(this.lastDay.getDate()); 142 } 143 144 /** 145 * Returns a new Week instance representing the previous Week. 146 * 147 * @return The previous Week. 148 */ 149 public Week dec() { 150 return new Week(this.firstDay.inc(-7)); 151 } 152 153 /** 154 * Returns a new Week instance representing the next Week. 155 * 156 * @return The next Week. 157 */ 158 public Week inc() { 159 return new Week(this.lastDay.inc(7)); 160 } 161 162 /** 163 * Compares two Week objects. 164 * 165 * @param obj Another week object. 166 * @return Comparison of the first day. 167 */ 168 public int compareTo(Object obj) { 169 if (!(obj instanceof Week)) { 170 return -1; 171 } 172 return this.firstDay.compareTo(((Week) obj).firstDay); 173 } 174 }