1 17 package org.apache.ws.jaxme.util; 18 19 import java.io.Serializable ; 20 21 22 24 public class Duration implements Serializable , Comparable { 25 private static final long serialVersionUID = 3257001055736117303L; 26 private final boolean isNegative; 27 private final int years, months, days, hours, minutes, seconds; 28 private final long millis; 29 30 32 public Duration(boolean pNegative, int pYears, int pMonths, int pDays, int pHours, int pMinutes, int pSeconds, long pMillis) { 33 isNegative = pNegative; 34 years = pYears; 35 months = pMonths; 36 days = pDays; 37 hours = pHours; 38 minutes = pMinutes; 39 seconds = pSeconds; 40 millis = pMillis; 41 } 42 43 45 public int getYears() { 46 return years; 47 } 48 49 51 public int getMonths() { 52 return months; 53 } 54 55 57 public int getDays() { 58 return days; 59 } 60 61 63 public int getHours() { 64 return hours; 65 } 66 67 69 public int getMinutes() { 70 return minutes; 71 } 72 73 75 public int getSeconds() { 76 return seconds; 77 } 78 79 81 public long getMillis() { 82 return millis; 83 } 84 85 87 public String toString() { 88 StringBuffer sb = new StringBuffer (); 89 sb.append('P'); 90 sb.append(getYears()); 91 sb.append('Y'); 92 sb.append(getMonths()); 93 sb.append('M'); 94 sb.append(getDays()); 95 sb.append("DT"); 96 sb.append(getHours()); 97 sb.append('H'); 98 sb.append(getMinutes()); 99 sb.append('M'); 100 sb.append(getSeconds()); 101 long m = getMillis(); 102 if (m != 0) { 103 sb.append('.'); 104 sb.append(m); 105 } 106 sb.append('S'); 107 return sb.toString(); 108 } 109 110 114 public static Duration valueOf(String pValue) { 115 if (pValue == null) { 116 throw new NullPointerException ("The duration value must not be null."); 117 } 118 int len = pValue.length(); 119 int offset = 0; 120 boolean isNegative; 121 if (len > 0) { 122 char c = pValue.charAt(0); 123 if (c == '-') { 124 isNegative = true; 125 ++offset; 126 } else if (c == '+') { 127 isNegative = false; 128 ++offset; 129 } else { 130 isNegative = false; 131 } 132 } else { 133 throw new IllegalArgumentException ("Invalid duration: Empty string"); 134 } 135 136 if (len == 0 || pValue.charAt(offset) != 'P') { 137 throw new IllegalArgumentException ("Invalid duration: " + pValue + " (must start with P, +P, or -P)"); 138 } else { 139 ++offset; 140 } 141 142 int years = -1, months = -1, daysOfMonth = -1, hours = -1, minutes = -1, seconds = -1; 143 long millis = -1; 144 int preDecimalPoint = -1; 145 boolean separatorSeen = false; 146 StringBuffer digits = new StringBuffer (); 147 while (offset < len) { 148 char c = pValue.charAt(offset); 149 if (Character.isDigit(c)) { 150 digits.append(c); 151 } else if (c == 'T') { 152 if (separatorSeen) { 153 throw new IllegalArgumentException ("Invalid duration: " + pValue 154 + " (date/time separator 'T' used twice)"); 155 } else { 156 separatorSeen = true; 157 } 158 } else { 159 long l; 160 if (digits.length() == 0) { 161 l = 0; 162 } else { 163 try { 164 l = Long.parseLong(digits.toString()); 165 } catch (NumberFormatException e) { 166 throw new IllegalArgumentException ("Invalid duration: " + pValue 167 + " (max long value exceeded by " + digits + ")"); 168 } 169 digits.setLength(0); 170 } 171 if (preDecimalPoint >= 0) { 172 if (c == 'S') { 173 if (!separatorSeen) { 174 throw new IllegalArgumentException ("Invalid duration: " + pValue 175 + "(seconds specified before date/time separator 'T' seen)"); 176 } 177 if (seconds != -1) { 178 throw new IllegalArgumentException ("Invalid duration: " + pValue 179 + " (seconds specified twice)"); 180 } 181 seconds = preDecimalPoint; 182 millis = l; 183 preDecimalPoint = -1; 184 } else { 185 throw new IllegalArgumentException ("Invalid duration: " + pValue 186 + " (decimal point not allowed here: " 187 + preDecimalPoint + "." + digits + c + ")"); 188 } 189 } else if (l > Integer.MAX_VALUE) { 190 throw new IllegalArgumentException ("Invalid duration: " + pValue 191 + " (max integer value exceeded by " + digits + ")"); 192 } else { 193 int i = (int) l; 194 if (c == '.') { 195 preDecimalPoint = i; 196 } else if (separatorSeen) { 197 if (c == 'Y' || c == 'D') { 198 throw new IllegalArgumentException ("Invalid duration: " + pValue 199 + " (years or days of month specified after date/time separator 'T' seen)"); 200 } else if (c == 'S') { 201 if (seconds != -1) { 202 throw new IllegalArgumentException ("Invalid duration: " + pValue 203 + " (seconds specified twice)"); 204 } 205 seconds = i; 206 millis = 0; 207 } else if (c == 'M') { 208 if (minutes != -1) { 209 throw new IllegalArgumentException ("Invalid duration: " + pValue 210 + " (minutes specified twice)"); 211 } else if (seconds != -1) { 212 throw new IllegalArgumentException ("Invalid duration: " + pValue 213 + " (minutes specified after seconds)"); 214 } 215 minutes = i; 216 } else if (c == 'H') { 217 if (hours != -1) { 218 throw new IllegalArgumentException ("Invalid duration: " + pValue 219 + " (hours specified twice)"); 220 } else if (minutes != -1) { 221 throw new IllegalArgumentException ("Invalid duration: " + pValue 222 + " (hours specified after minutes)"); 223 } else if (seconds != -1) { 224 throw new IllegalArgumentException ("Invalid duration: " + pValue 225 + " (seconds specified after minutes)"); 226 } 227 hours = i; 228 } 229 } else { 230 if (c == 'H' || c == 'S') { 231 throw new IllegalArgumentException ("Invalid duration: " + pValue 232 + " (hours or seconds specified before date/time separator 'T' seen)"); 233 } else if (c == 'Y') { 234 if (years != -1) { 235 throw new IllegalArgumentException ("Invalid duration: " + pValue 236 + " (years specified twice)"); 237 } else if (months != -1) { 238 throw new IllegalArgumentException ("Invalid duration: " + pValue 239 + " (years specified after months)"); 240 } else if (daysOfMonth != -1) { 241 throw new IllegalArgumentException ("Invalid duration: " + pValue 242 + " (years specified after days of month)"); 243 } 244 years = i; 245 } else if (c == 'M') { 246 if (months != -1) { 247 throw new IllegalArgumentException ("Invalid duration: " + pValue 248 + " (months specified twice)"); 249 } else if (daysOfMonth != -1) { 250 throw new IllegalArgumentException ("Invalid duration: " + pValue 251 + " (days of month specified after months)"); 252 } 253 months = i; 254 } else if (c == 'D') { 255 if (daysOfMonth != -1) { 256 throw new IllegalArgumentException ("Invalid duration: " + pValue 257 + " (days of month specified twice)"); 258 } 259 daysOfMonth = i; 260 } 261 } 262 } 263 } 264 ++offset; 265 } 266 return new Duration(isNegative, 267 years == -1 ? 0 : years, 268 months == -1 ? 0 : months, 269 daysOfMonth == -1 ? 0 :daysOfMonth, 270 hours == -1 ? 0 : hours, 271 minutes == -1 ? 0 : minutes, 272 seconds == -1 ? 0 : seconds, 273 millis == -1 ? 0 : millis); 274 } 275 276 public boolean equals(Object o) { 277 if (o == null || !(o instanceof Duration)) { 278 return false; 279 } 280 return compareTo((Duration) o) == 0; 281 } 282 283 public int compareTo(Object o) { 284 return compareTo((Duration) o); 285 } 286 287 289 public int compareTo(Duration d) { 290 if (isNegative != d.isNegative) { 291 return isNegative ? -1 : 1; 292 } 293 if (years != d.years) { return years - d.years; } 294 if (months != d.months) { return months - d.months; } 295 if (days != d.days) { return days - d.days; } 296 if (hours != d.hours) { return hours - d.hours; } 297 if (minutes != d.minutes) { return minutes - d.minutes; } 298 if (seconds != d.seconds) { return seconds - d.seconds; } 299 if (millis > d.millis) { 300 return 1; 301 } else if (millis < d.millis) { 302 return -1; 303 } else { 304 return 0; 305 } 306 } 307 308 public int hashCode() { 309 return isNegative ? 1 : 0 + years + months + days + hours + minutes + seconds + (int) millis; 310 } 311 } 312 | Popular Tags |