1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.sun.syndication.io.impl;
18
19 import java.text.DateFormat;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.TimeZone;
23
24 /***
25 * A helper class that parses Dates out of Strings with date time in RFC822 and W3CDateTime
26 * formats plus the variants Atom (0.3) and RSS (0.9, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0)
27 * specificators added to those formats.
28 * <p/>
29 * It uses the JDK java.text.SimpleDateFormat class attemtping the parse using a mask for
30 * each one of the possible formats.
31 * <p/>
32 *
33 * @author Alejandro Abdelnur
34 *
35 */
36 public class DateParser {
37
38
39
40
41 private static final String[] RFC822_MASKS = {
42 "EEE, dd MMM yyyy HH:mm:ss z",
43 "EEE, dd MMM yyyy HH:mm z",
44 "EEE, dd MMM yy HH:mm:ss z",
45 "EEE, dd MMM yy HH:mm z",
46 "dd MMM yyyy HH:mm:ss z",
47 "dd MMM yyyy HH:mm z",
48 "dd MMM yy HH:mm:ss z",
49 "dd MMM yy HH:mm z"
50 };
51
52
53
54
55 private static final String[] W3CDATETIME_MASKS = {
56 "yyyy-MM-dd'T'HH:mm:ssz",
57 "yyyy-MM-dd'T'HH:mmz",
58 "yyyy-MM-dd",
59 "yyyy-MM",
60 "yyyy"
61 };
62
63 /***
64 * Private constructor to avoid DateParser instances creation.
65 */
66 private DateParser() {
67 }
68
69 /***
70 * Parses a Date out of a string using an array of masks.
71 * <p/>
72 * It uses the masks in order until one of them succedes or all fail.
73 * <p/>
74 *
75 * @param masks array of masks to use for parsing the string
76 * @param sDate string to parse for a date.
77 * @return the Date represented by the given string using one of the given masks.
78 * It returns <b>null</b> if it was not possible to parse the the string with any of the masks.
79 *
80 */
81 private static Date parseUsingMask(String[] masks,String sDate) {
82 Date d = null;
83 for (int i=0;d==null && i<masks.length;i++) {
84 DateFormat df = new SimpleDateFormat(masks[i]);
85 df.setLenient(true);
86 try {
87 d = df.parse(sDate);
88
89 }
90 catch (Exception ex1) {
91
92 }
93 }
94 return d;
95 }
96
97 /***
98 * Parses a Date out of a String with a date in RFC822 format.
99 * <p/>
100 * It parsers the following formats:
101 * <ul>
102 * <li>"EEE, dd MMM yyyy HH:mm:ss z"</li>
103 * <li>"EEE, dd MMM yyyy HH:mm z"</li>
104 * <li>"EEE, dd MMM yy HH:mm:ss z"</li>
105 * <li>"EEE, dd MMM yy HH:mm z"</li>
106 * <li>"dd MMM yyyy HH:mm:ss z"</li>
107 * <li>"dd MMM yyyy HH:mm z"</li>
108 * <li>"dd MMM yy HH:mm:ss z"</li>
109 * <li>"dd MMM yy HH:mm z"</li>
110 * </ul>
111 * <p/>
112 * Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
113 * <p/>
114 * @param sDate string to parse for a date.
115 * @return the Date represented by the given RFC822 string.
116 * It returns <b>null</b> if it was not possible to parse the given string into a Date.
117 *
118 */
119 public static Date parseRFC822(String sDate) {
120 return parseUsingMask(RFC822_MASKS,sDate);
121 }
122
123
124 /***
125 * Parses a Date out of a String with a date in W3C date-time format.
126 * <p/>
127 * It parsers the following formats:
128 * <ul>
129 * <li>"yyyy-MM-dd'T'HH:mm:ssz"</li>
130 * <li>"yyyy-MM-dd'T'HH:mmz"</li>
131 * <li>"yyyy-MM-dd"</li>
132 * <li>"yyyy-MM"</li>
133 * <li>"yyyy"</li>
134 * </ul>
135 * <p/>
136 * Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
137 * <p/>
138 * @param sDate string to parse for a date.
139 * @return the Date represented by the given W3C date-time string.
140 * It returns <b>null</b> if it was not possible to parse the given string into a Date.
141 *
142 */
143 public static Date parseW3CDateTime(String sDate) {
144
145
146 int tIndex = sDate.indexOf("T");
147 if (tIndex>-1) {
148 if (sDate.endsWith("Z")) {
149 sDate = sDate.substring(0,sDate.length()-1)+"+00:00";
150 }
151 int tzdIndex = sDate.indexOf("+",tIndex);
152 if (tzdIndex==-1) {
153 tzdIndex = sDate.indexOf("-",tIndex);
154 }
155 if (tzdIndex>-1) {
156 String pre = sDate.substring(0,tzdIndex);
157 int secFraction = pre.indexOf(",");
158 if (secFraction>-1) {
159 pre = pre.substring(0,secFraction);
160 }
161 String post = sDate.substring(tzdIndex);
162 sDate = pre + "GMT" + post;
163 }
164 }
165 return parseUsingMask(W3CDATETIME_MASKS,sDate);
166 }
167
168 /***
169 * create a RFC822 representation of a date.
170 * <p/>
171 * Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
172 * <p/>
173 * @param date Date to parse
174 * @return the RFC822 represented by the given Date
175 * It returns <b>null</b> if it was not possible to parse the date.
176 *
177 */
178 public static String formatRFC822(Date date) {
179 SimpleDateFormat dateFormater = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
180 dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
181 return dateFormater.format(date);
182 }
183
184 /***
185 * create a W3C Date Time representation of a date.
186 * <p/>
187 * Refer to the java.text.SimpleDateFormat javadocs for details on the format of each element.
188 * <p/>
189 * @param date Date to parse
190 * @return the W3C Date Time represented by the given Date
191 * It returns <b>null</b> if it was not possible to parse the date.
192 *
193 */
194 public static String formatW3CDateTime(Date date) {
195 SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
196 dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
197 return dateFormater.format(date);
198 }
199
200 }