HTTPDateFormat.java [plain text]
package gnu.java.net.protocol.http;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class HTTPDateFormat
extends DateFormat
{
static final String[] DAYS_OF_WEEK = {
null, "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static final String[] MONTHS = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
public HTTPDateFormat()
{
calendar = new GregorianCalendar(TimeZone.getTimeZone ("GMT"));
numberFormat = new DecimalFormat();
}
public StringBuffer format(Date date, StringBuffer buf,
FieldPosition field)
{
calendar.clear();
calendar.setTime(date);
buf.setLength(0);
buf.append(DAYS_OF_WEEK[calendar.get(Calendar.DAY_OF_WEEK)]);
buf.append(',');
buf.append(' ');
int day = calendar.get(Calendar.DAY_OF_MONTH);
buf.append(Character.forDigit(day / 10, 10));
buf.append(Character.forDigit(day % 10, 10));
buf.append(' ');
buf.append(MONTHS[calendar.get(Calendar.MONTH)]);
buf.append(' ');
int year = calendar.get(Calendar.YEAR);
if (year < 1000)
{
buf.append('0');
if (year < 100)
{
buf.append('0');
if (year < 10)
{
buf.append('0');
}
}
}
buf.append(Integer.toString(year));
buf.append(' ');
int hour = calendar.get(Calendar.HOUR_OF_DAY);
buf.append(Character.forDigit(hour / 10, 10));
buf.append(Character.forDigit(hour % 10, 10));
buf.append(':');
int minute = calendar.get(Calendar.MINUTE);
buf.append(Character.forDigit(minute / 10, 10));
buf.append(Character.forDigit(minute % 10, 10));
buf.append(':');
int second = calendar.get(Calendar.SECOND);
buf.append(Character.forDigit(second / 10, 10));
buf.append(Character.forDigit(second % 10, 10));
buf.append(' ');
int zoneOffset =(calendar.get(Calendar.ZONE_OFFSET) +
calendar.get(Calendar.DST_OFFSET)) / 60000;
if (zoneOffset < 0)
{
zoneOffset = -zoneOffset;
buf.append('-');
}
else
{
buf.append('+');
}
int tzhours = zoneOffset / 60;
buf.append(Character.forDigit(tzhours / 10, 10));
buf.append(Character.forDigit(tzhours % 10, 10));
int tzminutes = zoneOffset % 60;
buf.append(Character.forDigit(tzminutes / 10, 10));
buf.append(Character.forDigit(tzminutes % 10, 10));
field.setBeginIndex(0);
field.setEndIndex(buf.length());
return buf;
}
public Date parse(String text, ParsePosition pos)
{
int date, month, year, hour, minute, second;
String monthText;
int start = 0, end = -1;
int len = text.length();
calendar.clear();
pos.setIndex(start);
try
{
if (Character.isLetter(text.charAt(start)))
{
start = skipNonWhitespace(text, start);
}
switch(start)
{
case 3:
start = skipWhitespace(text, start);
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
monthText = text.substring(start, end);
month = -1;
for (int i = 0; i < 12; i++)
{
if (MONTHS[i].equals(monthText))
{
month = i;
break;
}
}
if (month == -1)
{
pos.setErrorIndex(end);
return null;
}
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
date = Integer.parseInt(text.substring(start, end));
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipTo(text, start + 1, ':');
hour = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = skipTo(text, start + 1, ':');
minute = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
second = Integer.parseInt(text.substring(start, end));
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
year = Integer.parseInt(text.substring(start, end));
break;
case 0:
case 4:
start = skipWhitespace(text, start);
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
date = Integer.parseInt(text.substring(start, end));
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
monthText = text.substring(start, end);
month = -1;
for (int i = 0; i < 12; i++)
{
if (MONTHS[i].equals(monthText))
{
month = i;
break;
}
}
if (month == -1)
{
pos.setErrorIndex(end);
return null;
}
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
year = Integer.parseInt(text.substring(start, end));
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipTo(text, start + 1, ':');
hour = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = skipTo(text, start + 1, ':');
minute = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = start + 1;
while (end < len && !Character.isWhitespace(text.charAt(end)))
{
end++;
}
second = Integer.parseInt(text.substring(start, end));
break;
default:
start = skipWhitespace(text, start);
pos.setIndex(start);
end = skipTo(text, start + 1, '-');
date = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = skipTo(text, start + 1, '-');
monthText = text.substring(start, end);
month = -1;
for (int i = 0; i < 12; i++)
{
if (MONTHS[i].equals(monthText))
{
month = i;
break;
}
}
if (month == -1)
{
pos.setErrorIndex(end);
return null;
}
start = end + 1;
pos.setIndex(start);
end = skipNonWhitespace(text, start + 1);
year = 1900 + Integer.parseInt(text.substring(start, end));
start = skipWhitespace(text, end + 1);
pos.setIndex(start);
end = skipTo(text, start + 1, ':');
hour = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = skipTo(text, start + 1, ':');
minute = Integer.parseInt(text.substring(start, end));
start = end + 1;
pos.setIndex(start);
end = start + 1;
while (end < len && !Character.isWhitespace(text.charAt(end)))
{
end++;
}
second = Integer.parseInt(text.substring(start, end));
}
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, date);
calendar.set(Calendar.HOUR, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
if (end != len)
{
start = skipWhitespace(text, end + 1);
end = start + 1;
while (end < len && !Character.isWhitespace(text.charAt(end)))
{
end++;
}
char pm = text.charAt(start);
if (Character.isLetter(pm))
{
TimeZone tz =
TimeZone.getTimeZone(text.substring(start, end));
calendar.set(Calendar.ZONE_OFFSET, tz.getRawOffset());
}
else
{
int zoneOffset = 0;
zoneOffset += 600 * Character.digit(text.charAt(++start), 10);
zoneOffset += 60 * Character.digit(text.charAt(++start), 10);
zoneOffset += 10 * Character.digit(text.charAt(++start), 10);
zoneOffset += Character.digit(text.charAt(++start), 10);
zoneOffset *= 60000; if ('-' == pm)
{
zoneOffset = -zoneOffset;
}
calendar.set(Calendar.ZONE_OFFSET, zoneOffset);
}
}
pos.setIndex(end);
return calendar.getTime();
}
catch (NumberFormatException e)
{
pos.setErrorIndex(Math.max(start, end));
}
catch (StringIndexOutOfBoundsException e)
{
pos.setErrorIndex(Math.max(start, end));
}
return null;
}
private int skipWhitespace(String text, int pos)
{
while(Character.isWhitespace(text.charAt(pos)))
{
pos++;
}
return pos;
}
private int skipNonWhitespace(String text, int pos)
{
while(!Character.isWhitespace(text.charAt(pos)))
{
pos++;
}
return pos;
}
private int skipTo(String text, int pos, char c)
{
while(text.charAt(pos) != c)
{
pos++;
}
return pos;
}
public void setCalendar(Calendar newCalendar)
{
throw new UnsupportedOperationException();
}
public void setNumberFormat(NumberFormat newNumberFormat)
{
throw new UnsupportedOperationException();
}
}