KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > mail > internet > MailDateFormat


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21
22 /*
23  * @(#)MailDateFormat.java 1.15 05/08/29
24  *
25  * Copyright 1993-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package javax.mail.internet;
29
30 import java.util.Date JavaDoc;
31 import java.util.Calendar JavaDoc;
32 import java.util.GregorianCalendar JavaDoc;
33 import java.util.Locale JavaDoc;
34 import java.util.TimeZone JavaDoc;
35 import java.text.DateFormat JavaDoc;
36 import java.text.SimpleDateFormat JavaDoc;
37 import java.text.NumberFormat JavaDoc;
38 import java.text.FieldPosition JavaDoc;
39 import java.text.ParsePosition JavaDoc;
40 import java.text.ParseException JavaDoc;
41
42 /**
43  * Formats and parses date specification based on the
44  * draft-ietf-drums-msg-fmt-08 dated January 26, 2000. This is a followup
45  * spec to RFC822.<p>
46  *
47  * This class does not take pattern strings. It always formats the
48  * date based on the specification below.<p>
49  *
50  * 3.3 Date and Time Specification<p>
51  *
52  * Date and time occur in several header fields of a message. This section
53  * specifies the syntax for a full date and time specification. Though folding
54  * whitespace is permitted throughout the date-time specification, it is
55  * recommended that only a single space be used where FWS is required and no
56  * space be used where FWS is optional in the date-time specification; some
57  * older implementations may not interpret other occurrences of folding
58  * whitespace correctly.<p>
59  *
60  * date-time = [ day-of-week "," ] date FWS time [CFWS]<p>
61  *
62  * day-of-week = ([FWS] day-name) / obs-day-of-week<p>
63  *
64  * day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"<p>
65  *
66  * date = day month year<p>
67  *
68  * year = 4*DIGIT / obs-year<p>
69  *
70  * month = (FWS month-name FWS) / obs-month<p>
71  *
72  *<pre>month-name = "Jan" / "Feb" / "Mar" / "Apr" /
73  * "May" / "Jun" / "Jul" / "Aug" /
74  * "Sep" / "Oct" / "Nov" / "Dec"
75  * </pre><p>
76  * day = ([FWS] 1*2DIGIT) / obs-day<p>
77  *
78  * time = time-of-day FWS zone<p>
79  *
80  * time-of-day = hour ":" minute [ ":" second ]<p>
81  *
82  * hour = 2DIGIT / obs-hour<p>
83  *
84  * minute = 2DIGIT / obs-minute<p>
85  *
86  * second = 2DIGIT / obs-second<p>
87  *
88  * zone = (( "+" / "-" ) 4DIGIT) / obs-zone<p>
89  *
90  *
91  * The day is the numeric day of the month. The year is any numeric year in
92  * the common era.<p>
93  *
94  * The time-of-day specifies the number of hours, minutes, and optionally
95  * seconds since midnight of the date indicated.<p>
96  *
97  * The date and time-of-day SHOULD express local time.<p>
98  *
99  * The zone specifies the offset from Coordinated Universal Time (UTC,
100  * formerly referred to as "Greenwich Mean Time") that the date and
101  * time-of-day represent. The "+" or "-" indicates whether the time-of-day is
102  * ahead of or behind Universal Time. The first two digits indicate the number
103  * of hours difference from Universal Time, and the last two digits indicate
104  * the number of minutes difference from Universal Time. (Hence, +hhmm means
105  * +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm) minutes). The form
106  * "+0000" SHOULD be used to indicate a time zone at Universal Time. Though
107  * "-0000" also indicates Universal Time, it is used to indicate that the time
108  * was generated on a system that may be in a local time zone other than
109  * Universal Time.<p>
110  *
111  * A date-time specification MUST be semantically valid. That is, the
112  * day-of-the week (if included) MUST be the day implied by the date, the
113  * numeric day-of-month MUST be between 1 and the number of days allowed for
114  * the specified month (in the specified year), the time-of-day MUST be in the
115  * range 00:00:00 through 23:59:60 (the number of seconds allowing for a leap
116  * second; see [STD-12]), and the zone MUST be within the range -9959 through
117  * +9959.<p>
118  *
119  * @author Max Spivak
120  * @since JavaMail 1.2
121  */

122
123 public class MailDateFormat extends SimpleDateFormat JavaDoc {
124
125     private static final long serialVersionUID = -8148227605210628779L;
126
127     public MailDateFormat() {
128     super("EEE, d MMM yyyy HH:mm:ss 'XXXXX' (z)", Locale.US);
129     }
130
131     /**
132      * Formats the given date in the format specified by
133      * draft-ietf-drums-msg-fmt-08 in the current TimeZone.
134      *
135      * @param date the Date object
136      * @param dateStrBuf the formatted string
137      * @param fieldPosition the current field position
138      * @return StringBuffer the formatted String
139      * @since JavaMail 1.2
140      */

141     public StringBuffer JavaDoc format(Date JavaDoc date, StringBuffer JavaDoc dateStrBuf,
142                    FieldPosition JavaDoc fieldPosition) {
143
144     /* How this method works: First format the date with the
145      * format specified in the constructor inserting string 'XXXXX'
146      * where the timezone offset goes. Find where in the string the
147      * string 'XXXXX' appears and remember that in var "pos".
148      * Calculate the offset, taking the DST into account and insert
149      * it into the stringbuffer at position pos.
150      */

151
152     int start = dateStrBuf.length();
153     super.format(date, dateStrBuf, fieldPosition);
154     int pos = 0;
155     // find the beginning of the 'XXXXX' string in the formatted date
156
// 25 is the first position that we expect to find XXXXX at
157
for (pos = start + 25; dateStrBuf.charAt(pos) != 'X'; pos++)
158         ;
159
160     // set the timezone to +HHMM or -HHMM
161
calendar.clear();
162     calendar.setTime(date);
163     int offset = calendar.get(Calendar.ZONE_OFFSET) +
164             calendar.get(Calendar.DST_OFFSET);
165     // take care of the sign
166
if (offset < 0) {
167         dateStrBuf.setCharAt(pos++, '-');
168         offset = (-offset);
169     } else
170         dateStrBuf.setCharAt(pos++, '+');
171
172     int rawOffsetInMins = offset / 60 / 1000; // offset from GMT in mins
173
int offsetInHrs = rawOffsetInMins / 60;
174     int offsetInMins = rawOffsetInMins % 60;
175
176     dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs/10), 10));
177     dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs%10), 10));
178     dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins/10), 10));
179     dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins%10), 10));
180     // done with timezone
181

182     return dateStrBuf;
183     }
184
185     ////////////////////////////////////////////////////////////
186

187     /**
188      * Parses the given date in the format specified by
189      * draft-ietf-drums-msg-fmt-08 in the current TimeZone.
190      *
191      * @param text the formatted date to be parsed
192      * @param pos the current parse position
193      * @return Date the parsed date in a Date object
194      * @since JavaMail 1.2
195      */

196     public Date JavaDoc parse(String JavaDoc text, ParsePosition JavaDoc pos) {
197     return parseDate(text.toCharArray(), pos, isLenient());
198     }
199
200     /*
201       Valid Examples:
202       
203       Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)
204       Date:
205       Date: Mon, 22 Mar 1993 09:41:09 -0800 (PST)
206       Date: 26 Aug 76 14:29 EDT
207
208       */

209     
210     /**
211      * method of what to look for:
212      *
213      *
214      * skip WS
215      * skip day "," (this is "Mon", "Tue")
216      * skip WS
217      *
218      * parse number (until WS) ==> 1*2DIGIT (day of month)
219      *
220      * skip WS
221      *
222      * parse alpha chars (until WS) ==> find month
223      *
224      * skip WS
225      *
226      * parse number (until WS) ==> 2*4DIGIT (year)
227      *
228      * skip WS
229      *
230      * // now looking for time
231      * parse number (until ':') ==> hours
232      * parse number (until ':') ==> minutes
233      * parse number (until WS) ==> seconds
234      *
235      * // now look for Time Zone
236      * skip WS
237      * if ('+' or '-') then numerical time zone offset
238      * if (alpha) then alpha time zone offset
239      */

240
241     static boolean debug = false;
242
243     /**
244      * create a Date by parsing the char array
245      */

246     static private Date JavaDoc parseDate(char[] orig, ParsePosition JavaDoc pos,
247                 boolean lenient) {
248     try {
249         int day = -1;
250         int month = -1;
251         int year = -1;
252         int hours = 0;
253         int minutes = 0;
254         int seconds = 0;
255         int offset = 0;
256         
257             
258         MailDateParser p = new MailDateParser(orig);
259             
260         // get the day
261
p.skipUntilNumber();
262         day = p.parseNumber();
263
264         if (!p.skipIfChar('-')) { // for IMAP internal Date
265
p.skipWhiteSpace();
266         }
267
268         // get the month
269
month = p.parseMonth();
270         if (!p.skipIfChar('-')) { // for IMAP internal Date
271
p.skipWhiteSpace();
272         }
273         
274         // get the year
275
year = p.parseNumber(); // should not return a negative number
276
if (year < 50) {
277         year += 2000;
278         } else if (year < 100) {
279         year += 1900;
280         } // otherwise the year is correct (and should be 4 digits)
281

282             
283         // get the time
284
// first get hours
285
p.skipWhiteSpace();
286         hours = p.parseNumber();
287             
288         // get minutes
289
p.skipChar(':');
290         minutes = p.parseNumber();
291         
292         // get seconds (may be no seconds)
293
if (p.skipIfChar(':')) {
294         seconds = p.parseNumber();
295         }
296         
297             
298         // try to get a Time Zone
299
try {
300         p.skipWhiteSpace();
301         offset = p.parseTimeZone();
302         } catch (ParseException JavaDoc pe) {
303         if (debug) {
304             System.out.println("No timezone? : '" + orig + "'");
305         }
306         }
307             
308         pos.setIndex(p.getIndex());
309         Date JavaDoc d = ourUTC(year, month, day, hours, minutes, seconds, offset,
310                             lenient);
311         return d;
312
313     } catch (Exception JavaDoc e) {
314         // Catch *all* exceptions, including RuntimeExceptions like
315
// ArrayIndexOutofBoundsException ... we need to be
316
// extra tolerant of all those bogus dates that might screw
317
// up our parser. Sigh.
318

319         if (debug) {
320         System.out.println("Bad date: '" + orig + "'");
321         e.printStackTrace();
322         }
323         pos.setIndex(1); // to prevent DateFormat.parse() from throwing ex
324
return null;
325     }
326     }
327     
328     private static TimeZone JavaDoc tz = TimeZone.getTimeZone("GMT");
329     private static Calendar JavaDoc cal = new GregorianCalendar JavaDoc(tz);
330     private synchronized static Date JavaDoc ourUTC(int year, int mon, int mday,
331                        int hour, int min, int sec,
332                        int tzoffset, boolean lenient) {
333     // clear the time and then set all the values
334
cal.clear();
335     cal.setLenient(lenient);
336     cal.set(Calendar.YEAR, year);
337     cal.set(Calendar.MONTH, mon);
338     cal.set(Calendar.DATE, mday);
339     cal.set(Calendar.HOUR_OF_DAY, hour);
340     cal.set(Calendar.MINUTE, min + tzoffset); // adjusted for the timezone
341
cal.set(Calendar.SECOND, sec);
342
343     return cal.getTime();
344     }
345
346
347     ////////////////////////////////////////////////////////////
348

349     /** Don't allow setting the calendar */
350     public void setCalendar(Calendar JavaDoc newCalendar) {
351     throw new RuntimeException JavaDoc("Method setCalendar() shouldn't be called");
352     }
353
354     /** Don't allow setting the NumberFormat */
355     public void setNumberFormat(NumberFormat JavaDoc newNumberFormat) {
356     throw new RuntimeException JavaDoc("Method setNumberFormat() shouldn't be called");
357     }
358     
359
360     /* test code for MailDateFormat */
361     /*
362     public static void main(String[] args) {
363     DateFormat df = new MailDateFormat();
364     Date d = new Date();
365
366     // test output in all the timezones
367     System.out.println("------- test all timezones ---------------");
368     System.out.println("Current date: " + d);
369     String[] allIDs = TimeZone.getAvailableIDs();
370     for (int i = 0; i < allIDs.length; i++) {
371         TimeZone tz = TimeZone.getTimeZone(allIDs[i]);
372         df.setTimeZone(tz);
373         System.out.println("Date in " + tz.getID() + ": " +
374                    df.format(new Date()));
375     }
376     try {
377         System.out.println(df.parse("Sun, 21 Mar 1993 23:56:48 -0800 (PST)"));
378     System.out.println(df.parse("Mon, 22 Mar 1994 13:34:51 +0000"));
379     System.out.println(df.parse("26 Aug 76 14:29 EDT"));
380     System.out.println(df.parse("15 Apr 11 23:49 EST"));
381     System.out.println(df.parse("15 Apr 11 23:49 ABC"));
382     } catch (ParseException pex) {
383         pex.printStackTrace();
384     }
385
386     // reset DateFormat TZ
387     df.setTimeZone(TimeZone.getDefault());
388
389     // test all days in a month
390     System.out.println();
391     System.out.println("------- test all days in a month ---------------");
392     Calendar cal = Calendar.getInstance();
393     cal.set(Calendar.YEAR, 1972);
394     cal.set(Calendar.MONTH, Calendar.OCTOBER);
395     cal.set(Calendar.DATE, 1);
396     cal.set(Calendar.HOUR, 10);
397     cal.set(Calendar.MINUTE, 50);
398     cal.set(Calendar.AM_PM, Calendar.PM);
399     System.out.println("Initial Date: " + cal.getTime());
400     System.out.println("Current Date: " + df.format(cal.getTime()));
401     for (int i = 0; i < 30; i++) {
402         cal.roll(Calendar.DATE, true);
403         System.out.println("Current Date: " + df.format(cal.getTime()));
404     }
405
406     // test all months
407     System.out.println();
408     System.out.println("------- test all months in a year -----------");
409     cal.set(Calendar.MONTH, Calendar.JANUARY);
410     cal.set(Calendar.DATE, 7);
411     System.out.println("Initial Date: " + cal.getTime());
412     System.out.println("Current Date: " + df.format(cal.getTime()));
413     for (int i = 1; i < 12; i++) {
414         cal.roll(Calendar.MONTH, true);
415         System.out.println("Current Date: " + df.format(cal.getTime()));
416     }
417
418     // test leap years
419     System.out.println();
420     System.out.println("------- test leap years -----------");
421     cal.set(Calendar.YEAR, 1999);
422     cal.set(Calendar.MONTH, Calendar.JANUARY);
423     cal.set(Calendar.DATE, 31);
424     cal.roll(Calendar.MONTH, true);
425     System.out.println("Initial Date: " + cal.getTime());
426     System.out.println("Current Date: " + df.format(cal.getTime()));
427     for (int i = 1; i < 12; i++) {
428         cal.set(Calendar.MONTH, Calendar.JANUARY);
429         cal.set(Calendar.DATE, 31);
430         cal.roll(Calendar.YEAR, true);
431         cal.roll(Calendar.MONTH, true);
432         System.out.println("Current Date: " + df.format(cal.getTime()));
433     }
434     }
435     */

436
437 }
438
439 /**
440  * Helper class to deal with parsing the characters
441  */

442 class MailDateParser {
443     
444     int index = 0;
445     char[] orig = null;
446
447     public MailDateParser(char[] orig) {
448     this.orig = orig;
449     }
450
451     /**
452      * skips chars until it finds a number (0-9)
453      *
454      * if it does not find a number, it will throw
455      * an ArrayIndexOutOfBoundsException
456      */

457     public void skipUntilNumber() throws ParseException JavaDoc {
458     try {
459         while (true) {
460         switch ( orig[index] ) {
461         case '0':
462         case '1':
463         case '2':
464         case '3':
465         case '4':
466         case '5':
467         case '6':
468         case '7':
469         case '8':
470         case '9':
471             return;
472                 
473         default:
474             index++;
475             break;
476         }
477         }
478     } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
479         throw new ParseException JavaDoc("No Number Found", index);
480     }
481     }
482
483     /**
484      * skips any number of tabs, spaces, CR, and LF - folding whitespace
485      */

486     public void skipWhiteSpace() {
487     int len = orig.length;
488     while (index < len) {
489         switch (orig[index]) {
490         case ' ': // space
491
case '\t': // tab
492
case '\r': // CR
493
case '\n': // LF
494
index++;
495         break;
496                     
497         default:
498         return;
499         }
500     }
501     }
502
503
504     /**
505      * used to look at the next character without "parsing" that
506      * character.
507      */

508     public int peekChar() throws ParseException JavaDoc {
509     if (index < orig.length)
510         return orig[index];
511     else
512         throw new ParseException JavaDoc("No more characters", index);
513     }
514     
515     /**
516      * skips the given character. if the current char does not
517      * match a ParseException will be thrown
518      */

519     public void skipChar(char c) throws ParseException JavaDoc {
520     if (index < orig.length) {
521         if (orig[index] == c) {
522         index++;
523         } else {
524         throw new ParseException JavaDoc("Wrong char", index);
525         }
526     } else {
527         throw new ParseException JavaDoc("No more characters", index);
528     }
529     }
530
531     /**
532      * will only skip the current char if it matches the given
533      * char
534      */

535     public boolean skipIfChar(char c) throws ParseException JavaDoc {
536     if (index < orig.length) {
537         if (orig[index] == c) {
538         index++;
539         return true;
540         } else {
541         return false;
542         }
543     } else {
544         throw new ParseException JavaDoc("No more characters", index);
545     }
546     }
547     
548
549     /**
550      * current char must point to a number. the number will be
551      * parsed and the resulting number will be returned. if a
552      * number is not found, a ParseException will be thrown
553      */

554     public int parseNumber() throws ParseException JavaDoc {
555     int length = orig.length;
556     boolean gotNum = false;
557     int result = 0;
558                 
559     while (index < length) {
560         switch( orig[index] ) {
561         case '0':
562             result *= 10;
563             gotNum = true;
564             break;
565             
566         case '1':
567             result = result * 10 + 1;
568             gotNum = true;
569             break;
570             
571         case '2':
572             result = result * 10 + 2;
573             gotNum = true;
574             break;
575             
576         case '3':
577             result = result * 10 + 3;
578             gotNum = true;
579             break;
580             
581         case '4':
582             result = result * 10 + 4;
583             gotNum = true;
584             break;
585             
586         case '5':
587             result = result * 10 + 5;
588             gotNum = true;
589             break;
590             
591         case '6':
592             result = result * 10 + 6;
593             gotNum = true;
594             break;
595             
596         case '7':
597             result = result * 10 + 7;
598             gotNum = true;
599             break;
600             
601         case '8':
602             result = result * 10 + 8;
603             gotNum = true;
604             break;
605             
606         case '9':
607             result = result * 10 + 9;
608             gotNum = true;
609             break;
610     
611         default:
612             if (gotNum)
613             return result;
614             else
615             throw new ParseException JavaDoc("No Number found", index);
616         }
617         
618         index++;
619     }
620         
621     // check the result
622
if (gotNum)
623         return result;
624             
625     // else, throw a parse error
626
throw new ParseException JavaDoc("No Number found", index);
627     }
628     
629
630     /**
631      * will look for one of "Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dev"
632      * and return the numerical version of the month. (0-11). a ParseException
633      * error is thrown if a month cannot be found.
634      */

635     public int parseMonth() throws ParseException JavaDoc {
636     char curr;
637         
638     try {
639         switch(orig[index++]) {
640         case 'J':
641         case 'j': // "Jan" (0) / "Jun" (5) / "Jul" (6)
642
// check next char
643
switch(orig[index++]) {
644         case 'A':
645         case 'a':
646             curr = orig[index++];
647             if (curr == 'N' || curr == 'n') {
648             return 0;
649             }
650             break;
651                             
652         case 'U':
653         case 'u':
654             curr = orig[index++];
655             if (curr == 'N' || curr == 'n') {
656             return 5;
657             } else if (curr == 'L' || curr == 'l') {
658             return 6;
659             }
660             break;
661         }
662         break;
663                 
664         case 'F':
665         case 'f': // "Feb"
666
curr = orig[index++];
667         if (curr == 'E' || curr == 'e') {
668             curr = orig[index++];
669             if (curr == 'B' || curr == 'b') {
670             return 1;
671             }
672         }
673         break;
674                 
675         case 'M':
676         case 'm': // "Mar" (2) / "May" (4)
677
curr = orig[index++];
678         if (curr == 'A' || curr == 'a') {
679             curr = orig[index++];
680             if (curr == 'R' || curr == 'r') {
681             return 2;
682             } else if (curr == 'Y' || curr == 'y') {
683             return 4;
684             }
685         }
686         break;
687                 
688         case 'A':
689         case 'a': // "Apr" (3) / "Aug" (7)
690
curr = orig[index++];
691         if (curr == 'P' || curr == 'p') {
692             curr = orig[index++];
693             if (curr == 'R' || curr == 'r') {
694             return 3;
695             }
696         } else if (curr == 'U' || curr == 'u') {
697             curr = orig[index++];
698             if (curr == 'G' || curr == 'g') {
699             return 7;
700             }
701         }
702         break;
703                 
704         case 'S':
705         case 's': // "Sep" (8)
706
curr = orig[index++];
707         if (curr == 'E' || curr == 'e') {
708             curr = orig[index++];
709             if (curr == 'P' || curr == 'p') {
710             return 8;
711             }
712         }
713         break;
714                 
715         case 'O':
716         case 'o': // "Oct"
717
curr = orig[index++];
718         if (curr == 'C' || curr == 'c') {
719             curr = orig[index++];
720             if (curr == 'T' || curr == 't') {
721             return 9;
722             }
723         }
724         break;
725                 
726         case 'N':
727         case 'n': // "Nov"
728
curr = orig[index++];
729         if (curr == 'O' || curr == 'o') {
730             curr = orig[index++];
731             if (curr == 'V' || curr == 'v') {
732             return 10;
733             }
734         }
735         break;
736
737         case 'D':
738         case 'd': // "Dec"
739
curr = orig[index++];
740         if (curr == 'E' || curr == 'e') {
741             curr = orig[index++];
742             if (curr == 'C' || curr == 'c') {
743             return 11;
744             }
745         }
746         break;
747         }
748     } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
749     }
750         
751     throw new ParseException JavaDoc("Bad Month", index);
752     }
753     
754     /**
755      * will parse the timezone - either Numerical version (e.g. +0800, -0500)
756      * or the alpha version (e.g. PDT, PST). the result will be returned in
757      * minutes needed to be added to the date to bring it to GMT.
758      */

759     public int parseTimeZone() throws ParseException JavaDoc {
760     if (index >= orig.length)
761         throw new ParseException JavaDoc("No more characters", index);
762         
763     char test = orig[index];
764     if ( test == '+' || test == '-' ) {
765         return parseNumericTimeZone();
766     } else {
767         return parseAlphaTimeZone();
768     }
769     }
770
771     
772     /**
773      * will parse the Numerical time zone version (e.g. +0800, -0500)
774      * the result will be returned in minutes needed to be added
775      * to the date to bring it to GMT.
776      */

777     public int parseNumericTimeZone() throws ParseException JavaDoc {
778     // we switch the sign if it is a '+'
779
// since the time in the string we are
780
// parsing is off from GMT by that amount.
781
// and we want to get the time back into
782
// GMT, so we substract it.
783
boolean switchSign = false;
784     char first = orig[index++];
785     if (first == '+') {
786         switchSign = true;
787     } else if (first != '-') {
788         throw new ParseException JavaDoc("Bad Numeric TimeZone", index);
789     }
790         
791     int tz = parseNumber();
792     int offset = (tz / 100) * 60 + (tz % 100);
793     if (switchSign) {
794         return -offset;
795     } else {
796         return offset;
797     }
798     }
799
800     /**
801      * will parse the alpha time zone version (e.g. PDT, PST).
802      * the result will be returned in minutes needed to be added
803      * to the date to bring it to GMT.
804      */

805     public int parseAlphaTimeZone() throws ParseException JavaDoc {
806     int result = 0;
807     boolean foundCommon = false;
808     char curr;
809         
810     try {
811         switch(orig[index++]) {
812         case 'U':
813         case 'u': // "UT" / Universal Time
814
curr = orig[index++];
815         if (curr == 'T' || curr == 't') {
816             result = 0;
817             break;
818         }
819         throw new ParseException JavaDoc("Bad Alpha TimeZone", index);
820                     
821         case 'G':
822         case 'g': // "GMT" ; Universal Time
823
curr = orig[index++];
824         if (curr == 'M' || curr == 'm') {
825             curr = orig[index++];
826             if (curr == 'T' || curr == 't') {
827             result = 0;
828             break;
829             }
830         }
831         throw new ParseException JavaDoc("Bad Alpha TimeZone", index);
832                     
833         case 'E':
834         case 'e': // "EST" / "EDT" ; Eastern: - 5/ - 4
835
result = 300;
836         foundCommon = true;
837         break;
838                     
839         case 'C':
840         case 'c': // "CST" / "CDT" ; Central: - 6/ - 5
841
result = 360;
842         foundCommon = true;
843         break;
844                     
845         case 'M':
846         case 'm': // "MST" / "MDT" ; Mountain: - 7/ - 6
847
result = 420;
848         foundCommon = true;
849         break;
850                     
851         case 'P':
852         case 'p': // "PST" / "PDT" ; Pacific: - 8/ - 7
853
result = 480;
854         foundCommon = true;
855         break;
856
857         default:
858         throw new ParseException JavaDoc("Bad Alpha TimeZone", index);
859         }
860     } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
861         throw new ParseException JavaDoc("Bad Alpha TimeZone", index);
862     }
863         
864     if (foundCommon) {
865         curr = orig[index++];
866         if (curr == 'S' || curr == 's') {
867         curr = orig[index++];
868         if (curr != 'T' && curr != 't') {
869             throw new ParseException JavaDoc("Bad Alpha TimeZone", index);
870         }
871         } else if (curr == 'D' || curr == 'd') {
872         curr = orig[index++];
873         if (curr == 'T' || curr != 't') {
874             // for daylight time
875
result -= 60;
876         } else {
877             throw new ParseException JavaDoc("Bad Alpha TimeZone", index);
878         }
879         }
880     }
881
882     return result;
883     }
884
885     int getIndex() {
886     return index;
887     }
888 }
889
Popular Tags