blob: 269ea1c8aeeeb8dfe1ee45fca32c3e6418fcbef2 [file] [log] [blame]
/* $Id$ */
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.manifoldcf.core.common;
import java.util.*;
/** Class to parse and format common dates.
*/
public class DateParser
{
public static final String _rcsid = "@(#)$Id$";
/** Parse ISO 8601 dates, and their common variants.
*/
public static Date parseISO8601Date(String isoDateValue)
{
if (isoDateValue == null)
return null;
boolean isMicrosoft = (isoDateValue.indexOf("T") == -1);
String formatString;
if (isMicrosoft)
{
formatString = "yyyy-MM-dd' 'HH:mm:ss";
}
else
{
// There are a number of variations on the basic format.
// We'll look for key characters to help is determine which is which.
StringBuilder isoFormatString = new StringBuilder("yy");
if (isoDateValue.length() > 2 && isoDateValue.charAt(2) != '-')
isoFormatString.append("yy");
isoFormatString.append("-MM-dd'T'HH:mm:ss");
if (isoDateValue.indexOf(".") != -1)
isoFormatString.append(".SSS");
if (isoDateValue.endsWith("Z"))
isoFormatString.append("'Z'");
else
{
// We need to be able to parse either "-08:00" or "-0800". The 'Z' specifier only handles
// -0800, unfortunately - see CONNECTORS-700. So we have to do some hackery to remove the colon.
int colonIndex = isoDateValue.lastIndexOf(":");
int dashIndex = isoDateValue.lastIndexOf("-");
int plusIndex = isoDateValue.lastIndexOf("+");
if (colonIndex != -1 &&
((dashIndex != -1 && colonIndex == dashIndex+3 && isNumeral(isoDateValue,dashIndex-1)) || (plusIndex != -1 && colonIndex == plusIndex+3 && isNumeral(isoDateValue,plusIndex-1))))
isoDateValue = isoDateValue.substring(0,colonIndex) + isoDateValue.substring(colonIndex+1);
isoFormatString.append("Z"); // RFC 822 time, including general time zones
}
formatString = isoFormatString.toString();
}
java.text.DateFormat iso8601Format = new java.text.SimpleDateFormat(formatString);
try
{
return iso8601Format.parse(isoDateValue);
}
catch (java.text.ParseException e)
{
return null;
}
}
protected static boolean isNumeral(String value, int index)
{
return index >= 0 && value.charAt(index) >= '0' && value.charAt(index) <= '9';
}
/** Format ISO8601 date.
*/
public static String formatISO8601Date(Date dateValue)
{
java.text.DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(dateValue);
}
/** Timezone mapping from RFC822 timezones to ones understood by Java */
// Month map
protected static HashMap monthMap = new HashMap();
static
{
monthMap.put("jan",new Integer(1));
monthMap.put("feb",new Integer(2));
monthMap.put("mar",new Integer(3));
monthMap.put("apr",new Integer(4));
monthMap.put("may",new Integer(5));
monthMap.put("jun",new Integer(6));
monthMap.put("jul",new Integer(7));
monthMap.put("aug",new Integer(8));
monthMap.put("sep",new Integer(9));
monthMap.put("oct",new Integer(10));
monthMap.put("nov",new Integer(11));
monthMap.put("dec",new Integer(12));
}
protected static final HashMap milTzMap;
static
{
milTzMap = new HashMap();
milTzMap.put("Z","GMT");
milTzMap.put("UT","GMT");
milTzMap.put("A","GMT-01:00");
milTzMap.put("M","GMT-12:00");
milTzMap.put("N","GMT+01:00");
milTzMap.put("Y","GMT+12:00");
}
/** Parse RFC822 date */
public static Date parseRFC822Date(String dateValue)
{
if (dateValue == null)
return null;
dateValue = dateValue.trim();
// See http://www.faqs.org/rfcs/rfc822.html for legal formats
// Format: [day of week,] day mo year hh24:mm:ss tz
int commaIndex = dateValue.indexOf(",");
String usable;
if (commaIndex == -1)
usable = dateValue;
else
usable = dateValue.substring(commaIndex+1).trim();
int index;
index = usable.indexOf(" ");
if (index == -1)
return null;
String day = usable.substring(0,index);
usable = usable.substring(index+1).trim();
index = usable.indexOf(" ");
if (index == -1)
return null;
String month = usable.substring(0,index).toLowerCase();
usable = usable.substring(index+1).trim();
String year;
String hour = null;
String minute = null;
String second = null;
String timezone = null;
index = usable.indexOf(" ");
if (index != -1)
{
year = usable.substring(0,index);
usable = usable.substring(index+1).trim();
index = usable.indexOf(":");
if (index == -1)
return null;
hour = usable.substring(0,index);
usable = usable.substring(index+1).trim();
index = usable.indexOf(":");
if (index != -1)
{
minute = usable.substring(0,index);
usable = usable.substring(index+1).trim();
index = usable.indexOf(" ");
if (index == -1)
second = usable;
else
{
second = usable.substring(0,index);
timezone = usable.substring(index+1).trim();
}
}
else
{
index = usable.indexOf(" ");
if (index == -1)
minute = usable;
else
{
minute = usable.substring(0,index);
timezone = usable.substring(index+1).trim();
}
}
}
else
year = usable;
// Now construct a calendar object from this
TimeZone tz;
if (timezone != null && timezone.length() > 0)
{
if (timezone.startsWith("+") || timezone.startsWith("-"))
{
if (timezone.indexOf(":") == -1 && timezone.length() > 3)
timezone = timezone.substring(0,timezone.length()-2) + ":" + timezone.substring(timezone.length()-2);
timezone = "GMT"+timezone;
}
else
{
// Map special timezones to java timezones
if (milTzMap.get(timezone) != null)
timezone = (String)milTzMap.get(timezone);
}
}
else
timezone = "GMT";
tz = TimeZone.getTimeZone(timezone);
Calendar c = new GregorianCalendar(tz);
try
{
int value = Integer.parseInt(year);
if (value < 1900)
value += 1900;
c.set(Calendar.YEAR,value);
Integer x = (Integer)monthMap.get(month);
if (x == null)
return null;
c.set(Calendar.MONTH,x.intValue()-1);
value = Integer.parseInt(day);
c.set(Calendar.DAY_OF_MONTH,value);
if (hour != null)
value = Integer.parseInt(hour);
else
value = 0;
c.set(Calendar.HOUR_OF_DAY,value);
if (minute != null)
value = Integer.parseInt(minute);
else
value = 0;
c.set(Calendar.MINUTE,value);
if (second != null)
value = Integer.parseInt(second);
else
value = 0;
c.set(Calendar.SECOND,value);
c.set(Calendar.MILLISECOND,0);
return new Date(c.getTimeInMillis());
}
catch (NumberFormatException e)
{
return null;
}
}
/** Parse a China Daily News date */
public static Date parseChinaDate(String dateValue)
{
if (dateValue == null)
return null;
dateValue = dateValue.trim();
// Format: 2007/12/30 11:01
int index;
index = dateValue.indexOf("/");
if (index == -1)
return null;
String year = dateValue.substring(0,index);
dateValue = dateValue.substring(index+1);
index = dateValue.indexOf("/");
if (index == -1)
return null;
String month = dateValue.substring(0,index);
dateValue = dateValue.substring(index+1);
index = dateValue.indexOf(" ");
String day;
String hour = null;
String minute = null;
String second = null;
if (index == -1)
day = dateValue;
else
{
day = dateValue.substring(0,index);
dateValue = dateValue.substring(index+1);
index = dateValue.indexOf(":");
if (index == -1)
return null;
hour = dateValue.substring(0,index);
dateValue = dateValue.substring(index+1);
index = dateValue.indexOf(":");
if (index != -1)
{
minute = dateValue.substring(0,index);
dateValue = dateValue.substring(index+1);
second = dateValue;
}
else
minute = dateValue;
}
TimeZone tz = TimeZone.getTimeZone("GMT");
Calendar c = new GregorianCalendar(tz);
try
{
int value = Integer.parseInt(year);
if (value < 1900)
value += 1900;
c.set(Calendar.YEAR,value);
value = Integer.parseInt(month);
c.set(Calendar.MONTH,value-1);
value = Integer.parseInt(day);
c.set(Calendar.DAY_OF_MONTH,value);
if (hour != null)
value = Integer.parseInt(hour);
else
value = 0;
c.set(Calendar.HOUR_OF_DAY,value);
if (minute != null)
value = Integer.parseInt(minute);
else
value = 0;
c.set(Calendar.MINUTE,value);
if (second != null)
value = Integer.parseInt(second);
else
value = 0;
c.set(Calendar.SECOND,value);
c.set(Calendar.MILLISECOND,0);
return new Date(c.getTimeInMillis());
}
catch (NumberFormatException e)
{
return null;
}
}
}