package org.caudexorigo.time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
public class RFC822
{
private static final TimeZone gmt_timeZone = TimeZone.getTimeZone("GMT");
private static final Pattern rfc_part_splitter = Pattern.compile(",|\\s");
private static final Pattern rfc_hour_splitter = Pattern.compile(":");
private static final ConcurrentMap<String, Integer> rfc_month;
private static final ConcurrentMap<String, Integer> rfc_dow;
static
{
rfc_month = new ConcurrentHashMap<String, Integer>();
rfc_month.put("Jan", 0);
rfc_month.put("Feb", 1);
rfc_month.put("Mar", 2);
rfc_month.put("Apr", 3);
rfc_month.put("May", 4);
rfc_month.put("Jun", 5);
rfc_month.put("Jul", 6);
rfc_month.put("Aug", 7);
rfc_month.put("Sep", 8);
rfc_month.put("Oct", 9);
rfc_month.put("Nov", 10);
rfc_month.put("Dec", 11);
rfc_dow = new ConcurrentHashMap<String, Integer>();
rfc_dow.put("Sun", 1);
rfc_dow.put("Mon", 2);
rfc_dow.put("Tue", 3);
rfc_dow.put("Wed", 4);
rfc_dow.put("Thu", 5);
rfc_dow.put("Fri", 6);
rfc_dow.put("Sat", 7);
}
private static final ThreadLocal<SimpleDateFormat> rfc_sdf = new ThreadLocal<SimpleDateFormat>()
{
@Override
protected SimpleDateFormat initialValue()
{
final String _rfc_pattern = "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'zzz";
SimpleDateFormat _rfc_format;
_rfc_format = new SimpleDateFormat(_rfc_pattern, Locale.US);
_rfc_format.setTimeZone(gmt_timeZone);
return _rfc_format;
}
};
public static String toISO(String rfc_date) throws ParseException
{
Date date = parse(rfc_date);
return ISO8601.format(date);
}
public static Date parse(String rfc_date)
{
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.US);
calendar.clear();
String[] parts = rfc_part_splitter.split(rfc_date);
// System.out.println(Arrays.toString(parts));
int month_pos = 0;
boolean is_month_set = false;
int dow_pos = 0;
boolean is_dow_set = false;
int hour_pos = 0;
boolean is_hour_set = false;
for (int i = 0; i < parts.length; i++)
{
String part = parts[i];
if (!is_month_set)
{
Integer month_part = rfc_month.get(part);
if (month_part != null)
{
calendar.set(Calendar.MONTH, month_part.intValue());
month_pos = i;
is_month_set = true;
}
}
if (!is_dow_set)
{
Integer dow_part = rfc_dow.get(part);
if (dow_part != null)
{
calendar.set(Calendar.DAY_OF_WEEK, dow_part.intValue());
dow_pos = i;
is_dow_set = true;
}
}
if (!is_hour_set)
{
if (part.indexOf(":") > -1)
{
String[] hour_parts = rfc_hour_splitter.split(part);
if (hour_parts.length >= 2 && hour_parts.length <= 3)
{
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour_parts[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(hour_parts[1]));
if (hour_parts.length == 3)
{
calendar.set(Calendar.SECOND, Integer.parseInt(hour_parts[2]));
}
}
else
{
throw new RuntimeException("Error parsing date value, illegal hour format: '" + part + "'");
}
is_hour_set = true;
hour_pos = i;
}
}
}
int day_pos = month_pos - 1;
int year_pos = month_pos + 1;
String timeZone = parts[parts.length - 1];
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(parts[day_pos]));
calendar.set(Calendar.YEAR, Integer.parseInt(parts[year_pos]));
if (timeZone.startsWith("+"))
{
int offset = Integer.parseInt(timeZone.substring(1)) * 60000;
// System.out.println("RfcTest.parseRfcDate.offset: " + offset);
calendar.set(Calendar.ZONE_OFFSET, offset);
}
else if (timeZone.startsWith("-"))
{
int offset = -1 * Integer.parseInt(timeZone.substring(1)) * 60000;
// System.out.println("RfcTest.parseRfcDate.offset: " + offset);
calendar.set(Calendar.ZONE_OFFSET, offset);
}
else
{
// System.out.println("RfcTest.parseRfcDate.timezone: " + timeZone);
calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
}
return calendar.getTime();
}
public static String format(Date date) throws ParseException
{
return rfc_sdf.get().format(date);
}
}