KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > ristretto > parser > DateParser


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Ristretto Mail API.
15  *
16  * The Initial Developers of the Original Code are
17  * Timo Stich and Frederik Dietz.
18  * Portions created by the Initial Developers are Copyright (C) 2004
19  * All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */

36 package org.columba.ristretto.parser;
37
38 import java.util.Date JavaDoc;
39 import java.util.TimeZone JavaDoc;
40 import java.util.regex.Matcher JavaDoc;
41 import java.util.regex.Pattern JavaDoc;
42
43 /**
44  * Parser for dates as defined in RFC 2822.
45  *
46  * @author Timo Stich <tstich@users.sourceforge.net>
47  */

48 public class DateParser {
49     private static final long[] monthOffset = { 0l, // Jan
50
2678400000l, // Feb
51
5097600000l, // Mar
52
7776000000l, // Apr
53
10368000000l, // May
54
13046400000l, // Jun
55
15638400000l, // Jul
56
18316800000l, // Aug
57
20995200000l, // Sep
58
23587200000l, // Oct
59
26265600000l, // Nov
60
28857600000l // Dec
61
};
62
63     private static final Pattern JavaDoc stringPattern = Pattern
64             .compile("(\\w{3})\\w*");
65
66     private static final Pattern JavaDoc numberPattern = Pattern
67             .compile("(\\d{1,4})");
68
69     private static final Pattern JavaDoc timePattern = Pattern
70             .compile("(\\d\\d):(\\d\\d)(:(\\d\\d))?");
71
72     private static final Pattern JavaDoc timezonePattern = Pattern
73             .compile("((\\+|-)(\\d\\d)(\\d\\d))|(\\\"?(\\w+)\\\"?)");
74
75     private DateParser() {
76     }
77
78     private static int getMonth(String JavaDoc month) {
79         String JavaDoc loweredMonth = month.toLowerCase();
80         char startChar = loweredMonth.charAt(0);
81
82         switch (startChar) {
83         case 'j': {
84             if (loweredMonth.equals("jan"))
85                 return 0;
86             if (loweredMonth.equals("jun"))
87                 return 5;
88             if (loweredMonth.equals("jul"))
89                 return 6;
90         }
91         case 'f': {
92             if (loweredMonth.equals("feb"))
93                 return 1;
94         }
95         case 'm': {
96             if (loweredMonth.equals("mar"))
97                 return 2;
98             if (loweredMonth.equals("may"))
99                 return 4;
100         }
101         case 'a': {
102             if (loweredMonth.equals("apr"))
103                 return 3;
104             if (loweredMonth.equals("aug"))
105                 return 7;
106         }
107         case 's': {
108             if (loweredMonth.equals("sep"))
109                 return 8;
110         }
111         case 'o': {
112             if (loweredMonth.equals("oct"))
113                 return 9;
114         }
115         case 'n': {
116             if (loweredMonth.equals("nov"))
117                 return 10;
118         }
119         case 'd': {
120             if (loweredMonth.equals("dec"))
121                 return 11;
122         }
123         }
124
125         return -1;
126     }
127
128     private static long getLeapYearCorrection(int day, int month, int year) {
129         int normalizedYear = year - 1972;
130         if (day <= 29 && month < 2)
131             normalizedYear -= 1;
132
133         int leapYears = normalizedYear / 4;
134
135         return 86400000l * leapYears;
136     }
137
138     /**
139      * Parses a date String as specified in RFC 2822.
140      *
141      * @param dateString
142      * CharSequence of the Date to parse
143      * @return parsed Date
144      * @throws ParserException
145      */

146     public static Date JavaDoc parse(CharSequence JavaDoc dateString) throws ParserException {
147         String JavaDoc temp = dateString.toString();
148         
149         Matcher JavaDoc matcher;
150
151         // retrieve date
152
matcher = stringPattern.matcher(temp);
153         int month = -1;
154         while (month == -1 && matcher.find() ) {
155             month = getMonth(matcher.group(1));
156             temp = temp.substring(0,matcher.start()) + temp.substring(matcher.end());
157
158             matcher = stringPattern.matcher(temp);
159         }
160         if (month == -1)
161             throw new ParserException("Invalid Date: " + dateString);
162
163
164         matcher = timePattern.matcher(temp);
165         if (!matcher.find())
166             throw new ParserException("Invalid Date: " + dateString);
167         temp = temp.substring(0,matcher.start()) + temp.substring(matcher.end());
168
169         // retrieve time
170
int hours = Integer.parseInt(matcher.group(1));
171         int minutes = Integer.parseInt(matcher.group(2));
172         int seconds = 0;
173         if (matcher.group(3) != null) {
174             seconds = Integer.parseInt(matcher.group(4));
175         }
176
177         
178         // retrieve day in month and year
179
matcher = numberPattern.matcher(temp);
180
181         if (!matcher.find())
182             throw new ParserException("Invalid Date: " + dateString);
183         int day = Integer.parseInt(matcher.group());
184         temp = temp.substring(0,matcher.start()) + temp.substring(matcher.end());
185
186         matcher = numberPattern.matcher(temp);
187         if (!matcher.find())
188             throw new ParserException("Invalid Date: " + dateString);
189         int year = Integer.parseInt(matcher.group());
190         if (year < 99) {
191             if (year < 49)
192                 year += 2000;
193             else
194                 year += 1900;
195         }
196         temp = temp.substring(0,matcher.start()) + temp.substring(matcher.end());
197
198         // calculate Milliseconds from 1.1.1970 00:00:00 GMT
199
long date = seconds * 1000l + minutes * 60000l + hours * 3600000l + day
200                 * 86400000l + monthOffset[month] + (year - 1970) * 31536000000l
201                 + getLeapYearCorrection(day, month, year);
202
203         // Make timezone corrections
204
matcher = timezonePattern.matcher(temp);
205         long zoneoffset = 0;
206         if (matcher.find()) {
207             if (matcher.group(1) != null) {
208                 zoneoffset = Integer.parseInt(matcher.group(4)) * 60000l
209                         + Integer.parseInt(matcher.group(3)) * 3600000l;
210                 if (matcher.group(2).equals("+")) {
211                     zoneoffset = -zoneoffset;
212                 }
213             } else if (matcher.group(6) != null) {
214                 TimeZone JavaDoc timezone = TimeZone.getTimeZone(matcher.group(6));
215                 zoneoffset = timezone.getOffset(date);
216             }
217         }
218         date += zoneoffset;
219
220         // return parsed date
221
return new Date JavaDoc(date);
222     }
223 }
224
Popular Tags