MIME4J-309 MimeUtil::date0 should use DateTimeFormatter (#61)
diff --git a/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java b/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
index 7241e1b..46e71e4 100644
--- a/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
+++ b/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
@@ -19,12 +19,29 @@
package org.apache.james.mime4j.util;
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
+import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.OFFSET_SECONDS;
+import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
+import static java.time.temporal.ChronoField.YEAR;
+
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.ResolverStyle;
+import java.time.format.SignStyle;
import java.util.Date;
import java.util.GregorianCalendar;
+import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
@@ -171,15 +188,17 @@
* @return the formatted time string.
*/
public static String formatDate(Date date, TimeZone zone) {
- DateFormat df = RFC822_DATE_FORMAT.get();
+ return RFC822_DATE_FORMAT
+ .withZone(zone(zone))
+ .format(date.toInstant());
+ }
+ private static ZoneId zone(TimeZone zone) {
if (zone == null) {
- df.setTimeZone(TimeZone.getDefault());
+ return TimeZone.getDefault().toZoneId();
} else {
- df.setTimeZone(zone);
+ return zone.toZoneId();
}
-
- return df.format(date);
}
/**
@@ -294,39 +313,55 @@
return counter++;
}
- private static final ThreadLocal<DateFormat> RFC822_DATE_FORMAT = new ThreadLocal<DateFormat>() {
- @Override
- protected DateFormat initialValue() {
- return new Rfc822DateFormat();
- }
- };
+ private static final int INITIAL_YEAR = 1970;
+ public static final DateTimeFormatter RFC822_DATE_FORMAT = new DateTimeFormatterBuilder()
+ .parseCaseInsensitive()
+ .parseLenient()
+ .appendText(DAY_OF_WEEK, dayOfWeek())
+ .appendLiteral(", ")
+ .appendValue(DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
+ .appendLiteral(' ')
+ .appendText(MONTH_OF_YEAR, monthOfYear())
+ .appendLiteral(' ')
+ .appendValueReduced(YEAR, 4, 4, INITIAL_YEAR)
+ .appendLiteral(' ')
+ .appendValue(HOUR_OF_DAY, 2)
+ .appendLiteral(':')
+ .appendValue(MINUTE_OF_HOUR, 2)
+ .appendLiteral(':')
+ .appendValue(SECOND_OF_MINUTE, 2)
+ .appendLiteral(' ')
+ .appendOffset("+HHMM", "+0000")
+ .toFormatter()
+ .withZone(TimeZone.getDefault().toZoneId())
+ .withLocale(Locale.US);
- private static final class Rfc822DateFormat extends SimpleDateFormat {
- private static final long serialVersionUID = 1L;
+ private static Map<Long, String> monthOfYear() {
+ HashMap<Long, String> result = new HashMap<>();
+ result.put(1L, "Jan");
+ result.put(2L, "Feb");
+ result.put(3L, "Mar");
+ result.put(4L, "Apr");
+ result.put(5L, "May");
+ result.put(6L, "Jun");
+ result.put(7L, "Jul");
+ result.put(8L, "Aug");
+ result.put(9L, "Sep");
+ result.put(10L, "Oct");
+ result.put(11L, "Nov");
+ result.put(12L, "Dec");
+ return result;
+ }
- public Rfc822DateFormat() {
- super("EEE, d MMM yyyy HH:mm:ss ", Locale.US);
- }
-
- @Override
- public StringBuffer format(Date date, StringBuffer toAppendTo,
- FieldPosition pos) {
- StringBuffer sb = super.format(date, toAppendTo, pos);
-
- int zoneMillis = calendar.get(GregorianCalendar.ZONE_OFFSET);
- int dstMillis = calendar.get(GregorianCalendar.DST_OFFSET);
- int minutes = (zoneMillis + dstMillis) / 1000 / 60;
-
- if (minutes < 0) {
- sb.append('-');
- minutes = -minutes;
- } else {
- sb.append('+');
- }
-
- sb.append(String.format("%02d%02d", minutes / 60, minutes % 60));
-
- return sb;
- }
+ private static Map<Long, String> dayOfWeek() {
+ HashMap<Long, String> result = new HashMap<>();
+ result.put(1L, "Mon");
+ result.put(2L, "Tue");
+ result.put(3L, "Wed");
+ result.put(4L, "Thu");
+ result.put(5L, "Fri");
+ result.put(6L, "Sat");
+ result.put(7L, "Sun");
+ return result;
}
}