1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.util;
21
22 import static org.apache.directory.api.util.TimeZones.GMT;
23
24 import java.text.ParseException;
25 import java.util.Calendar;
26 import java.util.Date;
27 import java.util.GregorianCalendar;
28 import java.util.Locale;
29 import java.util.TimeZone;
30
31 import org.apache.directory.api.i18n.I18n;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 public class GeneralizedTime implements Comparable<GeneralizedTime>
113 {
114
115 private static final Date INFINITE = new Date( 0x7FFFFFFFFFFFFFFFL );
116
117
118
119
120 public enum Format
121 {
122
123 YEAR_MONTH_DAY_HOUR_MIN_SEC,
124
125
126 YEAR_MONTH_DAY_HOUR_MIN_SEC_FRACTION,
127
128
129 YEAR_MONTH_DAY_HOUR_MIN,
130
131
132 YEAR_MONTH_DAY_HOUR_MIN_FRACTION,
133
134
135 YEAR_MONTH_DAY_HOUR,
136
137
138 YEAR_MONTH_DAY_HOUR_FRACTION;
139 }
140
141
142
143
144 public enum FractionDelimiter
145 {
146
147 DOT,
148
149 COMMA
150 }
151
152
153
154
155 public enum TimeZoneFormat
156 {
157
158 Z,
159
160 DIFF_HOUR,
161
162 DIFF_HOUR_MINUTE
163 }
164
165
166 private String upGeneralizedTime;
167
168
169 private Format upFormat;
170
171
172 private TimeZoneFormat upTimeZoneFormat;
173
174
175 private FractionDelimiter upFractionDelimiter;
176
177
178 private int upFractionLength;
179
180
181 private Calendar calendar;
182
183
184
185
186
187
188
189
190
191 public GeneralizedTime( Date date )
192 {
193 calendar = new GregorianCalendar( GMT, Locale.ROOT );
194 calendar.setTime( date );
195 setUp( calendar );
196 }
197
198
199
200
201
202
203
204
205
206 public GeneralizedTime( Calendar calendar )
207 {
208 setUp( calendar );
209 }
210
211
212
213
214
215
216
217
218 public GeneralizedTime( long timeInMillis )
219 {
220 Locale locale = Locale.getDefault();
221 TimeZone timeZone = TimeZone.getTimeZone( "GMT" );
222 calendar = Calendar.getInstance( timeZone, locale );
223 calendar.setTimeInMillis( timeInMillis );
224 setUp( calendar );
225 }
226
227
228
229
230
231
232
233
234
235
236 public GeneralizedTime( String generalizedTime ) throws ParseException
237 {
238 if ( generalizedTime == null )
239 {
240 throw new ParseException( I18n.err( I18n.ERR_17043_GENERALIZED_TIME_NULL ), 0 );
241 }
242
243 this.upGeneralizedTime = generalizedTime;
244
245 calendar = new GregorianCalendar( GMT, Locale.ROOT );
246 calendar.setTimeInMillis( 0 );
247 calendar.setLenient( false );
248
249 parseYear();
250 parseMonth();
251 parseDay();
252 parseHour();
253
254 if ( upGeneralizedTime.length() < 11 )
255 {
256 throw new ParseException( I18n.err( I18n.ERR_17044_BAD_GENERALIZED_TIME ), 10 );
257 }
258
259
260
261
262
263
264 int pos = 10;
265 char c = upGeneralizedTime.charAt( pos );
266
267 if ( ( '0' <= c ) && ( c <= '9' ) )
268 {
269 parseMinute();
270
271 if ( upGeneralizedTime.length() < 13 )
272 {
273 throw new ParseException( I18n.err( I18n.ERR_17045_BAD_GENERALIZED_TIME ), 12 );
274 }
275
276
277
278
279
280
281 pos = 12;
282 c = upGeneralizedTime.charAt( pos );
283
284 if ( ( '0' <= c ) && ( c <= '9' ) )
285 {
286 parseSecond();
287
288 if ( upGeneralizedTime.length() < 15 )
289 {
290 throw new ParseException( I18n.err( I18n.ERR_17046_BAD_GENERALIZED_TIME ), 14 );
291 }
292
293
294
295
296
297 pos = 14;
298 c = upGeneralizedTime.charAt( pos );
299
300 if ( ( c == '.' ) || ( c == ',' ) )
301 {
302
303 parseFractionOfSecond();
304 pos += 1 + upFractionLength;
305
306 parseTimezone( pos );
307 upFormat = Format.YEAR_MONTH_DAY_HOUR_MIN_SEC_FRACTION;
308 }
309 else if ( ( c == 'Z' ) || ( c == '+' ) || ( c == '-' ) )
310 {
311
312 parseTimezone( pos );
313 upFormat = Format.YEAR_MONTH_DAY_HOUR_MIN_SEC;
314 }
315 else
316 {
317 throw new ParseException( I18n.err( I18n.ERR_17047_TIME_TOO_SHORT ), 14 );
318 }
319 }
320 else if ( ( c == '.' ) || ( c == ',' ) )
321 {
322
323 parseFractionOfMinute();
324 pos += 1 + upFractionLength;
325
326 parseTimezone( pos );
327 upFormat = Format.YEAR_MONTH_DAY_HOUR_MIN_FRACTION;
328 }
329 else if ( ( c == 'Z' ) || ( c == '+' ) || ( c == '-' ) )
330 {
331
332 parseTimezone( pos );
333 upFormat = Format.YEAR_MONTH_DAY_HOUR_MIN;
334 }
335 else
336 {
337 throw new ParseException( I18n.err( I18n.ERR_17048_TIME_TOO_SHORT ), 12 );
338 }
339 }
340 else if ( ( c == '.' ) || ( c == ',' ) )
341 {
342
343 parseFractionOfHour();
344 pos += 1 + upFractionLength;
345
346 parseTimezone( pos );
347 upFormat = Format.YEAR_MONTH_DAY_HOUR_FRACTION;
348 }
349 else if ( ( c == 'Z' ) || ( c == '+' ) || ( c == '-' ) )
350 {
351
352 parseTimezone( pos );
353 upFormat = Format.YEAR_MONTH_DAY_HOUR;
354 }
355 else
356 {
357 throw new ParseException( I18n.err( I18n.ERR_17049_INVALID_GENERALIZED_TIME ), 10 );
358 }
359
360
361
362 try
363 {
364 calendar.getTimeInMillis();
365 }
366 catch ( IllegalArgumentException iae )
367 {
368 throw new ParseException( I18n.err( I18n.ERR_17050_INVALID_DATE_TIME ), 0 );
369 }
370
371 calendar.setLenient( true );
372 }
373
374
375 private void setUp( Calendar newCalendar )
376 {
377 if ( newCalendar == null )
378 {
379 throw new IllegalArgumentException( I18n.err( I18n.ERR_17051_CALENDAR_NULL ) );
380 }
381
382 this.calendar = newCalendar;
383 upGeneralizedTime = null;
384 upFormat = Format.YEAR_MONTH_DAY_HOUR_MIN_SEC_FRACTION;
385 upTimeZoneFormat = TimeZoneFormat.Z;
386 upFractionDelimiter = FractionDelimiter.DOT;
387 upFractionLength = 3;
388 }
389
390
391 private void parseTimezone( int pos ) throws ParseException
392 {
393 if ( upGeneralizedTime.length() < pos + 1 )
394 {
395 throw new ParseException( I18n.err( I18n.ERR_17052_TIME_TOO_SHOR_NO_TZ ), pos );
396 }
397
398 char c = upGeneralizedTime.charAt( pos );
399
400 if ( c == 'Z' )
401 {
402 calendar.setTimeZone( GMT );
403 upTimeZoneFormat = TimeZoneFormat.Z;
404
405 if ( upGeneralizedTime.length() > pos + 1 )
406 {
407 throw new ParseException( I18n.err( I18n.ERR_17053_MISSING_TZ ), pos + 1 );
408 }
409 }
410 else if ( ( c == '+' ) || ( c == '-' ) )
411 {
412 StringBuilder sb = new StringBuilder( "GMT" );
413 sb.append( c );
414
415 String digits = getAllDigits( pos + 1 );
416 sb.append( digits );
417
418 if ( digits.length() == 2 && digits.matches( "^([01]\\d|2[0-3])$" ) )
419 {
420 TimeZone timeZone = TimeZone.getTimeZone( sb.toString() );
421 calendar.setTimeZone( timeZone );
422 upTimeZoneFormat = TimeZoneFormat.DIFF_HOUR;
423 }
424 else if ( digits.length() == 4 && digits.matches( "^([01]\\d|2[0-3])([0-5]\\d)$" ) )
425 {
426 TimeZone timeZone = TimeZone.getTimeZone( sb.toString() );
427 calendar.setTimeZone( timeZone );
428 upTimeZoneFormat = TimeZoneFormat.DIFF_HOUR_MINUTE;
429 }
430 else
431 {
432 throw new ParseException( I18n.err( I18n.ERR_17054_TZ_MUST_BE_2_OR_4_DIGITS ), pos );
433 }
434
435 if ( upGeneralizedTime.length() > pos + 1 + digits.length() )
436 {
437 throw new ParseException( I18n.err( I18n.ERR_17053_MISSING_TZ ), pos + 1 + digits.length() );
438 }
439 }
440 }
441
442
443 private void parseFractionOfSecond() throws ParseException
444 {
445 parseFractionDelmiter( 14 );
446 String fraction = getFraction( 14 + 1 );
447 upFractionLength = fraction.length();
448
449 double fract = Double.parseDouble( "0." + fraction );
450 int millisecond = ( int ) Math.floor( fract * 1000 );
451
452 calendar.set( GregorianCalendar.MILLISECOND, millisecond );
453 }
454
455
456 private void parseFractionOfMinute() throws ParseException
457 {
458 parseFractionDelmiter( 12 );
459 String fraction = getFraction( 12 + 1 );
460 upFractionLength = fraction.length();
461
462 double fract = Double.parseDouble( "0." + fraction );
463 int milliseconds = ( int ) Math.round( fract * 1000 * 60 );
464 int second = milliseconds / 1000;
465 int millisecond = milliseconds - ( second * 1000 );
466
467 calendar.set( Calendar.SECOND, second );
468 calendar.set( Calendar.MILLISECOND, millisecond );
469 }
470
471
472 private void parseFractionOfHour() throws ParseException
473 {
474 parseFractionDelmiter( 10 );
475 String fraction = getFraction( 10 + 1 );
476 upFractionLength = fraction.length();
477
478 double fract = Double.parseDouble( "0." + fraction );
479 int milliseconds = ( int ) Math.round( fract * 1000 * 60 * 60 );
480 int minute = milliseconds / ( 1000 * 60 );
481 int second = ( milliseconds - ( minute * 60 * 1000 ) ) / 1000;
482 int millisecond = milliseconds - ( minute * 60 * 1000 ) - ( second * 1000 );
483
484 calendar.set( Calendar.MINUTE, minute );
485 calendar.set( Calendar.SECOND, second );
486 calendar.set( Calendar.MILLISECOND, millisecond );
487 }
488
489
490 private void parseFractionDelmiter( int fractionDelimiterPos )
491 {
492 char c = upGeneralizedTime.charAt( fractionDelimiterPos );
493 upFractionDelimiter = c == '.' ? FractionDelimiter.DOT : FractionDelimiter.COMMA;
494 }
495
496
497 private String getFraction( int startIndex ) throws ParseException
498 {
499 String fraction = getAllDigits( startIndex );
500
501
502 if ( fraction.length() == 0 )
503 {
504 throw new ParseException( I18n.err( I18n.ERR_17055_MISSING_FRACTION ), startIndex );
505 }
506
507 return fraction;
508 }
509
510
511 private String getAllDigits( int startIndex )
512 {
513 StringBuilder sb = new StringBuilder();
514 while ( upGeneralizedTime.length() > startIndex )
515 {
516 char c = upGeneralizedTime.charAt( startIndex );
517 if ( '0' <= c && c <= '9' )
518 {
519 sb.append( c );
520 startIndex++;
521 }
522 else
523 {
524 break;
525 }
526 }
527 return sb.toString();
528 }
529
530
531 private void parseSecond() throws ParseException
532 {
533
534 if ( upGeneralizedTime.length() < 14 )
535 {
536 throw new ParseException( I18n.err( I18n.ERR_17056_TIME_TOO_SHORT_NO_SECOND ), 12 );
537 }
538 try
539 {
540 int second = Strings.parseInt( upGeneralizedTime.substring( 12, 14 ) );
541 calendar.set( Calendar.SECOND, second );
542 }
543 catch ( NumberFormatException e )
544 {
545 throw new ParseException( I18n.err( I18n.ERR_17057_SECOND_NOT_NUM ), 12 );
546 }
547 }
548
549
550 private void parseMinute() throws ParseException
551 {
552
553 if ( upGeneralizedTime.length() < 12 )
554 {
555 throw new ParseException( I18n.err( I18n.ERR_17058_MISSING_MINUTE ), 10 );
556 }
557 try
558 {
559 int minute = Strings.parseInt( upGeneralizedTime.substring( 10, 12 ) );
560 calendar.set( Calendar.MINUTE, minute );
561 }
562 catch ( NumberFormatException e )
563 {
564 throw new ParseException( I18n.err( I18n.ERR_17059_MIN_NOT_NUM ), 10 );
565 }
566 }
567
568
569 private void parseHour() throws ParseException
570 {
571 if ( upGeneralizedTime.length() < 10 )
572 {
573 throw new ParseException( I18n.err( I18n.ERR_17060_TIME_TO_SHORT_MISSING_HOUR ), 8 );
574 }
575 try
576 {
577 int hour = Strings.parseInt( upGeneralizedTime.substring( 8, 10 ) );
578 calendar.set( Calendar.HOUR_OF_DAY, hour );
579 }
580 catch ( NumberFormatException e )
581 {
582 throw new ParseException( I18n.err( I18n.ERR_17061_HOUR_NOT_NUM ), 8 );
583 }
584 }
585
586
587 private void parseDay() throws ParseException
588 {
589 if ( upGeneralizedTime.length() < 8 )
590 {
591 throw new ParseException( I18n.err( I18n.ERR_17062_TIME_TO_SHORT_MISSING_DAY ), 6 );
592 }
593 try
594 {
595 int day = Strings.parseInt( upGeneralizedTime.substring( 6, 8 ) );
596 calendar.set( Calendar.DAY_OF_MONTH, day );
597 }
598 catch ( NumberFormatException e )
599 {
600 throw new ParseException( I18n.err( I18n.ERR_17063_DAY_NOT_NUM ), 6 );
601 }
602 }
603
604
605 private void parseMonth() throws ParseException
606 {
607 if ( upGeneralizedTime.length() < 6 )
608 {
609 throw new ParseException( I18n.err( I18n.ERR_17064_TIME_TO_SHORT_MISSING_MONTH ), 4 );
610 }
611 try
612 {
613 int month = Strings.parseInt( upGeneralizedTime.substring( 4, 6 ) );
614 calendar.set( Calendar.MONTH, month - 1 );
615 }
616 catch ( NumberFormatException e )
617 {
618 throw new ParseException( I18n.err( I18n.ERR_17065_MONTH_NOT_NUM ), 4 );
619 }
620 }
621
622
623 private void parseYear() throws ParseException
624 {
625 if ( upGeneralizedTime.length() < 4 )
626 {
627 throw new ParseException( I18n.err( I18n.ERR_17066_TIME_TO_SHORT_MISSING_YEAR ), 0 );
628 }
629 try
630 {
631 int year = Strings.parseInt( upGeneralizedTime.substring( 0, 4 ) );
632 calendar.set( Calendar.YEAR, year );
633 }
634 catch ( NumberFormatException e )
635 {
636 throw new ParseException( I18n.err( I18n.ERR_17067_YEAR_NOT_NUM ), 0 );
637 }
638 }
639
640
641
642
643
644
645
646
647 public String toGeneralizedTime()
648 {
649 return toGeneralizedTime( upFormat, upFractionDelimiter, upFractionLength, upTimeZoneFormat );
650 }
651
652
653
654
655
656
657
658
659 public String toGeneralizedTimeWithoutFraction()
660 {
661 return toGeneralizedTime( getFormatWithoutFraction( upFormat ), upFractionDelimiter, upFractionLength,
662 upTimeZoneFormat );
663 }
664
665
666
667
668
669
670
671
672 private Format getFormatWithoutFraction( Format f )
673 {
674 switch ( f )
675 {
676 case YEAR_MONTH_DAY_HOUR_FRACTION:
677 return Format.YEAR_MONTH_DAY_HOUR;
678 case YEAR_MONTH_DAY_HOUR_MIN_FRACTION:
679 return Format.YEAR_MONTH_DAY_HOUR_MIN;
680 case YEAR_MONTH_DAY_HOUR_MIN_SEC_FRACTION:
681 return Format.YEAR_MONTH_DAY_HOUR_MIN_SEC;
682 default:
683 break;
684 }
685
686 return f;
687 }
688
689
690
691
692
693
694
695
696
697
698
699
700 public String toGeneralizedTime( Format format, FractionDelimiter fractionDelimiter, int fractionLength,
701 TimeZoneFormat timeZoneFormat )
702 {
703 Calendar clonedCalendar = ( Calendar ) calendar.clone();
704
705 if ( timeZoneFormat == TimeZoneFormat.Z )
706 {
707 clonedCalendar.setTimeZone( GMT );
708 }
709
710
711 byte[] result = new byte[23];
712
713
714 int pos = 0;
715
716
717 int year = clonedCalendar.get( Calendar.YEAR );
718
719 result[pos++] = ( byte ) ( ( year / 1000 ) + '0' );
720 year %= 1000;
721
722 result[pos++] = ( byte ) ( ( year / 100 ) + '0' );
723 year %= 100;
724
725 result[pos++] = ( byte ) ( ( year / 10 ) + '0' );
726
727 result[pos++] = ( byte ) ( ( year % 10 ) + '0' );
728
729
730 int month = clonedCalendar.get( Calendar.MONTH ) + 1;
731
732 result[pos++] = ( byte ) ( ( month / 10 ) + '0' );
733
734 result[pos++] = ( byte ) ( ( month % 10 ) + '0' );
735
736
737 int day = clonedCalendar.get( Calendar.DAY_OF_MONTH );
738
739 result[pos++] = ( byte ) ( ( day / 10 ) + '0' );
740
741 result[pos++] = ( byte ) ( ( day % 10 ) + '0' );
742
743
744 int hour = clonedCalendar.get( Calendar.HOUR_OF_DAY );
745
746 result[pos++] = ( byte ) ( ( hour / 10 ) + '0' );
747
748 result[pos++] = ( byte ) ( ( hour % 10 ) + '0' );
749
750 switch ( format )
751 {
752 case YEAR_MONTH_DAY_HOUR_MIN_SEC:
753
754 int minute = clonedCalendar.get( Calendar.MINUTE );
755
756 result[pos++] = ( byte ) ( ( minute / 10 ) + '0' );
757
758 result[pos++] = ( byte ) ( ( minute % 10 ) + '0' );
759
760
761 int second = clonedCalendar.get( Calendar.SECOND );
762
763 result[pos++] = ( byte ) ( ( second / 10 ) + '0' );
764
765 result[pos++] = ( byte ) ( ( second % 10 ) + '0' );
766
767 break;
768
769 case YEAR_MONTH_DAY_HOUR_MIN_SEC_FRACTION:
770
771 minute = clonedCalendar.get( Calendar.MINUTE );
772
773 result[pos++] = ( byte ) ( ( minute / 10 ) + '0' );
774
775 result[pos++] = ( byte ) ( ( minute % 10 ) + '0' );
776
777
778 second = clonedCalendar.get( Calendar.SECOND );
779
780 result[pos++] = ( byte ) ( ( second / 10 ) + '0' );
781
782 result[pos++] = ( byte ) ( ( second % 10 ) + '0' );
783
784
785 if ( fractionDelimiter == FractionDelimiter.COMMA )
786 {
787 result[pos++] = ',';
788 }
789 else
790 {
791 result[pos++] = '.';
792 }
793
794
795 int millisecond = clonedCalendar.get( Calendar.MILLISECOND );
796
797 result[pos++] = ( byte ) ( ( millisecond / 100 ) + '0' );
798 millisecond %= 100;
799
800 result[pos++] = ( byte ) ( ( millisecond / 10 ) + '0' );
801
802
803 result[pos++] = ( byte ) ( ( millisecond % 10 ) + '0' );
804
805 break;
806
807 case YEAR_MONTH_DAY_HOUR_MIN:
808
809 minute = clonedCalendar.get( Calendar.MINUTE );
810
811 result[pos++] = ( byte ) ( ( minute / 10 ) + '0' );
812
813 result[pos++] = ( byte ) ( ( minute % 10 ) + '0' );
814 break;
815
816 case YEAR_MONTH_DAY_HOUR_MIN_FRACTION:
817
818 minute = clonedCalendar.get( Calendar.MINUTE );
819
820 result[pos++] = ( byte ) ( ( minute / 10 ) + '0' );
821
822 result[pos++] = ( byte ) ( ( minute % 10 ) + '0' );
823
824
825 int fraction = 1000 * clonedCalendar.get( Calendar.SECOND )
826 + clonedCalendar.get( Calendar.MILLISECOND );
827 fraction /= 60;
828
829 if ( fraction > 0 )
830 {
831 if ( fractionDelimiter == FractionDelimiter.COMMA )
832 {
833 result[pos++] = ',';
834 }
835 else
836 {
837 result[pos++] = '.';
838 }
839
840
841 result[pos++] = ( byte ) ( ( fraction / 100 ) + '0' );
842 fraction %= 100;
843
844 if ( fraction > 0 )
845 {
846 result[pos++] = ( byte ) ( ( fraction / 10 ) + '0' );
847
848 if ( fraction > 0 )
849 {
850 result[pos++] = ( byte ) ( ( fraction % 10 ) + '0' );
851 }
852 }
853 }
854
855 break;
856
857 case YEAR_MONTH_DAY_HOUR:
858
859 break;
860
861 case YEAR_MONTH_DAY_HOUR_FRACTION:
862
863 fraction = 1000 * 60 * clonedCalendar.get( Calendar.MINUTE ) + 1000
864 * clonedCalendar.get( Calendar.SECOND )
865 + clonedCalendar.get( Calendar.MILLISECOND );
866 fraction /= 60 * 60;
867
868
869 if ( fraction > 0 )
870 {
871 if ( fractionDelimiter == FractionDelimiter.COMMA )
872 {
873 result[pos++] = ',';
874 }
875 else
876 {
877 result[pos++] = '.';
878 }
879
880 result[pos++] = ( byte ) ( ( fraction / 100 ) + '0' );
881 fraction %= 100;
882
883 if ( fraction > 0 )
884 {
885 result[pos++] = ( byte ) ( ( fraction / 10 ) + '0' );
886
887 if ( fraction > 0 )
888 {
889 result[pos++] = ( byte ) ( ( fraction % 10 ) + '0' );
890 }
891 }
892 }
893
894 break;
895
896 default:
897 throw new IllegalArgumentException( I18n.err( I18n.ERR_17069_UNEXPECTED_FORMAT, format ) );
898 }
899
900 if ( ( timeZoneFormat == TimeZoneFormat.Z ) && clonedCalendar.getTimeZone().hasSameRules( GMT ) )
901 {
902 result[pos++] = 'Z';
903 }
904 else
905 {
906
907 int offset = clonedCalendar.get( Calendar.ZONE_OFFSET ) + clonedCalendar.get( Calendar.DST_OFFSET );
908
909
910 if ( offset < 0 )
911 {
912 result[pos++] = '-';
913 }
914 else
915 {
916 result[pos++] = '+';
917 }
918
919 offset = Math.abs( offset );
920 hour = offset / ( 60 * 60 * 1000 );
921 int minute = ( offset - ( hour * 60 * 60 * 1000 ) ) / ( 1000 * 60 );
922
923
924 result[pos++] = ( byte ) ( ( hour / 10 ) + '0' );
925
926 result[pos++] = ( byte ) ( ( hour % 10 ) + '0' );
927
928 if ( ( timeZoneFormat == TimeZoneFormat.DIFF_HOUR_MINUTE ) || ( timeZoneFormat == TimeZoneFormat.Z ) )
929 {
930
931 result[pos++] = ( byte ) ( ( minute / 10 ) + '0' );
932
933 result[pos++] = ( byte ) ( ( minute % 10 ) + '0' );
934 }
935 }
936
937 return Strings.utf8ToString( result, 0, pos );
938 }
939
940
941
942
943
944
945
946
947 public Calendar getCalendar()
948 {
949 return calendar;
950 }
951
952
953
954
955
956 @Override
957 public String toString()
958 {
959 return toGeneralizedTime();
960 }
961
962
963
964
965
966 @Override
967 public int hashCode()
968 {
969 final int prime = 31;
970 int result = 1;
971 result = prime * result + calendar.hashCode();
972 return result;
973 }
974
975
976
977
978
979 @Override
980 public boolean equals( Object obj )
981 {
982 if ( obj instanceof GeneralizedTime )
983 {
984 GeneralizedTime other = ( GeneralizedTime ) obj;
985 return calendar.equals( other.calendar );
986 }
987 else
988 {
989 return false;
990 }
991 }
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004 @Override
1005 public int compareTo( GeneralizedTime other )
1006 {
1007 return calendar.compareTo( other.calendar );
1008 }
1009
1010
1011
1012
1013
1014 public long getTime()
1015 {
1016 return calendar.getTimeInMillis();
1017 }
1018
1019
1020
1021
1022
1023 public Date getDate()
1024 {
1025 return calendar.getTime();
1026 }
1027
1028
1029
1030
1031
1032 public int getYear()
1033 {
1034 return calendar.get( Calendar.YEAR );
1035 }
1036
1037
1038
1039
1040
1041 public int getMonth()
1042 {
1043 return calendar.get( Calendar.MONTH );
1044 }
1045
1046
1047
1048
1049
1050 public int getDay()
1051 {
1052 return calendar.get( Calendar.DATE );
1053 }
1054
1055
1056
1057
1058
1059 public int getHour()
1060 {
1061 return calendar.get( Calendar.HOUR_OF_DAY );
1062 }
1063
1064
1065
1066
1067
1068 public int getMinutes()
1069 {
1070 return calendar.get( Calendar.MINUTE );
1071 }
1072
1073
1074
1075
1076
1077 public int getSeconds()
1078 {
1079 return calendar.get( Calendar.SECOND );
1080 }
1081
1082
1083
1084
1085
1086 public int getFraction()
1087 {
1088 return calendar.get( Calendar.MILLISECOND );
1089 }
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099 public static Date getDate( String zuluTime ) throws ParseException
1100 {
1101 try
1102 {
1103 return new GeneralizedTime( zuluTime ).calendar.getTime();
1104 }
1105 catch ( ParseException pe )
1106 {
1107
1108 if ( "9223372036854775807".equals( zuluTime ) )
1109 {
1110
1111 return INFINITE;
1112 }
1113 else
1114 {
1115 throw pe;
1116 }
1117 }
1118 }
1119 }