1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.core.impl.datetime;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.time.DurationFormatUtils;
21 import org.kuali.rice.core.api.datetime.DateTimeService;
22 import org.kuali.rice.core.api.CoreConstants;
23 import org.kuali.rice.core.api.config.property.ConfigContext;
24 import org.springframework.beans.factory.InitializingBean;
25
26 import java.sql.Timestamp;
27 import java.text.DateFormat;
28 import java.text.ParseException;
29 import java.text.ParsePosition;
30 import java.text.SimpleDateFormat;
31 import java.util.Arrays;
32 import java.util.Calendar;
33 import java.util.Collections;
34 import java.util.Date;
35 import java.util.List;
36
37
38
39
40
41
42 public class DateTimeServiceImpl implements DateTimeService, InitializingBean {
43 protected String[] stringToDateFormats;
44 protected String[] stringToTimestampFormats;
45 protected String dateToStringFormatForUserInterface;
46 protected String timestampToStringFormatForUserInterface;
47 protected String dateToStringFormatForFileName;
48 protected String timestampToStringFormatForFileName;
49
50
51
52
53
54 public String toDateString(Date date) {
55 return toString(date, dateToStringFormatForUserInterface);
56 }
57
58
59
60
61 public String toDateTimeString(Date date) {
62 return toString(date, timestampToStringFormatForUserInterface);
63 }
64
65
66
67
68
69 public String toString(Date date, String pattern) {
70 DateFormat dateFormat = new SimpleDateFormat(pattern);
71 dateFormat.setLenient(false);
72 return dateFormat.format(date);
73 }
74
75
76
77
78 public Date getCurrentDate() {
79 Calendar c = Calendar.getInstance();
80 c.setTime(new Date());
81 return c.getTime();
82 }
83
84
85
86
87 public Timestamp getCurrentTimestamp() {
88 return new java.sql.Timestamp(getCurrentDate().getTime());
89 }
90
91
92
93
94 public java.sql.Date getCurrentSqlDate() {
95 return new java.sql.Date(getCurrentDate().getTime());
96 }
97
98
99
100
101 public java.sql.Date getCurrentSqlDateMidnight() {
102
103 return java.sql.Date.valueOf(getCurrentSqlDate().toString());
104 }
105
106
107
108
109 public Calendar getCurrentCalendar() {
110 return getCalendar(getCurrentDate());
111 }
112
113
114
115
116 public Calendar getCalendar(Date date) {
117 if (date == null) {
118 throw new IllegalArgumentException("invalid (null) date");
119 }
120
121 Calendar currentCalendar = Calendar.getInstance();
122 currentCalendar.setTime(date);
123
124 return currentCalendar;
125 }
126
127
128
129
130
131
132 public Date convertToDate(String dateString) throws ParseException {
133 return parseAgainstFormatArray(dateString, stringToDateFormats);
134 }
135
136
137
138
139 public Date convertToDateTime(String dateTimeString) throws ParseException {
140 if (StringUtils.isBlank(dateTimeString)) {
141 throw new IllegalArgumentException("invalid (blank) date/time string");
142 }
143 return parseAgainstFormatArray(dateTimeString, stringToTimestampFormats);
144 }
145
146
147
148
149 public java.sql.Timestamp convertToSqlTimestamp(String timeString)
150 throws ParseException {
151 if (!StringUtils.isBlank(timeString)) {
152 return new java.sql.Timestamp(convertToDateTime(timeString).getTime());
153 }
154 return null;
155 }
156
157
158
159
160 public java.sql.Date convertToSqlDate(String dateString)
161 throws ParseException {
162 if (StringUtils.isBlank(dateString)) {
163 throw new IllegalArgumentException("invalid (blank) timeString");
164 }
165 Date date = parseAgainstFormatArray(dateString, stringToDateFormats);
166 return new java.sql.Date(date.getTime());
167 }
168
169 protected Date parseAgainstFormatArray(String dateString, String[] formats) throws ParseException {
170 dateString = dateString.trim();
171 StringBuffer exceptionMessage = new StringBuffer("Date or date/time string '")
172 .append(dateString)
173 .append("' could not be converted using any of the accepted formats: ");
174 for (String dateFormatString : formats) {
175 try {
176 return parse(dateString, dateFormatString);
177 } catch (ParseException e) {
178 exceptionMessage.append(dateFormatString).append(
179 " (error offset=").append(e.getErrorOffset()).append(
180 "),");
181 }
182 }
183 throw new ParseException(exceptionMessage.toString().substring(0,
184 exceptionMessage.length() - 1), 0);
185 }
186
187
188
189
190
191 public java.sql.Date convertToSqlDate(Timestamp timestamp)
192 throws ParseException {
193 return new java.sql.Date(timestamp.getTime());
194 }
195
196 public int dateDiff(Date startDate, Date endDate, boolean inclusive) {
197 Calendar startDateCalendar = Calendar.getInstance();
198 startDateCalendar.setTime(startDate);
199
200 Calendar endDateCalendar = Calendar.getInstance();
201 endDateCalendar.setTime(endDate);
202
203 int startDateOffset = -(startDateCalendar.get(Calendar.ZONE_OFFSET) + startDateCalendar
204 .get(Calendar.DST_OFFSET))
205 / (60 * 1000);
206
207 int endDateOffset = -(endDateCalendar.get(Calendar.ZONE_OFFSET) + endDateCalendar
208 .get(Calendar.DST_OFFSET))
209 / (60 * 1000);
210
211 if (startDateOffset > endDateOffset) {
212 startDateCalendar.add(Calendar.MINUTE, endDateOffset
213 - startDateOffset);
214 }
215
216 if (inclusive) {
217 startDateCalendar.add(Calendar.DATE, -1);
218 }
219
220 int dateDiff = Integer.parseInt(DurationFormatUtils.formatDuration(
221 endDateCalendar.getTimeInMillis()
222 - startDateCalendar.getTimeInMillis(), "d", true));
223
224 return dateDiff;
225 }
226
227 protected Date parse(String dateString, String pattern) throws ParseException {
228 if (!StringUtils.isBlank(dateString)) {
229 DateFormat dateFormat = new SimpleDateFormat(pattern);
230 dateFormat.setLenient(false);
231 ParsePosition parsePosition = new ParsePosition(0);
232 Date testDate = dateFormat.parse(dateString, parsePosition);
233
234
235 if (testDate == null) {
236 throw new ParseException("The date that you provided is invalid.",parsePosition.getErrorIndex());
237 } else if (parsePosition.getIndex() != dateString.length()) {
238 throw new ParseException("The date that you provided is invalid.",parsePosition.getIndex());
239 }
240
241
242 Calendar testCalendar = Calendar.getInstance();
243 testCalendar.setLenient(false);
244 testCalendar.setTime(testDate);
245 if (testCalendar.get(Calendar.YEAR) < 1000 || testCalendar.get(Calendar.YEAR) > 9999) {
246 throw new ParseException("The date that you provided is not between the years 1000 and 9999.",-1);
247 }
248
249 if(testCalendar.get(Calendar.YEAR) == 1970 && !pattern.contains("y".toLowerCase())){
250 Calendar curCalendar = Calendar.getInstance();
251 curCalendar.setTime(new java.util.Date());
252 testCalendar.set(Calendar.YEAR, curCalendar.get(Calendar.YEAR));
253 testDate = testCalendar.getTime();
254 }
255
256 return testDate;
257 }
258 return null;
259 }
260
261
262
263
264 public String toDateStringForFilename(Date date) {
265 SimpleDateFormat dateFormat = new SimpleDateFormat(dateToStringFormatForFileName);
266 return dateFormat.format(date);
267 }
268
269
270
271
272 public String toDateTimeStringForFilename(Date date) {
273 SimpleDateFormat dateFormat = new SimpleDateFormat(timestampToStringFormatForFileName);
274 return dateFormat.format(date);
275 }
276
277
278
279
280
281
282
283
284
285 private List<String> parseConfigValues(String configValue) {
286 if (configValue == null || "".equals(configValue)) {
287 return Collections.emptyList();
288 }
289 return Arrays.asList(configValue.split(";"));
290 }
291
292
293
294
295
296 @Override
297 public void afterPropertiesSet() throws Exception {
298 if (stringToDateFormats == null) {
299 List<String> dateFormatParams = parseConfigValues(ConfigContext.getCurrentContextConfig().getProperty(CoreConstants.STRING_TO_DATE_FORMATS));
300
301 stringToDateFormats = new String[dateFormatParams.size()];
302
303 for (int i = 0; i < dateFormatParams.size(); i++) {
304 String dateFormatParam = dateFormatParams.get(i);
305 if (StringUtils.isBlank(dateFormatParam)) {
306 throw new IllegalArgumentException("Core/All/STRING_TO_DATE_FORMATS parameter contains a blank semi-colon delimited substring");
307 }
308 else {
309
310 new SimpleDateFormat(dateFormatParam);
311 stringToDateFormats[i] = dateFormatParam;
312 }
313 }
314 }
315
316 if (stringToTimestampFormats == null) {
317 List<String> dateFormatParams = parseConfigValues(ConfigContext.getCurrentContextConfig().getProperty(CoreConstants.STRING_TO_TIMESTAMP_FORMATS));
318
319 stringToTimestampFormats = new String[dateFormatParams.size()];
320
321 for (int i = 0; i < dateFormatParams.size(); i++) {
322 String dateFormatParam = dateFormatParams.get(i);
323 if (StringUtils.isBlank(dateFormatParam)) {
324 throw new IllegalArgumentException("Core/All/STRING_TO_TIMESTAMP_FORMATS parameter contains a blank semi-colon delimited substring");
325 }
326 else {
327
328 new SimpleDateFormat(dateFormatParam);
329 stringToTimestampFormats[i] = dateFormatParam;
330 }
331 }
332 }
333
334 if (dateToStringFormatForUserInterface == null) {
335 dateToStringFormatForUserInterface = ConfigContext.getCurrentContextConfig().getProperty(CoreConstants.DATE_TO_STRING_FORMAT_FOR_USER_INTERFACE);
336
337 new SimpleDateFormat(dateToStringFormatForUserInterface);
338 }
339
340 if (timestampToStringFormatForUserInterface == null) {
341 timestampToStringFormatForUserInterface = ConfigContext.getCurrentContextConfig().getProperty(CoreConstants.TIMESTAMP_TO_STRING_FORMAT_FOR_USER_INTERFACE);
342
343 new SimpleDateFormat(timestampToStringFormatForUserInterface);
344 }
345
346 if (dateToStringFormatForFileName == null) {
347 dateToStringFormatForFileName = ConfigContext.getCurrentContextConfig().getProperty(CoreConstants.DATE_TO_STRING_FORMAT_FOR_FILE_NAME);
348
349
350 new SimpleDateFormat(dateToStringFormatForFileName);
351 }
352
353 if (timestampToStringFormatForFileName == null) {
354 timestampToStringFormatForFileName = ConfigContext.getCurrentContextConfig().getProperty(CoreConstants.TIMESTAMP_TO_STRING_FORMAT_FOR_FILE_NAME);
355
356
357 new SimpleDateFormat(timestampToStringFormatForFileName);
358 }
359 }
360 }