KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > mail > RFC822Date


1 /*
2  * RFC822Date.java
3  *
4  * Copyright (C) 2000-2002 Peter Graves
5  * $Id: RFC822Date.java,v 1.1.1.1 2002/09/24 16:10:14 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j.mail;
23
24 import java.io.Serializable JavaDoc;
25 import java.text.SimpleDateFormat JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Calendar JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.Locale JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31 import java.util.TimeZone JavaDoc;
32 import org.armedbear.j.FastStringBuffer;
33 import org.armedbear.j.Utilities;
34
35 public final class RFC822Date implements Serializable JavaDoc
36 {
37     private Date JavaDoc date;
38
39     private RFC822Date()
40     {
41     }
42
43     public RFC822Date(Date JavaDoc date)
44     {
45         this.date = date;
46     }
47
48     public Date JavaDoc getDate()
49     {
50         return date;
51     }
52
53     public long getTime()
54     {
55         if (date != null)
56             return date.getTime();
57         return 0;
58     }
59
60     public static RFC822Date parseDate(String JavaDoc input)
61     {
62         if (input == null || input.length() == 0)
63             return new RFC822Date();
64         final StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(input, " ,");
65         final ArrayList JavaDoc tokens = new ArrayList JavaDoc();
66         while (st.hasMoreTokens())
67             tokens.add(st.nextToken());
68         final int tokenCount = tokens.size();
69         int month = -1;
70         int dayOfMonth = -1;
71         int year = -1;
72         int hour = -1;
73         int minute = -1;
74         int second = -1;
75         for (int i = 0; i < tokenCount; i++) {
76             String JavaDoc token = (String JavaDoc) tokens.get(i);
77             switch (token.charAt(0)) {
78                 case 'J':
79                     if (token.equals("Jan"))
80                         month = 0;
81                     else if (token.equals("Jun"))
82                         month = 5;
83                     else if (token.equals("Jul"))
84                         month = 6;
85                     break;
86                 case 'F':
87                     if (token.equals("Feb"))
88                         month = 1;
89                     break;
90                 case 'M':
91                     if (token.equals("Mar"))
92                         month = 2;
93                     else if (token.equals("May"))
94                         month = 4;
95                     break;
96                 case 'A':
97                     if (token.equals("Apr"))
98                         month = 3;
99                     else if (token.equals("Aug"))
100                         month = 7;
101                     break;
102                 case 'S':
103                     if (token.equals("Sep"))
104                         month = 8;
105                     break;
106                 case 'O':
107                     if (token.equals("Oct"))
108                         month = 9;
109                     break;
110                 case 'N':
111                     if (token.equals("Nov"))
112                         month = 10;
113                     break;
114                 case 'D':
115                     if (token.equals("Dec"))
116                         month = 11;
117                     break;
118             }
119             if (month >= 0) {
120                 tokens.set(i, null);
121                 if (i > 0) {
122                     String JavaDoc before = (String JavaDoc) tokens.get(i-1);
123                     try {
124                         dayOfMonth = Integer.parseInt(before);
125                     }
126                     catch (NumberFormatException JavaDoc e) {}
127                     if (dayOfMonth >= 1 && dayOfMonth <= 31) {
128                         tokens.set(i - 1, null);
129                         break;
130                     }
131                 }
132                 if (i < tokenCount - 1) {
133                     String JavaDoc after = (String JavaDoc) tokens.get(i+1);
134                     try {
135                         dayOfMonth = Integer.parseInt(after);
136                     }
137                     catch (NumberFormatException JavaDoc e) {}
138                     tokens.set(i + 1, null);
139                 }
140                 break;
141             }
142         }
143         // Year.
144
for (int i = 0; i < tokenCount; i++) {
145             String JavaDoc token = (String JavaDoc) tokens.get(i);
146             if (token == null)
147                 continue;
148             try {
149                 year = Integer.parseInt(token);
150             }
151             catch (NumberFormatException JavaDoc e) {}
152             if (year >= 1900 && year < 2100) {
153                 tokens.set(i, null);
154                 break;
155             }
156             year = -1;
157         }
158         if (year == -1) {
159             // Be slightly more permissive.
160
for (int i = 0; i < tokenCount; i++) {
161                 String JavaDoc token = (String JavaDoc) tokens.get(i);
162                 if (token == null)
163                     continue;
164                 try {
165                     year = Integer.parseInt(token);
166                 }
167                 catch (NumberFormatException JavaDoc e) {}
168                 if (year >= 0 && year < 200) {
169                     year += 1900;
170                     if (year < 1971) // There was no email before 1971.
171
year += 100;
172                     tokens.set(i, null);
173                     break;
174                 }
175             }
176         }
177         // Time.
178
for (int i = 0; i < tokenCount; i++) {
179             String JavaDoc token = (String JavaDoc) tokens.get(i);
180             if (token == null)
181                 continue;
182             int index = token.indexOf(':');
183             if (index < 0)
184                 continue;
185             try {
186                 hour = Integer.parseInt(token.substring(0, index));
187             }
188             catch (NumberFormatException JavaDoc e) {
189                 continue;
190             }
191             if (hour > 24)
192                 continue;
193             if (index + 1 >= token.length())
194                 continue;
195             if (!Character.isDigit(token.charAt(index + 1)))
196                 continue;
197             token = token.substring(index + 1);
198             try {
199                 minute = Utilities.parseInt(token);
200             }
201             catch (NumberFormatException JavaDoc e) {
202                 continue;
203             }
204             index = token.indexOf(':');
205             if (index >= 0) {
206                 token = token.substring(index + 1);
207                 try {
208                     second = Utilities.parseInt(token);
209                 }
210                 catch (NumberFormatException JavaDoc e) {}
211             }
212             tokens.set(i, null);
213             break;
214         }
215         // Time zone.
216
TimeZone JavaDoc tz = null;
217         for (int i = 0; i < tokenCount; i++) {
218             String JavaDoc token = (String JavaDoc) tokens.get(i);
219             if (token == null)
220                 continue;
221             if (token.length() == 5) {
222                 boolean maybe = true;
223                 char c = token.charAt(0);
224                 if (c == '-' || c == '+') {
225                     for (int j = 1; j <= 4; j++) {
226                         if (!Character.isDigit(token.charAt(j))) {
227                             maybe = false;
228                             break;
229                         }
230                     }
231                 }
232                 if (maybe) {
233                     tz = TimeZone.getTimeZone("GMT" + token);
234                     break;
235                 }
236             }
237         }
238         if (tz == null) {
239             for (int i = 0; i < tokenCount; i++) {
240                 String JavaDoc token = (String JavaDoc) tokens.get(i);
241                 if (token == null)
242                     continue;
243                 if (token.length() == 3) {
244                     if (token.charAt(2) != 'T')
245                         continue;
246                     if (token.charAt(0) < 'A' || token.charAt(0) > 'Z')
247                         continue;
248                     if (token.charAt(1) < 'A' || token.charAt(1) > 'Z')
249                         continue;
250                     if (token.charAt(1) == 'D') {
251                         // Java thinks PDT, EDT, etc. are the same as GMT.
252
// Pacific, Mountain, Central, Eastern.
253
if ("PMCE".indexOf(token.charAt(0)) >= 0) {
254                             switch (token.charAt(0)) {
255                                 case 'P':
256                                     token = "PST";
257                                     break;
258                                 case 'M':
259                                     token = "MST";
260                                     break;
261                                 case 'C':
262                                     token = "CST";
263                                     break;
264                                 case 'E':
265                                     token = "EST";
266                                     break;
267                             }
268                         }
269                     }
270                     tz = TimeZone.getTimeZone(token);
271                     if (tz != null)
272                         break;
273                 }
274             }
275         }
276         if (tz == null)
277             tz = TimeZone.getTimeZone("GMT+0000");
278         if (month < 0 || dayOfMonth < 0 || year < 0 || hour < 0 || minute < 0)
279             return new RFC822Date();
280         Calendar JavaDoc cal = Calendar.getInstance();
281         cal.setTimeZone(tz);
282         cal.set(year, month, dayOfMonth, hour, minute);
283         if (second >= 0)
284             cal.set(Calendar.SECOND, second);
285         return new RFC822Date(cal.getTime());
286     }
287
288     private static final SimpleDateFormat JavaDoc toStringFormat =
289         new SimpleDateFormat JavaDoc("EEE, dd MMM yyyy HH:mm:ss", Locale.US);
290
291     public String JavaDoc toString()
292     {
293         if (date == null)
294             return "null";
295         return toStringFormat.format(date);
296     }
297
298     public static int compare(RFC822Date date1, RFC822Date date2)
299     {
300         if (date1.date == null)
301             return -1;
302         if (date2.date == null)
303             return 1;
304         if (date1.date.before(date2.date))
305             return -1;
306         if (date1.date.after(date2.date))
307             return 1;
308         return 0;
309     }
310
311     public final boolean equals(RFC822Date d)
312     {
313         if (d == null)
314             return false;
315         else if (date == null)
316             return d.date == null;
317         else
318             return date.equals(d.date);
319     }
320
321     // Compares date only (i.e. ignores hours, minutes, seconds).
322
public boolean before(RFC822Date d)
323     {
324         if (date == null) {
325             if (d.date == null)
326                 return false;
327             else
328                 return true;
329         }
330         if (d.date == null)
331             return false;
332         int thisYear = date.getYear();
333         int otherYear = d.date.getYear();
334         if (thisYear < otherYear)
335             return true;
336         if (thisYear > otherYear)
337             return false;
338         // Same year.
339
int thisMonth = date.getMonth();
340         int otherMonth = d.date.getMonth();
341         if (thisMonth < otherMonth)
342             return true;
343         if (thisMonth > otherMonth)
344             return false;
345         // Same year and month.
346
return date.getDate() < d.date.getDate();
347     }
348
349     // Compares date only (i.e. ignores hours, minutes, seconds).
350
public boolean after(RFC822Date d)
351     {
352         if (date == null)
353             return false;
354         if (d.date == null)
355             return true;
356         int thisYear = date.getYear();
357         int otherYear = d.date.getYear();
358         if (thisYear > otherYear)
359             return true;
360         if (thisYear < otherYear)
361             return false;
362         // Same year.
363
int thisMonth = date.getMonth();
364         int otherMonth = d.date.getMonth();
365         if (thisMonth > otherMonth)
366             return true;
367         if (thisMonth < otherMonth)
368             return false;
369         // Same year and month.
370
return date.getDate() > d.date.getDate();
371     }
372
373     // Used only by getDateTimeString.
374
private static final SimpleDateFormat JavaDoc df = new SimpleDateFormat JavaDoc("EEE, d MMM yyyy HH:mm:ss ", Locale.US);
375
376     public static String JavaDoc getDateTimeString()
377     {
378         return getDateTimeString(Calendar.getInstance());
379     }
380
381     public static String JavaDoc getDateTimeString(Calendar JavaDoc calendar)
382     {
383         FastStringBuffer sb = new FastStringBuffer(48);
384         sb.append(df.format(calendar.getTime()));
385         int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
386         if (offset == 0) {
387             sb.append("+0000"); // '+' by convention.
388
} else {
389             if (offset < 0) {
390                 sb.append('-');
391                 offset = - offset;
392             }
393             int hours = offset / (60 * 60 * 1000);
394             if (hours >= 10) {
395                 sb.append(String.valueOf(hours));
396             } else {
397                 sb.append('0');
398                 sb.append(String.valueOf(hours));
399             }
400             int minutes = offset % (60 * 60 * 1000);
401             if (minutes >= 10) {
402                 sb.append(String.valueOf(minutes));
403             } else {
404                 sb.append('0');
405                 sb.append(String.valueOf(minutes));
406             }
407         }
408         return sb.toString();
409     }
410
411     public static final int getOffset(Calendar JavaDoc calendar)
412     {
413         return calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
414     }
415
416 // public static void main(String[] args)
417
// {
418
// String input = "7 Nov 00 14:32:06 IST";
419
// System.out.print(input + " ==> " );
420
// System.out.println(parseDate(input));
421
// input = "Sun, 12 Nov 00 14:58:09 EST";
422
// System.out.print(input + " ==> " );
423
// System.out.println(parseDate(input));
424
// input = "Thu, 28 Dec 2000 09:47:08 -0800";
425
// System.out.print(input + " ==> " );
426
// System.out.println(parseDate(input));
427
// }
428
}
429
Popular Tags