001 /** 002 * Copyright 2010 The Kuali Foundation Licensed under the 003 * Educational Community License, Version 2.0 (the "License"); you may 004 * not use this file except in compliance with the License. You may 005 * obtain a copy of the License at 006 * 007 * http://www.osedu.org/licenses/ECL-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, 010 * software distributed under the License is distributed on an "AS IS" 011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 012 * or implied. See the License for the specific language governing 013 * permissions and limitations under the License. 014 */ 015 016 package org.kuali.student.lum.common.client.widgets; 017 018 import java.util.Date; 019 020 /** 021 * <dl> 022 * <dt><b>Title: </b><dd>GregorianCalendar</dd> 023 * <p> 024 * <dt><b>Description: </b><dd>java.util.GregorianCalendar replacment</dd> 025 * </dl> 026 * @author <a href="mailto:andre.freller@gmail.com">Andre Freller</a> 027 * @version $Revision: 0.1 $ 028 */ 029 ///////// ///////// ///////// ///////// ///////// ///////// ///////// ///////// ///////// ///////// ///////// ///////// 030 public class GregorianCalendar extends Calendar 031 { 032 public static final int BC = 0; 033 public static final int AD = 1; 034 035 public GregorianCalendar() { 036 super(); 037 } 038 public GregorianCalendar(Date date) { 039 setTime(date); 040 } 041 public GregorianCalendar(int year, int month, int date) { 042 set(year, month, date); 043 } 044 public GregorianCalendar(int year, int month, int date, int hour) { 045 set(year, month, date, hour); 046 } 047 public GregorianCalendar(int year, int month, int date, int hour, int minute) { 048 set(year, month, date, hour, minute); 049 } 050 public GregorianCalendar(int year, int month, int date, int hour, int minute, int second) { 051 set(year, month, date, hour, minute, second); 052 } 053 054 protected static int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31 ,30, 31, 30, 31}; 055 public static int getMaxDaysInMonth(int year, int month) { 056 if (month == Calendar.FEBRUARY && isLeapYear(year)) 057 return daysInMonth[month] + 1; 058 else 059 return daysInMonth[month]; 060 } 061 public int getMaxDaysInMonth() { 062 return getMaxDaysInMonth(this.year, this.month); 063 } 064 065 public static int getNumOfWeeksInMonth(int year, int month, int firstDayOfWeek) { 066 int day1 = getWeekDay(year, month, 1); 067 int maxDays = getMaxDaysInMonth(year, month); 068 if (month == Calendar.FEBRUARY && !isLeapYear(year) && day1 == firstDayOfWeek) 069 return 4; 070 if (maxDays == 30 && (day1 > firstDayOfWeek + 5 || day1 < firstDayOfWeek)) 071 return 6; 072 if (maxDays == 31 && (day1 > firstDayOfWeek + 4 || day1 < firstDayOfWeek)) 073 return 6; 074 return 5; 075 } 076 public int getNumOfWeeksInMonth() { 077 return getNumOfWeeksInMonth(this.year, this.month, this.firstWeekDayOfWeek); 078 } 079 080 public static int getWeekDay(int year, int month, int dayOfMonth) { 081 int weekDay = year - 1900; 082 weekDay += weekDay/4; 083 weekDay %= 7; 084 if (month <= Calendar.FEBRUARY && isLeapYear(weekDay)) 085 weekDay -= 1; 086 weekDay += dayOfMonth; 087 weekDay %= 7; 088 if (month == Calendar.MAY) 089 weekDay += 1; 090 else if (month == Calendar.AUGUST) 091 weekDay += 2; 092 else if (month == Calendar.FEBRUARY || month == Calendar.MARCH || month == Calendar.NOVEMBER) 093 weekDay += 3; 094 else if (month == Calendar.JUNE) 095 weekDay += 4; 096 else if (month == Calendar.SEPTEMBER || month == Calendar.DECEMBER) 097 weekDay += 5; 098 else if (month == Calendar.APRIL || month == Calendar.JULY) 099 weekDay += 6; 100 weekDay %= 7; 101 102 return Calendar.SUNDAY + weekDay; 103 } 104 public int getWeekDay() { 105 return getWeekDay(this.year, this.month, this.dayOfMonth); 106 } 107 public int getFirstWeekDayOfMonth() { 108 return getWeekDay(this.year, this.month, 1); 109 } 110 111 // Gets the minimum value for the given time field. 112 public int getMinimum(int fieldCode) { 113 switch (fieldCode) { 114 case Calendar.MILLISECOND: 115 return 0; 116 case Calendar.SECOND: 117 return 0; 118 case Calendar.MINUTE: 119 return 0; 120 case Calendar.HOUR: 121 return 0; 122 case Calendar.HOUR_OF_DAY: 123 return 0; 124 case Calendar.DATE: 125 return 1; 126 case Calendar.MONTH: 127 return Calendar.JANUARY; 128 default: 129 return -1; 130 } 131 } 132 // Return the minimum value that this field could have, given the current date. 133 public int getActualMinimum(int fieldCode) { 134 return getMinimum(fieldCode); 135 } 136 // Gets the highest minimum value for the given field if varies. 137 public int getGreatestMinimum(int fieldCode) { 138 return getMinimum(fieldCode); 139 } 140 141 // Gets the maximum value for the given time field. 142 public int getMaximum(int fieldCode) { 143 switch (fieldCode) { 144 case Calendar.MILLISECOND: 145 return 999; 146 case Calendar.SECOND: 147 return 59; 148 case Calendar.MINUTE: 149 return 59; 150 case Calendar.HOUR: 151 return 11; 152 case Calendar.HOUR_OF_DAY: 153 return 23; 154 case Calendar.DATE: 155 return 31; 156 case Calendar.MONTH: 157 return Calendar.DECEMBER; 158 default: 159 return -1; 160 } 161 } 162 // Return the maximum value that this field could have, given the current date. 163 public int getActualMaximum(int fieldCode) { 164 switch (fieldCode) { 165 case Calendar.MILLISECOND: 166 return 999; 167 case Calendar.SECOND: 168 return 59; 169 case Calendar.MINUTE: 170 return 59; 171 case Calendar.HOUR: 172 return 11; 173 case Calendar.HOUR_OF_DAY: 174 return 23; 175 case Calendar.DATE: 176 return getMaxDaysInMonth(); 177 case Calendar.MONTH: 178 return Calendar.DECEMBER; 179 default: 180 return -1; 181 } 182 } 183 // Gets the lowest maximum value for the given field if varies. 184 public int getLeastMaximum(int fieldCode) { 185 switch (fieldCode) { 186 case Calendar.MILLISECOND: 187 return 999; 188 case Calendar.SECOND: 189 return 59; 190 case Calendar.MINUTE: 191 return 59; 192 case Calendar.HOUR: 193 return 11; 194 case Calendar.HOUR_OF_DAY: 195 return 23; 196 case Calendar.DATE: 197 return 28; 198 case Calendar.MONTH: 199 return Calendar.DECEMBER; 200 default: 201 return -1; 202 } 203 } 204 205 206 public void set(int fieldCode, int value) { 207 switch (fieldCode) { 208 case Calendar.SECOND: 209 this.second = value; 210 break; 211 case Calendar.MINUTE: 212 this.minute = value; 213 break; 214 case Calendar.HOUR: 215 this.hour = value; 216 break; 217 case Calendar.HOUR_OF_DAY: 218 if (value <= 12) { 219 this.hour = value; 220 this.amPm = Calendar.AM; 221 } else { 222 this.hour = value - 12; 223 this.amPm = Calendar.PM; 224 } 225 break; 226 case Calendar.DATE: 227 this.dayOfMonth = value; 228 break; 229 case Calendar.MONTH: 230 this.month = value; 231 if (this.dayOfMonth > getMaxDaysInMonth()) 232 this.dayOfMonth = getMaxDaysInMonth(); 233 break; 234 case Calendar.YEAR: 235 this.year = value; 236 break; 237 case Calendar.AM_PM: 238 this.amPm = value; 239 break; 240 } 241 computeTime(); 242 } 243 244 245 // Date Arithmetic function. 246 public void add(int fieldCode, int amount) { 247 switch (fieldCode) { 248 case Calendar.DATE: 249 amount *= 24; 250 case Calendar.HOUR: 251 amount *= 60; 252 case Calendar.MINUTE: 253 amount *= 60; 254 case Calendar.SECOND: 255 amount *= 1000; 256 case Calendar.MILLISECOND: 257 this.date.setTime(this.date.getTime() + amount); 258 computeFields(); 259 break; 260 case Calendar.MONTH: 261 this.year += (this.month + amount) / 12; 262 this.month = (this.month + amount) % 12; 263 if (this.month < 0) { 264 this.year -= 1; 265 this.month += 12; 266 } 267 if (this.dayOfMonth > getMaxDaysInMonth()) 268 this.dayOfMonth = getMaxDaysInMonth(); 269 computeTime(); 270 break; 271 case Calendar.YEAR: 272 this.year += amount; 273 computeTime(); 274 break; 275 } 276 } 277 278 // Time Field Rolling function. 279 public void roll(int fieldCode, int amount) { 280 switch (fieldCode) { 281 case Calendar.SECOND: 282 this.second = (this.second + amount) % 60; 283 if (this.second < 0) 284 this.second += 60; 285 break; 286 case Calendar.MINUTE: 287 this.minute = (this.minute + amount) % 60; 288 if (this.minute < 0) 289 this.minute += 60; 290 break; 291 case Calendar.HOUR: 292 this.hour = (this.hour + amount) % 24; 293 if (this.hour < 0) 294 this.hour += 24; 295 break; 296 case Calendar.DATE: { 297 this.dayOfMonth = (this.dayOfMonth + amount) % getActualMaximum(Calendar.DATE); 298 if (this.dayOfMonth < 0) 299 this.dayOfMonth += getActualMaximum(Calendar.DATE); 300 break; 301 } 302 case Calendar.MONTH: { 303 this.month = (this.month + amount) % 12; 304 if (this.month < 0) 305 this.month += 12; 306 if (this.dayOfMonth > getActualMaximum(Calendar.DATE)) 307 this.dayOfMonth = getActualMaximum(Calendar.DATE); 308 break; 309 } 310 case Calendar.YEAR: 311 this.year += amount; 312 break; 313 } 314 computeTime(); 315 } 316 317 318 // Compares the time field records. 319 public boolean before(GregorianCalendar when) { 320 return this.date.before(when.getTime()); 321 } 322 public boolean after(GregorianCalendar when) { 323 return this.date.after(when.getTime()); 324 } 325 public boolean equals(GregorianCalendar obj) { 326 return this.date.equals(obj.getTime()); 327 } 328 329 public boolean isLeapYear() { 330 return isLeapYear(this.year); 331 } 332 public static boolean isLeapYear(int year) { 333 if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) 334 return true; 335 return false; 336 } 337 338 339 // Converts the current millisecond time value time to field values in fields[]. 340 protected void computeFields() { 341 this.second = this.date.getSeconds(); 342 this.minute = this.date.getMinutes(); 343 this.hour = this.date.getHours(); 344 if (this.hour < 12) { 345 this.amPm = Calendar.AM; 346 } else { 347 this.hour -= 12; 348 this.amPm = Calendar.PM; 349 } 350 this.dayOfMonth = this.date.getDate(); 351 this.month = this.date.getMonth(); 352 this.year = this.date.getYear() + 1900; 353 354 } 355 // Converts the current field values in fields[] to the millisecond time value time. 356 protected void computeTime() { 357 this.date = new Date(this.year - 1900, this.month, this.dayOfMonth, this.hour, this.minute, this.second); 358 } 359 360 // Overrides Cloneable 361 public Object clone() { 362 GregorianCalendar newCal = new GregorianCalendar(); 363 newCal.setTime(this.date); 364 return newCal; 365 } 366 367 } // end of class GregorianCalendar