You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ch...@apache.org on 2015/07/14 06:46:59 UTC
[lang] LANG-1154 FastDateFormat APIs that use a StringBuilder
Repository: commons-lang
Updated Branches:
refs/heads/master 03fe88ab7 -> 61579335b
LANG-1154
FastDateFormat APIs that use a StringBuilder
Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/61579335
Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/61579335
Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/61579335
Branch: refs/heads/master
Commit: 61579335bcb3da854fc8be82b5e61dc52b5018d3
Parents: 03fe88a
Author: Chas Honton <ch...@apache.org>
Authored: Mon Jul 13 21:46:14 2015 -0700
Committer: Chas Honton <ch...@apache.org>
Committed: Mon Jul 13 21:46:14 2015 -0700
----------------------------------------------------------------------
src/changes/changes.xml | 1 +
.../apache/commons/lang3/time/DatePrinter.java | 44 ++++-
.../commons/lang3/time/FastDateFormat.java | 56 +++++-
.../commons/lang3/time/FastDatePrinter.java | 172 +++++++++++++------
.../commons/lang3/time/FastDateFormatTest.java | 68 +++++---
.../commons/lang3/time/FastDateParserTest.java | 14 +-
.../commons/lang3/time/FastDatePrinterTest.java | 57 +++++-
7 files changed, 327 insertions(+), 85 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cffa0b3..e6bd030 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -22,6 +22,7 @@
<body>
<release version="3.5" date="tba" description="tba">
+ <action issue="LANG-1154" type="add" dev="chas" due-to="Gary Gregory">FastDateFormat APIs that use a StringBuilder</action>
<action issue="LANG-1149" type="add" dev="chas" due-to="Gregory Zak">Ability to throw checked exceptions without declaring them</action>
<action issue="LANG-1002" type="fix" dev="chas" due-to="Michael Osipov">Several predefined ISO FastDateFormats in DateFormatUtils are incorrect</action>
<action issue="LANG-1152" type="fix" dev="chas" due-to="Pas Filip">StringIndexOutOfBoundsException or field over-write for large year fields in FastDateParser</action>
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/main/java/org/apache/commons/lang3/time/DatePrinter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/lang3/time/DatePrinter.java b/src/main/java/org/apache/commons/lang3/time/DatePrinter.java
index 6808628..a2e97a9 100644
--- a/src/main/java/org/apache/commons/lang3/time/DatePrinter.java
+++ b/src/main/java/org/apache/commons/lang3/time/DatePrinter.java
@@ -59,23 +59,27 @@ public interface DatePrinter {
String format(Calendar calendar);
/**
- * <p>Formats a milliseond {@code long} value into the
+ * <p>Formats a millisecond {@code long} value into the
* supplied {@code StringBuffer}.</p>
+ * @deprecated Use {{@link #format(long, Appendable)}.
*
* @param millis the millisecond value to format
* @param buf the buffer to format into
* @return the specified string buffer
*/
+ @Deprecated
StringBuffer format(long millis, StringBuffer buf);
/**
* <p>Formats a {@code Date} object into the
* supplied {@code StringBuffer} using a {@code GregorianCalendar}.</p>
+ * @deprecated Use {{@link #format(Date, Appendable)}.
*
* @param date the date to format
* @param buf the buffer to format into
* @return the specified string buffer
*/
+ @Deprecated
StringBuffer format(Date date, StringBuffer buf);
/**
@@ -83,13 +87,51 @@ public interface DatePrinter {
* The TimeZone set on the Calendar is only used to adjust the time offset.
* The TimeZone specified during the construction of the Parser will determine the TimeZone
* used in the formatted string.
+ * @deprecated Use {{@link #format(Calendar, Appendable)}.
*
* @param calendar the calendar to format
* @param buf the buffer to format into
* @return the specified string buffer
*/
+ @Deprecated
StringBuffer format(Calendar calendar, StringBuffer buf);
+ /**
+ * <p>Formats a millisecond {@code long} value into the
+ * supplied {@code Appendable}.</p>
+ *
+ * @param millis the millisecond value to format
+ * @param buf the buffer to format into
+ * @return the specified string buffer
+ * @since 3.5
+ */
+ <B extends Appendable> B format(long millis, B buf);
+
+ /**
+ * <p>Formats a {@code Date} object into the
+ * supplied {@code Appendable} using a {@code GregorianCalendar}.</p>
+ *
+ * @param date the date to format
+ * @param buf the buffer to format into
+ * @return the specified string buffer
+ * @since 3.5
+ */
+ <B extends Appendable> B format(Date date, B buf);
+
+ /**
+ * <p>Formats a {@code Calendar} object into the supplied {@code Appendable}.</p>
+ * The TimeZone set on the Calendar is only used to adjust the time offset.
+ * The TimeZone specified during the construction of the Parser will determine the TimeZone
+ * used in the formatted string.
+ *
+ * @param calendar the calendar to format
+ * @param buf the buffer to format into
+ * @return the specified string buffer
+ * @since 3.5
+ */
+ <B extends Appendable> B format(Calendar calendar, B buf);
+
+
// Accessors
//-----------------------------------------------------------------------
/**
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/main/java/org/apache/commons/lang3/time/FastDateFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/lang3/time/FastDateFormat.java b/src/main/java/org/apache/commons/lang3/time/FastDateFormat.java
index b4cc85d..36d080f 100644
--- a/src/main/java/org/apache/commons/lang3/time/FastDateFormat.java
+++ b/src/main/java/org/apache/commons/lang3/time/FastDateFormat.java
@@ -399,6 +399,7 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* <p>Formats a {@code Date}, {@code Calendar} or
* {@code Long} (milliseconds) object.</p>
+ * This method is an implementation of {@link Format#format(Object, StringBuffer, FieldPosition)}
*
* @param obj the object to format
* @param toAppendTo the buffer to append to
@@ -407,7 +408,7 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
*/
@Override
public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) {
- return printer.format(obj, toAppendTo, pos);
+ return toAppendTo.append(printer.format(obj));
}
/**
@@ -447,12 +448,14 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* <p>Formats a millisecond {@code long} value into the
* supplied {@code StringBuffer}.</p>
+ * @deprecated Use {{@link #format(long, Appendable)}.
*
* @param millis the millisecond value to format
* @param buf the buffer to format into
* @return the specified string buffer
* @since 2.1
*/
+ @Deprecated
@Override
public StringBuffer format(final long millis, final StringBuffer buf) {
return printer.format(millis, buf);
@@ -461,11 +464,13 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* <p>Formats a {@code Date} object into the
* supplied {@code StringBuffer} using a {@code GregorianCalendar}.</p>
+ * @deprecated Use {{@link #format(Date, Appendable)}.
*
* @param date the date to format
* @param buf the buffer to format into
* @return the specified string buffer
*/
+ @Deprecated
@Override
public StringBuffer format(final Date date, final StringBuffer buf) {
return printer.format(date, buf);
@@ -474,16 +479,60 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* <p>Formats a {@code Calendar} object into the
* supplied {@code StringBuffer}.</p>
+ * @deprecated Use {{@link #format(Calendar, Appendable)}.
*
* @param calendar the calendar to format
* @param buf the buffer to format into
* @return the specified string buffer
*/
+ @Deprecated
@Override
public StringBuffer format(final Calendar calendar, final StringBuffer buf) {
return printer.format(calendar, buf);
}
+ /**
+ * <p>Formats a millisecond {@code long} value into the
+ * supplied {@code StringBuffer}.</p>
+ *
+ * @param millis the millisecond value to format
+ * @param buf the buffer to format into
+ * @return the specified string buffer
+ * @since 3.5
+ */
+ @Override
+ public <B extends Appendable> B format(final long millis, final B buf) {
+ return printer.format(millis, buf);
+ }
+
+ /**
+ * <p>Formats a {@code Date} object into the
+ * supplied {@code StringBuffer} using a {@code GregorianCalendar}.</p>
+ *
+ * @param date the date to format
+ * @param buf the buffer to format into
+ * @return the specified string buffer
+ * @since 3.5
+ */
+ @Override
+ public <B extends Appendable> B format(final Date date, final B buf) {
+ return printer.format(date, buf);
+ }
+
+ /**
+ * <p>Formats a {@code Calendar} object into the
+ * supplied {@code StringBuffer}.</p>
+ *
+ * @param calendar the calendar to format
+ * @param buf the buffer to format into
+ * @return the specified string buffer
+ * @since 3.5
+ */
+ @Override
+ public <B extends Appendable> B format(final Calendar calendar, final B buf) {
+ return printer.format(calendar, buf);
+ }
+
// Parsing
//-----------------------------------------------------------------------
@@ -597,18 +646,17 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
return "FastDateFormat[" + printer.getPattern() + "," + printer.getLocale() + "," + printer.getTimeZone().getID() + "]";
}
-
/**
* <p>Performs the formatting by applying the rules to the
* specified calendar.</p>
+ * @deprecated Use {{@link #format(Calendar, Appendable)
*
* @param calendar the calendar to format
* @param buf the buffer to format into
* @return the specified string buffer
*/
+ @Deprecated
protected StringBuffer applyRules(final Calendar calendar, final StringBuffer buf) {
return printer.applyRules(calendar, buf);
}
-
-
}
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/main/java/org/apache/commons/lang3/time/FastDatePrinter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/lang3/time/FastDatePrinter.java b/src/main/java/org/apache/commons/lang3/time/FastDatePrinter.java
index 84bf7e2..14c6d68 100644
--- a/src/main/java/org/apache/commons/lang3/time/FastDatePrinter.java
+++ b/src/main/java/org/apache/commons/lang3/time/FastDatePrinter.java
@@ -32,6 +32,8 @@ import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+
/**
* <p>FastDatePrinter is a fast and thread-safe version of
* {@link java.text.SimpleDateFormat}.</p>
@@ -387,12 +389,13 @@ public class FastDatePrinter implements DatePrinter, Serializable {
/**
* <p>Formats a {@code Date}, {@code Calendar} or
* {@code Long} (milliseconds) object.</p>
- *
+ * @deprecated Use {{@link #format(Date)}, {{@link #format(Calendar)}, {{@link #format(long)}, or {{@link #format(Object)}
* @param obj the object to format
* @param toAppendTo the buffer to append to
* @param pos the position - ignored
* @return the buffer passed in
*/
+ @Deprecated
@Override
public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) {
if (obj instanceof Date) {
@@ -407,6 +410,26 @@ public class FastDatePrinter implements DatePrinter, Serializable {
}
}
+ /**
+ * <p>Formats a {@code Date}, {@code Calendar} or
+ * {@code Long} (milliseconds) object.</p>
+ * @since 3.5
+ * @param obj the object to format
+ * @return The formatted value.
+ */
+ String format(Object obj) {
+ if (obj instanceof Date) {
+ return format((Date) obj);
+ } else if (obj instanceof Calendar) {
+ return format((Calendar) obj);
+ } else if (obj instanceof Long) {
+ return format(((Long) obj).longValue());
+ } else {
+ throw new IllegalArgumentException("Unknown class: " +
+ (obj == null ? "<null>" : obj.getClass().getName()));
+ }
+ }
+
/* (non-Javadoc)
* @see org.apache.commons.lang3.time.DatePrinter#format(long)
*/
@@ -423,7 +446,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* @return a String representation of the given Calendar.
*/
private String applyRulesToString(final Calendar c) {
- return applyRules(c, new StringBuffer(mMaxLengthEstimate)).toString();
+ return applyRules(c, new StringBuilder(mMaxLengthEstimate)).toString();
}
/**
@@ -450,7 +473,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
*/
@Override
public String format(final Calendar calendar) {
- return format(calendar, new StringBuffer(mMaxLengthEstimate)).toString();
+ return format(calendar, new StringBuilder(mMaxLengthEstimate)).toString();
}
/* (non-Javadoc)
@@ -480,6 +503,33 @@ public class FastDatePrinter implements DatePrinter, Serializable {
return format(calendar.getTime(), buf);
}
+ /* (non-Javadoc)
+ * @see org.apache.commons.lang3.time.DatePrinter#format(long, java.lang.Appendable)
+ */
+ @Override
+ public <B extends Appendable> B format(final long millis, final B buf) {
+ return format(new Date(millis), buf);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.lang3.time.DatePrinter#format(java.util.Date, java.lang.Appendable)
+ */
+ @Override
+ public <B extends Appendable> B format(final Date date, final B buf) {
+ final Calendar c = newCalendar(); // hard code GregorianCalendar
+ c.setTime(date);
+ return applyRules(c, buf);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.lang3.time.DatePrinter#format(java.util.Calendar, java.lang.Appendable)
+ */
+ @Override
+ public <B extends Appendable> B format(final Calendar calendar, final B buf) {
+ // do not pass in calendar directly, this will cause TimeZone of FastDatePrinter to be ignored
+ return format(calendar.getTime(), buf);
+ }
+
/**
* <p>Performs the formatting by applying the rules to the
* specified calendar.</p>
@@ -488,9 +538,13 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* @param buf the buffer to format into
* @return the specified string buffer
*/
- protected StringBuffer applyRules(final Calendar calendar, final StringBuffer buf) {
- for (final Rule rule : mRules) {
- rule.appendTo(buf, calendar);
+ protected <B extends Appendable> B applyRules(final Calendar calendar, final B buf) {
+ try {
+ for (final Rule rule : mRules) {
+ rule.appendTo(buf, calendar);
+ }
+ } catch (IOException ioe) {
+ ExceptionUtils.rethrow(ioe);
}
return buf;
}
@@ -589,16 +643,45 @@ public class FastDatePrinter implements DatePrinter, Serializable {
}
/**
- * Appends digits to the given buffer.
- *
+ * Appends two digits to the given buffer.
+ *
* @param buffer the buffer to append to.
* @param value the value to append digits from.
*/
- private static void appendDigits(final StringBuffer buffer, final int value) {
+ private static void appendDigits(final Appendable buffer, final int value) throws IOException {
buffer.append((char)(value / 10 + '0'));
buffer.append((char)(value % 10 + '0'));
}
+ private static final int MAX_DIGITS = 10; // log10(Integer.MAX_VALUE) ~= 9.3
+
+ /**
+ * Appends all digits to the given buffer.
+ *
+ * @param buffer the buffer to append to.
+ * @param value the value to append digits from.
+ */
+ private static void appendFullDigits(final Appendable buffer, int value, int minFieldWidth) throws IOException {
+ // build up decimal representation in reverse
+ char[] work = new char[MAX_DIGITS];
+ int digit = 0;
+ while(value!=0) {
+ work[digit++] = (char)(value % 10 + '0');
+ value = value / 10;
+ }
+
+ // pad with zeros
+ while(digit<minFieldWidth) {
+ buffer.append('0');
+ --minFieldWidth;
+ }
+
+ // reverse
+ while(--digit>=0) {
+ buffer.append(work[digit]);
+ }
+ }
+
// Rules
//-----------------------------------------------------------------------
/**
@@ -615,10 +698,10 @@ public class FastDatePrinter implements DatePrinter, Serializable {
/**
* Appends the value of the specified calendar to the output buffer based on the rule implementation.
*
- * @param buffer the output buffer
+ * @param buf the output buffer
* @param calendar calendar to be appended
*/
- void appendTo(StringBuffer buffer, Calendar calendar);
+ void appendTo(Appendable buf, Calendar calendar) throws IOException;
}
/**
@@ -631,7 +714,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* @param buffer the output buffer
* @param value the value to be appended
*/
- void appendTo(StringBuffer buffer, int value);
+ void appendTo(Appendable buffer, int value) throws IOException;
}
/**
@@ -662,7 +745,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
buffer.append(mValue);
}
}
@@ -695,7 +778,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
buffer.append(mValue);
}
}
@@ -738,7 +821,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
buffer.append(mValues[calendar.get(mField)]);
}
}
@@ -770,7 +853,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(mField));
}
@@ -778,13 +861,13 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public final void appendTo(final StringBuffer buffer, final int value) {
+ public final void appendTo(final Appendable buffer, final int value) throws IOException {
if (value < 10) {
buffer.append((char)(value + '0'));
} else if (value < 100) {
appendDigits(buffer, value);
} else {
- buffer.append(value);
+ appendFullDigits(buffer, value, 1);
}
}
}
@@ -815,7 +898,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
}
@@ -823,7 +906,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public final void appendTo(final StringBuffer buffer, final int value) {
+ public final void appendTo(final Appendable buffer, final int value) throws IOException {
if (value < 10) {
buffer.append((char)(value + '0'));
} else {
@@ -866,7 +949,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(mField));
}
@@ -874,23 +957,8 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public final void appendTo(final StringBuffer buffer, int value) {
- int first = buffer.length();
- // pad the buffer with adequate zeros
- for(int digit = 0; digit<mSize; ++digit) {
- buffer.append('0');
- }
- // backfill the buffer with non-zero digits
- int index = buffer.length();
- for( ; value>0; value /= 10) {
- char c= (char)('0' + value % 10);
- if(--index<first) {
- buffer.insert(first, c);
- }
- else {
- buffer.setCharAt(index, c);
- }
- }
+ public final void appendTo(final Appendable buffer, int value) throws IOException {
+ appendFullDigits(buffer, value, mSize);
}
}
@@ -921,7 +989,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(mField));
}
@@ -929,11 +997,11 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public final void appendTo(final StringBuffer buffer, final int value) {
+ public final void appendTo(final Appendable buffer, final int value) throws IOException {
if (value < 100) {
appendDigits(buffer, value);
} else {
- buffer.append(value);
+ appendFullDigits(buffer, value, 2);
}
}
}
@@ -963,7 +1031,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(Calendar.YEAR) % 100);
}
@@ -971,7 +1039,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public final void appendTo(final StringBuffer buffer, final int value) {
+ public final void appendTo(final Appendable buffer, final int value) throws IOException {
appendDigits(buffer, value);
}
}
@@ -1001,7 +1069,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
}
@@ -1009,7 +1077,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public final void appendTo(final StringBuffer buffer, final int value) {
+ public final void appendTo(final Appendable buffer, final int value) throws IOException {
appendDigits(buffer, value);
}
}
@@ -1042,7 +1110,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
int value = calendar.get(Calendar.HOUR);
if (value == 0) {
value = calendar.getLeastMaximum(Calendar.HOUR) + 1;
@@ -1054,7 +1122,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final int value) {
+ public void appendTo(final Appendable buffer, final int value) throws IOException {
mRule.appendTo(buffer, value);
}
}
@@ -1087,7 +1155,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
int value = calendar.get(Calendar.HOUR_OF_DAY);
if (value == 0) {
value = calendar.getMaximum(Calendar.HOUR_OF_DAY) + 1;
@@ -1099,7 +1167,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final int value) {
+ public void appendTo(final Appendable buffer, final int value) throws IOException {
mRule.appendTo(buffer, value);
}
}
@@ -1170,7 +1238,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
final TimeZone zone = calendar.getTimeZone();
if (calendar.get(Calendar.DST_OFFSET) != 0) {
buffer.append(getTimeZoneDisplay(zone, true, mStyle, mLocale));
@@ -1211,7 +1279,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
@@ -1290,7 +1358,7 @@ public class FastDatePrinter implements DatePrinter, Serializable {
* {@inheritDoc}
*/
@Override
- public void appendTo(final StringBuffer buffer, final Calendar calendar) {
+ public void appendTo(final Appendable buffer, final Calendar calendar) throws IOException {
int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
if (offset == 0) {
buffer.append("Z");
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
index 1b69403..564c10c 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateFormatTest.java
@@ -23,8 +23,9 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.text.FieldPosition;
import java.text.Format;
-import java.text.ParseException;
+import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@@ -33,7 +34,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongArray;
import org.apache.commons.lang3.test.SystemDefaults;
import org.apache.commons.lang3.test.SystemDefaultsSwitch;
@@ -232,33 +233,43 @@ public class FastDateFormatTest {
@Test
public void testParseSync() throws InterruptedException {
final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
- final FastDateFormat formatter= FastDateFormat.getInstance(pattern);
-
- final long sdfTime= measureTime(formatter, new SimpleDateFormat(pattern) {
- private static final long serialVersionUID = 1L; // because SimpleDateFormat is serializable
+ final SimpleDateFormat inner = new SimpleDateFormat(pattern);
+ final Format sdf= new Format() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public StringBuffer format(Object obj,
+ StringBuffer toAppendTo,
+ FieldPosition fieldPosition) {
+ synchronized(this) {
+ return inner.format(obj, toAppendTo, fieldPosition);
+ }
+ }
- @Override
- public Object parseObject(final String formattedDate) throws ParseException {
- synchronized(this) {
- return super.parse(formattedDate);
- }
- }
- });
-
- final long fdfTime= measureTime(formatter, FastDateFormat.getInstance(pattern));
-
- final String times= ">>FastDateFormatTest: FastDateParser:"+fdfTime+" SimpleDateFormat:"+sdfTime;
- System.out.println(times);
+ @Override
+ public Object parseObject(String source, ParsePosition pos) {
+ synchronized(this) {
+ return inner.parseObject(source, pos);
+ }
+ }
+ };
+ final AtomicLongArray sdfTime= measureTime(sdf, sdf);
+
+ Format fdf = FastDateFormat.getInstance(pattern);
+ final AtomicLongArray fdfTime= measureTime(fdf, fdf);
+
+ System.out.println(">>FastDateFormatTest: FastDatePrinter:"+fdfTime.get(0)+" SimpleDateFormat:"+sdfTime.get(0));
+ System.out.println(">>FastDateFormatTest: FastDateParser:"+fdfTime.get(1)+" SimpleDateFormat:"+sdfTime.get(1));
}
final static private int NTHREADS= 10;
final static private int NROUNDS= 10000;
- private long measureTime(final Format formatter, final Format parser) throws InterruptedException {
+ private AtomicLongArray measureTime(final Format printer, final Format parser) throws InterruptedException {
final ExecutorService pool = Executors.newFixedThreadPool(NTHREADS);
final AtomicInteger failures= new AtomicInteger(0);
- final AtomicLong totalElapsed= new AtomicLong(0);
-
+ final AtomicLongArray totalElapsed= new AtomicLongArray(2);
+
for(int i= 0; i<NTHREADS; ++i) {
pool.submit(new Runnable() {
@Override
@@ -266,10 +277,15 @@ public class FastDateFormatTest {
for(int j= 0; j<NROUNDS; ++j) {
try {
final Date date= new Date();
- final String formattedDate= formatter.format(date);
- final long start= System.currentTimeMillis();
+
+ final long t0= System.currentTimeMillis();
+ final String formattedDate= printer.format(date);
+ totalElapsed.addAndGet(0, System.currentTimeMillis() - t0);
+
+ final long t1 = System.currentTimeMillis();
final Object pd= parser.parseObject(formattedDate);
- totalElapsed.addAndGet(System.currentTimeMillis()-start);
+ totalElapsed.addAndGet(1, System.currentTimeMillis() - t1);
+
if(!date.equals(pd)) {
failures.incrementAndGet();
}
@@ -290,9 +306,9 @@ public class FastDateFormatTest {
fail("did not complete tasks");
}
assertEquals(0, failures.get());
- return totalElapsed.get();
+ return totalElapsed;
}
-
+
@Test
public void testLANG_1152() {
TimeZone utc = TimeZone.getTimeZone("UTC");
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
index 330935c..4c18e64 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue;
import java.io.Serializable;
import java.text.ParseException;
+import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@@ -666,7 +667,7 @@ public class FastDateParserTest {
@Test
public void testLang1121() throws ParseException {
TimeZone kst = TimeZone.getTimeZone("KST");
- final DateParser fdp = FastDateFormat.getInstance("yyyyMMdd", kst, Locale.KOREA);
+ final DateParser fdp = getInstance("yyyyMMdd", kst, Locale.KOREA);
try {
fdp.parse("2015");
@@ -690,4 +691,15 @@ public class FastDateParserTest {
actual = fdp.parse("20150429113100");
Assert.assertEquals(expected, actual);
}
+
+ @Test
+ public void testParseOffset() throws ParseException {
+ DateParser parser = getInstance(YMD_SLASH);
+ final Date date = parser.parse("Today is 2015/07/04", new ParsePosition(9));
+
+ final Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(2015, Calendar.JULY, 4);
+ Assert.assertEquals(cal.getTime(), date);
+ }
}
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/61579335/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java b/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java
index 74938e8..0727486 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDatePrinterTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.Serializable;
+import java.text.FieldPosition;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -30,8 +31,8 @@ import java.util.Locale;
import java.util.TimeZone;
import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.test.SystemDefaultsSwitch;
import org.apache.commons.lang3.test.SystemDefaults;
+import org.apache.commons.lang3.test.SystemDefaultsSwitch;
import org.junit.Rule;
import org.junit.Test;
@@ -364,4 +365,58 @@ public class FastDatePrinterTest {
assertEquals("calendar", "2009-10-16T07:42:16 +0100", value);
}
}
+
+ @Test
+ public void testHourFormats() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.clear();
+ DatePrinter printer = getInstance("K k H h");
+
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ assertEquals("0 24 0 12", printer.format(calendar));
+
+ calendar.set(Calendar.HOUR_OF_DAY, 12);
+ assertEquals("0 12 12 12", printer.format(calendar));
+
+ calendar.set(Calendar.HOUR_OF_DAY, 23);
+ assertEquals("11 23 23 11", printer.format(calendar));
+ }
+
+ @Test
+ public void testStringBufferOptions() {
+ final DatePrinter format = getInstance("yyyy-MM-dd HH:mm:ss.SSS Z", TimeZone.getTimeZone("GMT"));
+ Calendar calendar = Calendar.getInstance();
+ StringBuffer sb = new StringBuffer();
+ String expected = format.format(calendar, sb, new FieldPosition(0)).toString();
+ sb.setLength(0);
+ assertEquals(expected, format.format(calendar, sb).toString());
+ sb.setLength(0);
+
+ Date date = calendar.getTime();
+ assertEquals(expected, format.format(date, sb, new FieldPosition(0)).toString());
+ sb.setLength(0);
+ assertEquals(expected, format.format(date, sb).toString());
+ sb.setLength(0);
+
+ long epoch = date.getTime();
+ assertEquals(expected, format.format(epoch, sb, new FieldPosition(0)).toString());
+ sb.setLength(0);
+ assertEquals(expected, format.format(epoch, sb).toString());
+ }
+
+ @Test
+ public void testAppendableOptions() {
+ final DatePrinter format = getInstance("yyyy-MM-dd HH:mm:ss.SSS Z", TimeZone.getTimeZone("GMT"));
+ Calendar calendar = Calendar.getInstance();
+ StringBuilder sb = new StringBuilder();
+ String expected = format.format(calendar, sb).toString();
+ sb.setLength(0);
+
+ Date date = calendar.getTime();
+ assertEquals(expected, format.format(date, sb).toString());
+ sb.setLength(0);
+
+ long epoch = date.getTime();
+ assertEquals(expected, format.format(epoch, sb).toString());
+ }
}