1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 package org.exolab.castor.types;
37
38 import java.text.ParseException;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class TimeDuration implements java.io.Serializable {
57
58 private static final long serialVersionUID = -3080457339689062021L;
59
60
61 private static final boolean DEBUG = false;
62
63 private static final int TIME_FLAG = 8;
64
65
66
67
68
69 private short _year = 0;
70
71
72
73 private short _month = 0;
74
75
76
77 private short _day = 0;
78
79
80
81 private short _hour = 0;
82
83
84
85 private short _minute = 0;
86
87
88
89 private short _second = 0;
90
91
92
93
94 private short _millisecond = 0;
95
96
97
98
99 private boolean _isNegative = false;
100
101
102
103
104 public TimeDuration() {}
105
106
107
108
109
110
111
112
113
114 public TimeDuration(long l) {
115
116 long refSecond = 1000;
117 long refMinute = 60 * refSecond;
118 long refHour = 60 * refMinute;
119 long refDay = 24 * refHour;
120 long refMonth = (long) (30.42 * refDay);
121 long refYear = 12 * refMonth;
122
123 if (DEBUG) {
124 System.out.println("In time duration Constructor");
125 System.out.println("long : " + l);
126 }
127
128 if (l < 0) {
129 this.setNegative();
130 l = -l;
131 }
132
133 short year = (short) (l / refYear);
134 l = l % refYear;
135 if (DEBUG) {
136 System.out.println("nb years:" + year);
137 System.out.println("New long : " + l);
138 }
139
140 short month = (short) (l / refMonth);
141 l = l % refMonth;
142 if (DEBUG) {
143 System.out.println("nb months:" + month);
144 System.out.println("New long : " + l);
145 System.out.println(refDay);
146 }
147
148 short day = (short) (l / refDay);
149 l = l % refDay;
150 if (DEBUG) {
151 System.out.println("nb days:" + day);
152 System.out.println("New long : " + l);
153 }
154
155 short hour = (short) (l / refHour);
156 l = l % refHour;
157 if (DEBUG) {
158 System.out.println("nb hours:" + hour);
159 System.out.println("New long : " + l);
160 }
161
162 short minute = (short) (l / refMinute);
163 l = l % refMinute;
164 if (DEBUG) {
165 System.out.println("nb minutes:" + minute);
166 System.out.println("New long : " + l);
167 }
168
169 short seconds = (short) (l / refSecond);
170 l = l % refSecond;
171 if (DEBUG) {
172 System.out.println("nb seconds:" + seconds);
173 }
174
175 short milliseconds = (short) (l);
176 if (DEBUG) {
177 System.out.println("nb milliseconds:" + milliseconds);
178 }
179
180 this.setValue(year, month, day, hour, minute, seconds, milliseconds);
181 }
182
183
184 public void setYear(short year) {
185 _year = year;
186 }
187
188 public void setMonth(short month) {
189 _month = month;
190 }
191
192 public void setDay(short day) {
193 _day = day;
194 }
195
196 public void setHour(short hour) {
197 _hour = hour;
198 }
199
200 public void setMinute(short minute) {
201 _minute = minute;
202 }
203
204 public void setSeconds(short second) {
205 _second = second;
206 }
207
208 public void setMilli(short milli) {
209 _millisecond = milli;
210 }
211
212 public void setNegative() {
213 _isNegative = true;
214 }
215
216
217
218
219
220
221
222
223
224
225
226 public void setValue(short year, short month, short day, short hour, short minute, short second,
227 short millisecond) {
228 this.setYear(year);
229 this.setMonth(month);
230 this.setDay(day);
231 this.setHour(hour);
232 this.setMinute(minute);
233 this.setSeconds(second);
234 this.setMilli(millisecond);
235 }
236
237
238
239 public short getYear() {
240 return (_year);
241 }
242
243 public short getMonth() {
244 return (_month);
245 }
246
247 public short getDay() {
248 return (_day);
249 }
250
251 public short getHour() {
252 return (_hour);
253 }
254
255 public short getMinute() {
256 return (_minute);
257 }
258
259 public short getSeconds() {
260 return (_second);
261 }
262
263 public short getMilli() {
264 return (_millisecond);
265 }
266
267 public boolean isNegative() {
268 return _isNegative;
269 }
270
271
272
273
274
275
276
277 public long toLong() {
278 long result = 0;
279
280
281 result =
282 ((long) (((((((_year * 12L) + _month) * 30.42 + _day) * 24L + _hour) * 60L + _minute) * 60L
283 + _second) * 1000L + _millisecond));
284
285 result = isNegative() ? -result : result;
286 return result;
287 }
288
289
290
291
292
293
294
295
296
297 public String toString() {
298 StringBuilder result = new StringBuilder();
299 result.append('P');
300 if (_year != 0) {
301 result.append(_year).append('Y');
302 }
303 if (_month != 0) {
304 result.append(_month).append('M');
305 }
306 if (_day != 0) {
307 result.append(_day).append('D');
308 }
309 boolean isThereTime = ((_hour != 0) || (_minute != 0) || (_second != 0));
310 if (isThereTime) {
311 result.append('T');
312 if (_hour != 0) {
313 result.append(_hour).append('H');
314 }
315 if (_minute != 0) {
316 result.append(_minute).append('M');
317 }
318 if (_second != 0) {
319 result.append(_second);
320 if (_millisecond != 0) {
321 result.append('.');
322 if (_millisecond < 100) {
323 result.append('0');
324 if (_millisecond < 10)
325 result.append('0');
326 }
327 result.append(_millisecond);
328 }
329 result.append('S');
330 }
331 }
332 if (_isNegative)
333 result.insert(0, '-');
334 return result.toString();
335 }
336
337
338
339
340
341
342
343
344
345 public static Object parse(String str) throws ParseException {
346 return parseTimeDuration(str);
347 }
348
349
350
351
352
353
354
355
356
357 public static TimeDuration parseTimeDuration(String str) throws ParseException {
358
359
360 if (str == null) {
361 throw new IllegalArgumentException("the string to be parsed must not" + " be null");
362
363 }
364
365 TimeDuration result = new TimeDuration();
366 char[] chars = str.toCharArray();
367 int idx = 0;
368
369
370 if (chars.length == 0) {
371
372 return null;
373 }
374
375 if (chars[idx] == '-') {
376 ++idx;
377 result.setNegative();
378 if (idx >= chars.length) {
379 throw new ParseException("'-' is wrong placed", 0);
380 }
381 }
382
383
384 if (chars[idx] != 'P') {
385 throw new ParseException("Missing 'P' delimiter", idx);
386 }
387 ++idx;
388
389
390 int number = 0;
391 boolean hasNumber = false;
392
393
394
395
396 int flags = 0;
397
398 while (idx < chars.length) {
399
400 char ch = chars[idx++];
401
402 switch (ch) {
403
404
405 case 'Y':
406
407 if (flags > 0) {
408 String err = str + ":Syntax error, 'Y' must " + "proceed all other delimiters.";
409 throw new ParseException(err, idx);
410 }
411
412 flags = 64;
413 if (hasNumber) {
414 result.setYear((short) number);
415 hasNumber = false;
416 } else {
417 String err = str + ":missing number of years before 'Y'";
418 throw new ParseException(err, idx);
419 }
420
421 break;
422
423 case 'M':
424
425
426 if ((flags & TIME_FLAG) == 8) {
427
428
429
430 if ((flags & 3) > 0) {
431 throw new ParseException(str + ": Syntax Error...", idx);
432 }
433 flags = flags | 2;
434 if (hasNumber) {
435 result.setMinute((short) number);
436 hasNumber = false;
437 } else {
438 String err = str + ": missing number of minutes " + "before 'M'";
439 throw new ParseException(err, idx);
440 }
441 }
442
443 else {
444
445
446 if ((flags & 63) > 0) {
447 throw new ParseException(str + ":Syntax Error...", idx);
448 }
449 flags = flags | 32;
450 if (hasNumber) {
451 result.setMonth((short) number);
452 hasNumber = false;
453 } else {
454 String err = str + ":missing number of months before 'M'";
455 throw new ParseException(err, idx);
456 }
457 }
458 break;
459
460 case 'D':
461
462 if ((flags & 31) > 0) {
463 throw new ParseException(str + ":Syntax Error...", idx);
464 }
465 flags = flags | 16;
466 if (hasNumber) {
467 result.setDay((short) number);
468 hasNumber = false;
469 } else {
470 String err = str + ":missing number of days before 'D'";
471 throw new ParseException(err, idx);
472 }
473 break;
474
475 case 'T':
476
477 if ((flags & TIME_FLAG) == 8) {
478 String err = str + ":Syntax error, 'T' may not " + "exist more than once.";
479 throw new ParseException(err, idx);
480 }
481 flags = flags | 8;
482 break;
483
484 case 'H':
485
486
487 if ((flags & 15) != 8) {
488 String err = null;
489 if ((flags & 8) != 8)
490 err = str + ": Missing 'T' before 'H'";
491 else
492 err = str + ": Syntax Error, 'H' must appear for 'M' or 'S'";
493 throw new ParseException(err, idx);
494 }
495 flags = flags | 4;
496 if (hasNumber) {
497 result.setHour((short) number);
498 hasNumber = false;
499 } else {
500 String err = str + ":missing number of hours before 'H'";
501 throw new ParseException(err, idx);
502 }
503 break;
504 case 'S':
505 if (flags != 0) {
506
507 if ((flags & 8) != 8) {
508 String err = str + ": Missing 'T' before 'S'";
509 throw new ParseException(err, idx);
510 }
511 if ((flags & 1) == 1) {
512 String err = str + ": Syntax error 'S' may not exist more than once.";
513 throw new ParseException(err, idx);
514 }
515
516 flags = flags | 1;
517 if (hasNumber) {
518 result.setSeconds((short) number);
519 hasNumber = false;
520 } else {
521 String err = str + ": missing number of seconds before 'S'";
522 throw new ParseException(err, idx);
523 }
524 } else {
525 if (hasNumber) {
526 String numb = Integer.toString(number);
527 if (numb.length() < 3) {
528 if (numb.length() < 2)
529 number = number * 10;
530 number = number * 10;
531 }
532 result.setMilli((short) number);
533 hasNumber = false;
534 } else {
535 String err = str + ": missing number of milliseconds before 'S'";
536 throw new ParseException(err, idx);
537 }
538 }
539
540 break;
541
542 case '.':
543
544 if ((flags | 1) == 1) {
545 String err = str + ": Syntax error '.' may not exist more than once.";
546 throw new ParseException(err, idx);
547 }
548
549 if ((flags & 8) != 8) {
550 String err = str + ": Missing 'T' before 'S'";
551 throw new ParseException(err, idx);
552 }
553
554
555 flags = 0;
556
557 if (hasNumber) {
558 result.setSeconds((short) number);
559 hasNumber = false;
560 }
561
562 else {
563 String err = str + ": missing number of seconds before 'S'";
564 throw new ParseException(err, idx);
565 }
566 break;
567
568 default:
569
570 if (('0' <= ch) && (ch <= '9')) {
571
572 if (hasNumber)
573 number = (number * 10) + (ch - 48);
574 else {
575 hasNumber = true;
576 number = (ch - 48);
577 }
578 } else
579 throw new ParseException(str + ":Invalid character: " + ch, idx);
580 break;
581 }
582 }
583
584 if ((flags & 15) == 8) {
585 throw new ParseException(str + ": T must be omitted", idx);
586 }
587
588 if (hasNumber) {
589 throw new ParseException(str + ": expecting ending delimiter", idx);
590 }
591
592 return result;
593
594 }
595
596
597
598
599
600
601 public boolean equals(Object object) {
602 if (object instanceof TimeDuration)
603 return equal((TimeDuration) object);
604 return false;
605 }
606
607
608
609
610
611
612
613 public boolean equal(TimeDuration timeD) {
614 boolean result = false;
615 if (timeD == null)
616 return result;
617 result = (_year == timeD.getYear());
618 result = result && (_month == timeD.getMonth());
619 result = result && (_day == timeD.getDay());
620 result = result && (_hour == timeD.getHour());
621 result = result && (_minute == timeD.getMinute());
622 result = result && (_second == timeD.getSeconds());
623 result = result && (this.isNegative() == timeD.isNegative());
624 return result;
625 }
626
627
628
629
630
631
632
633
634
635
636
637 public boolean isGreater(TimeDuration timeD) {
638 boolean result = false;
639
640 result = this.toLong() > timeD.toLong();
641 return result;
642 }
643 }