001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005:
006: package com.sun.portal.search.util;
007:
008: import java.util.*;
009: import java.text.*;
010: import java.io.*;
011:
012: /**
013: *
014: */
015: public class DateParser {
016:
017: static long _32_bit_seconds = 0x7fffffffL * 1000L; // largest date that fits in 32 bits
018:
019: static List dateFormats = new ArrayList();
020:
021: static {
022: String[] USFormatStrings = { "E, d MMM y h:m:s a z",
023: "E, d MMM y h:m:s a", "E, d MMM y H:m:s z",
024: "E, d MMM y H:m:s", "E, d MMM y z", "E, d MMM y",
025: "E, MMM d y h:m:s a z", "E, MMM d y h:m:s a",
026: "E, MMM d y H:m:s z", "E, MMM d y H:m:s",
027: "E, MMM d y z", "E, MMM d y", "M/d/y h:m:s a z",
028: "M/d/y h:m:s a", "M/d/y H:m:s z", "M/d/y H:m:s",
029: "M/d/y z", "M/d/y", "M-d-y h:m:s a z", "M-d-y h:m:s a",
030: "M-d-y H:m:s z", "M-d-y H:m:s", "M-d-y z", "M-d-y",
031: "M.d.y h:m:s a z", "M.d.y h:m:s a", "M.d.y H:m:s z",
032: "M.d.y H:m:s", "M.d.y z", "M.d.y", "MMM d y h:m:s a z",
033: "MMM d y h:m:s a", "MMM d y H:m:s z", "MMM d y H:m:s",
034: "MMM d y z", "MMM d y", "d MMM y h:m:s a z",
035: "d MMM y h:m:s a", "d MMM y H:m:s z", "d MMM y H:m:s",
036: "d MMM y z", "d MMM y", "E MMM d h:m:s a z y",
037: "E MMM d H:m:s z y", "EEE, MMM d, ''yy", "h:mm a",
038: "H:mm", "hh 'o''clock' a, zzzz",
039: "yyyyy.MMMMM.dd GGG hh:mm aaa",
040: "yyyyy.MMMMM.dd GGG HH:mm", "E,MMM d y z", "E,MMM d y",
041: "E,d MMM y h:m:s a z", "E,d MMM y h:m:s a",
042: "E,d MMM y H:m:s z", "E,d MMM y H:m:s", "E,d MMM y z",
043: "E,d MMM y", "E, d-MMM-y h:m:s a z",
044: "E, d-MMM-y h:m:s a", "E, d-MMM-y H:m:s z",
045: "E, d-MMM-y H:m:s", "E, d-MMM-y z", "E, d-MMM-y",
046: "E MMM d h:m:s y a z", "E MMM d h:m:s y a",
047: "E MMM d H:m:s y z", "E MMM d H:m:s y", "E MMM d y z",
048: "E MMM d y", "d-MMM-y h:m:s a z", "d-MMM-y h:m:s a",
049: "d-MMM-y H:m:s z", "d-MMM-y H:m:s", "d-MMM-y z",
050: "d-MMM-y", "y-M-d", "M d y", "y M d", };
051: // Add US formats
052: for (int i = 0; i < USFormatStrings.length; ++i) {
053: dateFormats.add(new SimpleDateFormat(USFormatStrings[i],
054: Locale.US));
055: }
056: // Add local formats
057: dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.FULL,
058: DateFormat.FULL));
059: dateFormats.add(DateFormat.getDateInstance(DateFormat.FULL));
060: dateFormats.add(DateFormat.getTimeInstance(DateFormat.FULL));
061: dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.LONG,
062: DateFormat.LONG));
063: dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG));
064: dateFormats.add(DateFormat.getTimeInstance(DateFormat.LONG));
065: dateFormats.add(DateFormat.getDateTimeInstance(
066: DateFormat.MEDIUM, DateFormat.MEDIUM));
067: dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM));
068: dateFormats.add(DateFormat.getTimeInstance(DateFormat.MEDIUM));
069: dateFormats.add(DateFormat.getDateTimeInstance(
070: DateFormat.SHORT, DateFormat.SHORT));
071: dateFormats.add(DateFormat.getDateInstance(DateFormat.SHORT));
072: dateFormats.add(DateFormat.getTimeInstance(DateFormat.SHORT));
073: // XXX Should have a way to register more formats from config file
074: }
075:
076: /** Hidden */
077: private DateParser() {
078: }
079:
080: /**
081: * This date parser understands many US and locale based formats.
082: * Typical RD dates look like: Fri, 17 Jan 1997 16:42:49 GMT
083: * (this format derives from http timestamps)
084: * @param _32_bits if false allows 64 bit (milliseconds) dates
085: * if true, only allows 32 bit dates (seconds) due to search engine limit.
086: */
087: static public synchronized Date parse(String date, boolean _32_bits)
088: throws ParseException {
089: Date d = null;
090: for (Iterator i = dateFormats.iterator(); i.hasNext();) {
091: try {
092: d = ((SimpleDateFormat) i.next()).parse(date);
093: if (_32_bits && (d.getTime() > _32_bit_seconds)) {
094: continue;
095: }
096: return d;
097: } catch (Exception e) {
098: }
099: }
100:
101: if (d == null) {
102: // nothing parsed - try some special cases
103: try {
104: if (date.equals("0") || date.equalsIgnoreCase("now")
105: || date.equalsIgnoreCase("today")
106: || date.equalsIgnoreCase("immediately")
107: || date.equalsIgnoreCase("expired"))
108: return new Date();
109: else if (date.equalsIgnoreCase("never"))
110: if (_32_bits)
111: return new Date(_32_bit_seconds);
112: else
113: return new Date(0x7fffffffffffffffL);
114: else {
115: // [+]/-n days
116: if (date.startsWith("+"))
117: date = date.substring(1);
118: long i = Integer.parseInt(date);
119: return new Date(new Date().getTime() + i * 24 * 60
120: * 60 * 1000);
121: }
122: } catch (Exception ignored) {
123: }
124: }
125:
126: throw new ParseException("Date failed to parse", 0);
127: }
128:
129: /**
130: * This date parser understands many US and locale based formats.
131: * Typical RD dates look like: Fri, 17 Jan 1997 16:42:49 GMT
132: * (this format derives from http timestamps)
133: * Although Java allows 64 bit date (milliseconds) the default
134: * here only allows 32 bit dates (seconds) due to search engine limit.
135: */
136: static public synchronized Date parse(String date)
137: throws ParseException {
138: return parse(date, true);
139: }
140:
141: }
|