1 package org.codehaus.xfire.util;
2
3 import java.text.SimpleDateFormat;
4 import java.util.Calendar;
5 import java.util.Date;
6 import java.util.GregorianCalendar;
7 import java.util.TimeZone;
8
9 /***
10 * Helps reading and writing ISO8601 dates.
11 * <p>
12 * Contains code from Apache Axis.
13 *
14 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse </a>
15 */
16 public class DateUtils
17 {
18 private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
19 "yyyy-MM-dd");
20
21 private static SimpleDateFormat dateTimeFormatter = new SimpleDateFormat(
22 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
23
24 private static Calendar calendar = Calendar.getInstance();
25
26 static
27 {
28 dateTimeFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
29 }
30
31 public static Date parseDate(String source)
32 {
33 Date result;
34 boolean bc = false;
35
36
37 if (source != null)
38 {
39 if (source.charAt(0) == '+') source = source.substring(1);
40
41 if (source.charAt(0) == '-')
42 {
43 source = source.substring(1);
44 bc = true;
45 }
46
47 if (source.length() < 10)
48 throw new NumberFormatException("Invalid date format.");
49
50 if (source.charAt(4) != '-' || source.charAt(7) != '-')
51 throw new NumberFormatException("Invalid date format.");
52
53 }
54
55 synchronized (calendar)
56 {
57
58 try
59 {
60 result = dateFormatter.parse(source == null ? null : (source.substring(0, 10)));
61 }
62 catch (Exception e)
63 {
64 throw new NumberFormatException(e.toString());
65 }
66
67
68 if (bc)
69 {
70 calendar.setTime(result);
71 calendar.set(Calendar.ERA, GregorianCalendar.BC);
72 result = calendar.getTime();
73 }
74 }
75
76 return result;
77 }
78
79 public static String formatDate( Date date )
80 {
81 synchronized (dateFormatter)
82 {
83
84 return dateFormatter.format(date);
85 }
86 }
87
88 public static String formatDateTime( Date date )
89 {
90 synchronized (dateTimeFormatter)
91 {
92
93 return dateTimeFormatter.format(date);
94 }
95 }
96
97 public static Date parseDateTime(String source)
98 {
99 Calendar calendar = Calendar.getInstance();
100 Date date;
101 boolean bc = false;
102
103
104 if (source != null)
105 {
106 if (source.charAt(0) == '+') source = source.substring(1);
107
108 if (source.charAt(0) == '-')
109 {
110 source = source.substring(1);
111 bc = true;
112 }
113
114 if (source.length() < 19)
115 throw new NumberFormatException("Invalid date format.");
116
117 if (source.charAt(4) != '-' || source.charAt(7) != '-'
118 || source.charAt(10) != 'T')
119 throw new NumberFormatException("Invalid date format.");
120
121 if (source.charAt(13) != ':' || source.charAt(16) != ':')
122 throw new NumberFormatException("Invalid date format.");
123 }
124
125
126 try
127 {
128 synchronized (dateTimeFormatter)
129 {
130 date = dateTimeFormatter.parse(source == null ? null : (source.substring(0,19) + ".000Z"));
131 }
132 }
133 catch (Exception e)
134 {
135 throw new NumberFormatException(e.toString());
136 }
137
138 int pos = 19;
139
140
141 if (source != null)
142 {
143 if (pos < source.length() && source.charAt(pos) == '.')
144 {
145 int milliseconds = 0;
146 int start = ++pos;
147 while (pos < source.length()
148 && Character.isDigit(source.charAt(pos)))
149 pos++;
150
151 String decimal = source.substring(start, pos);
152 if (decimal.length() == 3)
153 {
154 milliseconds = Integer.parseInt(decimal);
155 }
156 else if (decimal.length() < 3)
157 {
158 milliseconds = Integer.parseInt((decimal + "000")
159 .substring(0, 3));
160 }
161 else
162 {
163 milliseconds = Integer.parseInt(decimal.substring(0, 3));
164 if (decimal.charAt(3) >= '5') ++milliseconds;
165 }
166
167
168 date.setTime(date.getTime() + milliseconds);
169 }
170
171
172 if (pos + 5 < source.length()
173 && (source.charAt(pos) == '+' || (source.charAt(pos) == '-')))
174 {
175 if (!Character.isDigit(source.charAt(pos + 1))
176 || !Character.isDigit(source.charAt(pos + 2))
177 || source.charAt(pos + 3) != ':'
178 || !Character.isDigit(source.charAt(pos + 4))
179 || !Character.isDigit(source.charAt(pos + 5)))
180 throw new NumberFormatException("Invalid date format. Bad Timezone.");
181
182 int hours = (source.charAt(pos + 1) - '0') * 10
183 + source.charAt(pos + 2) - '0';
184 int mins = (source.charAt(pos + 4) - '0') * 10
185 + source.charAt(pos + 5) - '0';
186 int milliseconds = (hours * 60 + mins) * 60 * 1000;
187
188
189 if (source.charAt(pos) == '+') milliseconds = -milliseconds;
190 date.setTime(date.getTime() + milliseconds);
191 pos += 6;
192 }
193
194 if (pos < source.length() && source.charAt(pos) == 'Z')
195 {
196 pos++;
197 calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
198 }
199
200 if (pos < source.length())
201 throw new NumberFormatException("Invalid date format.");
202 }
203
204 calendar.setTime(date);
205
206
207 if (bc)
208 {
209 calendar.set(Calendar.ERA, GregorianCalendar.BC);
210 }
211
212 return date;
213 }
214 }