001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018: /*
019: * Modified for Stringbeans/Juggets usage by Nabh Information Systems, Inc.
020: */
021: package com.nabhinc.util;
022:
023: import java.text.ParseException;
024: import java.text.ParsePosition;
025: import java.text.SimpleDateFormat;
026: import java.util.Calendar;
027: import java.util.Date;
028: import java.util.Locale;
029: import java.util.TimeZone;
030:
031: import org.apache.commons.lang.StringUtils;
032:
033: public class DateUtil {
034: public static final long millisInDay = 86400000;
035:
036: // a bunch of date formats
037: private static final String formatDefaultDate = "dd.MM.yyyy";
038: private static final String formatDefaultDateMinimal = "d.M.yy";
039: private static final String formatDefaultTimestamp = "yyyy-MM-dd HH:mm:ss.SSS";
040:
041: private static final String formatFriendlyTimestamp = "dd.MM.yyyy HH:mm:ss";
042:
043: private static final String format6chars = "yyyyMM";
044: private static final String format8chars = "yyyyMMdd";
045:
046: private static final String formatIso8601 = "yyyy-MM-dd'T'HH:mm:ssZ";
047: private static final String formatIso8601Day = "yyyy-MM-dd";
048:
049: private static final String formatRfc822 = "EEE, d MMM yyyy HH:mm:ss Z";
050:
051: /**
052: * Returns a Date set to the last possible millisecond of the day, just
053: * before midnight. If a null day is passed in, a new Date is created.
054: * midnight (00m 00h 00s)
055: */
056: public static Date getEndOfDay(Date day) {
057: return getEndOfDay(day, Calendar.getInstance());
058: }
059:
060: public static Date getEndOfDay(Date day, Calendar cal) {
061: if (day == null)
062: day = new Date();
063: cal.setTime(day);
064: cal.set(Calendar.HOUR_OF_DAY, cal
065: .getMaximum(Calendar.HOUR_OF_DAY));
066: cal.set(Calendar.MINUTE, cal.getMaximum(Calendar.MINUTE));
067: cal.set(Calendar.SECOND, cal.getMaximum(Calendar.SECOND));
068: cal.set(Calendar.MILLISECOND, cal
069: .getMaximum(Calendar.MILLISECOND));
070: return cal.getTime();
071: }
072:
073: /**
074: * Returns a Date set to the first possible millisecond of the month, just
075: * after midnight. If a null day is passed in, a new Date is created.
076: * midnight (00m 00h 00s)
077: */
078: public static Date getStartOfMonth(Date day) {
079: return getStartOfMonth(day, Calendar.getInstance());
080: }
081:
082: public static Date getStartOfMonth(Date day, Calendar cal) {
083: if (day == null)
084: day = new Date();
085: cal.setTime(day);
086:
087: // set time to start of day
088: cal.set(Calendar.HOUR_OF_DAY, cal
089: .getMinimum(Calendar.HOUR_OF_DAY));
090: cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
091: cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
092: cal.set(Calendar.MILLISECOND, cal
093: .getMinimum(Calendar.MILLISECOND));
094:
095: // set time to first day of month
096: cal.set(Calendar.DAY_OF_MONTH, 1);
097:
098: return cal.getTime();
099: }
100:
101: /**
102: * Returns a Date set to the last possible millisecond of the month, just
103: * before midnight. If a null day is passed in, a new Date is created.
104: * midnight (00m 00h 00s)
105: */
106: public static Date getEndOfMonth(Date day) {
107: return getEndOfMonth(day, Calendar.getInstance());
108: }
109:
110: public static Date getEndOfMonth(Date day, Calendar cal) {
111: if (day == null)
112: day = new Date();
113: cal.setTime(day);
114:
115: // set time to end of day
116: cal.set(Calendar.HOUR_OF_DAY, cal
117: .getMaximum(Calendar.HOUR_OF_DAY));
118: cal.set(Calendar.MINUTE, cal.getMaximum(Calendar.MINUTE));
119: cal.set(Calendar.SECOND, cal.getMaximum(Calendar.SECOND));
120: cal.set(Calendar.MILLISECOND, cal
121: .getMaximum(Calendar.MILLISECOND));
122:
123: // set time to first day of month
124: cal.set(Calendar.DAY_OF_MONTH, 1);
125:
126: // add one month
127: cal.add(Calendar.MONTH, 1);
128:
129: // back up one day
130: cal.add(Calendar.DAY_OF_MONTH, -1);
131:
132: return cal.getTime();
133: }
134:
135: /**
136: * Returns a Date set to the first possible millisecond of the day, just
137: * after midnight. If a null day is passed in, a new Date is created.
138: * midnight (00m 00h 00s)
139: */
140: public static Date getStartOfDay(Date day) {
141: return getStartOfDay(day, Calendar.getInstance());
142: }
143:
144: /**
145: * Returns a Date set to the first possible millisecond of the day, just
146: * after midnight. If a null day is passed in, a new Date is created.
147: * midnight (00m 00h 00s)
148: */
149: public static Date getStartOfDay(Date day, Calendar cal) {
150: if (day == null)
151: day = new Date();
152: cal.setTime(day);
153: cal.set(Calendar.HOUR_OF_DAY, cal
154: .getMinimum(Calendar.HOUR_OF_DAY));
155: cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
156: cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
157: cal.set(Calendar.MILLISECOND, cal
158: .getMinimum(Calendar.MILLISECOND));
159: return cal.getTime();
160: }
161:
162: /**
163: * Returns a Date set just to Noon, to the closest possible millisecond
164: * of the day. If a null day is passed in, a new Date is created.
165: * nnoon (00m 12h 00s)
166: */
167: public static Date getNoonOfDay(Date day, Calendar cal) {
168: if (day == null)
169: day = new Date();
170: cal.setTime(day);
171: cal.set(Calendar.HOUR_OF_DAY, 12);
172: cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
173: cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
174: cal.set(Calendar.MILLISECOND, cal
175: .getMinimum(Calendar.MILLISECOND));
176: return cal.getTime();
177: }
178:
179: /**
180: * Returns a java.sql.Timestamp equal to the current time
181: **/
182: public static java.sql.Timestamp now() {
183: return new java.sql.Timestamp(new java.util.Date().getTime());
184: }
185:
186: /**
187: * Returns a string the represents the passed-in date parsed
188: * according to the passed-in format. Returns an empty string
189: * if the date or the format is null.
190: **/
191: public static String format(Date aDate, SimpleDateFormat aFormat) {
192: if (aDate == null || aFormat == null) {
193: return "";
194: }
195: synchronized (aFormat) {
196: return aFormat.format(aDate);
197: }
198: }
199:
200: /**
201: * Returns a Date using the passed-in string and format. Returns null if the string
202: * is null or empty or if the format is null. The string must match the format.
203: **/
204: public static Date parse(String aValue, SimpleDateFormat aFormat)
205: throws ParseException {
206: if (StringUtils.isEmpty(aValue) || aFormat == null) {
207: return null;
208: }
209: synchronized (aFormat) {
210: return aFormat.parse(aValue);
211: }
212: }
213:
214: /**
215: * Returns true if endDate is after startDate or if startDate equals endDate
216: * or if they are the same date. Returns false if either value is null.
217: **/
218: public static boolean isValidDateRange(Date startDate, Date endDate) {
219: return isValidDateRange(startDate, endDate, true);
220: }
221:
222: /**
223: * Returns true if endDate is after startDate or if startDate equals endDate.
224: * Returns false if either value is null. If equalOK, returns true if the
225: * dates are equal.
226: **/
227: public static boolean isValidDateRange(Date startDate,
228: Date endDate, boolean equalOK) {
229: // false if either value is null
230: if (startDate == null || endDate == null) {
231: return false;
232: }
233:
234: if (equalOK) {
235: // true if they are equal
236: if (startDate.equals(endDate)) {
237: return true;
238: }
239: }
240:
241: // true if endDate after startDate
242: if (endDate.after(startDate)) {
243: return true;
244: }
245:
246: return false;
247: }
248:
249: // convenience method returns minimal date format
250: public static SimpleDateFormat defaultDateFormat() {
251: return DateUtil.friendlyDateFormat(true);
252: }
253:
254: // convenience method returns minimal date format
255: public static java.text.SimpleDateFormat minimalDateFormat() {
256: return friendlyDateFormat(true);
257: }
258:
259: // convenience method that returns friendly data format
260: // using full month, day, year digits.
261: public static SimpleDateFormat fullDateFormat() {
262: return friendlyDateFormat(false);
263: }
264:
265: /**
266: * Returns a "friendly" date format.
267: * @param mimimalFormat Should the date format allow single digits.
268: **/
269: public static SimpleDateFormat friendlyDateFormat(
270: boolean minimalFormat) {
271: if (minimalFormat) {
272: return new SimpleDateFormat(formatDefaultDateMinimal);
273: }
274:
275: return new SimpleDateFormat(formatDefaultDate);
276: }
277:
278: // returns full timestamp format
279: public static SimpleDateFormat defaultTimestampFormat() {
280: return new SimpleDateFormat(formatDefaultTimestamp);
281: }
282:
283: // convenience method returns long friendly timestamp format
284: public static SimpleDateFormat friendlyTimestampFormat() {
285: return new SimpleDateFormat(formatFriendlyTimestamp);
286: }
287:
288: // convenience method returns minimal date format
289: public static SimpleDateFormat get8charDateFormat() {
290: return new SimpleDateFormat(format8chars);
291: }
292:
293: // convenience method returns minimal date format
294: public static SimpleDateFormat get6charDateFormat() {
295: return new SimpleDateFormat(format6chars);
296: }
297:
298: // convenience method returns minimal date format
299: public static SimpleDateFormat getIso8601DateFormat() {
300: return new SimpleDateFormat(formatIso8601);
301: }
302:
303: // convenience method returns minimal date format
304: public static SimpleDateFormat getIso8601DayDateFormat() {
305: return new SimpleDateFormat(formatIso8601Day);
306: }
307:
308: // convenience method returns minimal date format
309: public static SimpleDateFormat getRfc822DateFormat() {
310: // http://www.w3.org/Protocols/rfc822/Overview.html#z28
311: // Using Locale.US to fix ROL-725 and ROL-628
312: return new SimpleDateFormat(formatRfc822, Locale.US);
313: }
314:
315: // convenience method
316: public static String defaultDate(Date date) {
317: return format(date, defaultDateFormat());
318: }
319:
320: // convenience method using minimal date format
321: public static String minimalDate(Date date) {
322: return format(date, DateUtil.minimalDateFormat());
323: }
324:
325: public static String fullDate(Date date) {
326: return format(date, DateUtil.fullDateFormat());
327: }
328:
329: /**
330: * Format the date using the "friendly" date format.
331: */
332: public static String friendlyDate(Date date, boolean minimalFormat) {
333: return format(date, friendlyDateFormat(minimalFormat));
334: }
335:
336: // convenience method
337: public static String friendlyDate(Date date) {
338: return format(date, friendlyDateFormat(true));
339: }
340:
341: // convenience method
342: public static String defaultTimestamp(Date date) {
343: return format(date, defaultTimestampFormat());
344: }
345:
346: // convenience method returns long friendly formatted timestamp
347: public static String friendlyTimestamp(Date date) {
348: return format(date, friendlyTimestampFormat());
349: }
350:
351: // convenience method returns 8 char day stamp YYYYMMDD
352: public static String format8chars(Date date) {
353: return format(date, get8charDateFormat());
354: }
355:
356: // convenience method returns 6 char month stamp YYYYMM
357: public static String format6chars(Date date) {
358: return format(date, get6charDateFormat());
359: }
360:
361: // convenience method returns long friendly formatted timestamp
362: public static String formatIso8601Day(Date date) {
363: return format(date, getIso8601DayDateFormat());
364: }
365:
366: public static String formatRfc822(Date date) {
367: return format(date, getRfc822DateFormat());
368: }
369:
370: // This is a hack, but it seems to work
371: public static String formatIso8601(Date date) {
372: if (date == null)
373: return "";
374:
375: // Add a colon 2 chars before the end of the string
376: // to make it a valid ISO-8601 date.
377:
378: String str = format(date, getIso8601DateFormat());
379: StringBuffer sb = new StringBuffer();
380: sb.append(str.substring(0, str.length() - 2));
381: sb.append(":");
382: sb.append(str.substring(str.length() - 2));
383: return sb.toString();
384: }
385:
386: public static Date parseIso8601(String value) throws Exception {
387: return ISO8601DateParser.parse(value);
388: }
389:
390: /**
391: * Parse data as either 6-char or 8-char format.
392: */
393: public static Date parseWeblogURLDateString(String dateString,
394: TimeZone tz, Locale locale) {
395:
396: Date ret = new Date();
397: SimpleDateFormat char8DateFormat = DateUtil
398: .get8charDateFormat();
399: SimpleDateFormat char6DateFormat = DateUtil
400: .get6charDateFormat();
401:
402: if (dateString != null && dateString.length() == 8
403: && StringUtils.isNumeric(dateString)) {
404: ParsePosition pos = new ParsePosition(0);
405: ret = char8DateFormat.parse(dateString, pos);
406:
407: // make sure the requested date is not in the future
408: Date today = null;
409: Calendar todayCal = Calendar.getInstance();
410: todayCal = Calendar.getInstance(tz, locale);
411: todayCal.setTime(new Date());
412: today = todayCal.getTime();
413: if (ret.after(today)) {
414: ret = today;
415: }
416:
417: } else if (dateString != null && dateString.length() == 6
418: && StringUtils.isNumeric(dateString)) {
419: ParsePosition pos = new ParsePosition(0);
420: ret = char6DateFormat.parse(dateString, pos);
421:
422: // make sure the requested date is not in the future
423: Calendar todayCal = Calendar.getInstance();
424: todayCal = Calendar.getInstance(tz, locale);
425: todayCal.setTime(new Date());
426: Date today = todayCal.getTime();
427: if (ret.after(today)) {
428: ret = today;
429: }
430: }
431:
432: return ret;
433: }
434:
435: }
|