parent
03fe88ab71
commit
61579335bc
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
|
|
|
@ -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,17 +448,63 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <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>
|
||||
|
@ -465,9 +512,10 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
|
|||
* @param date the date to format
|
||||
* @param buf the buffer to format into
|
||||
* @return the specified string buffer
|
||||
* @since 3.5
|
||||
*/
|
||||
@Override
|
||||
public StringBuffer format(final Date date, final StringBuffer buf) {
|
||||
public <B extends Appendable> B format(final Date date, final B buf) {
|
||||
return printer.format(date, buf);
|
||||
}
|
||||
|
||||
|
@ -478,9 +526,10 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
|
|||
* @param calendar the calendar to format
|
||||
* @param buf the buffer to format into
|
||||
* @return the specified string buffer
|
||||
*/
|
||||
* @since 3.5
|
||||
*/
|
||||
@Override
|
||||
public StringBuffer format(final Calendar calendar, final StringBuffer buf) {
|
||||
public <B extends Appendable> B format(final Calendar calendar, final B buf) {
|
||||
return printer.format(calendar, buf);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 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 StringBuffer format(Object obj,
|
||||
StringBuffer toAppendTo,
|
||||
FieldPosition fieldPosition) {
|
||||
synchronized(this) {
|
||||
return inner.format(obj, toAppendTo, fieldPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue