LANG-984 DurationFormatUtils does not handle large durations correctly
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1573749 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ddc06197e4
commit
cf4138d7bc
|
@ -21,6 +21,10 @@
|
|||
</properties>
|
||||
<body>
|
||||
|
||||
<release version="3.4" date="TBA" description="TBA">
|
||||
<action issue="LANG-984" type="fix" dev="sebb">DurationFormatUtils does not handle large durations correctly</action>
|
||||
</release>
|
||||
|
||||
<release version="3.3" date="TBA" description="Bug fixes and and new features including: DifferenceBuilder, ClassPathUtils, RandomUtils and Jaro-Winkler String distance metric">
|
||||
<action issue="LANG-621" type="fix" dev="kinow" due-to="Philip Hodges, Thomas Neidhart">ReflectionToStringBuilder.toString does not debug 3rd party object fields within 3rd party object</action>
|
||||
<action issue="LANG-955" type="add" dev="britter" due-to="Adam Hooper">Add methods for removing all invalid characters according to XML 1.0 and XML 1.1 in an input string to StringEscapeUtils</action>
|
||||
|
|
|
@ -123,30 +123,30 @@ public class DurationFormatUtils {
|
|||
|
||||
final Token[] tokens = lexx(format);
|
||||
|
||||
int days = 0;
|
||||
int hours = 0;
|
||||
int minutes = 0;
|
||||
int seconds = 0;
|
||||
int milliseconds = 0;
|
||||
long days = 0;
|
||||
long hours = 0;
|
||||
long minutes = 0;
|
||||
long seconds = 0;
|
||||
long milliseconds = 0;
|
||||
|
||||
if (Token.containsTokenWithValue(tokens, d) ) {
|
||||
days = (int) (durationMillis / DateUtils.MILLIS_PER_DAY);
|
||||
days = durationMillis / DateUtils.MILLIS_PER_DAY;
|
||||
durationMillis = durationMillis - (days * DateUtils.MILLIS_PER_DAY);
|
||||
}
|
||||
if (Token.containsTokenWithValue(tokens, H) ) {
|
||||
hours = (int) (durationMillis / DateUtils.MILLIS_PER_HOUR);
|
||||
hours = durationMillis / DateUtils.MILLIS_PER_HOUR;
|
||||
durationMillis = durationMillis - (hours * DateUtils.MILLIS_PER_HOUR);
|
||||
}
|
||||
if (Token.containsTokenWithValue(tokens, m) ) {
|
||||
minutes = (int) (durationMillis / DateUtils.MILLIS_PER_MINUTE);
|
||||
minutes = durationMillis / DateUtils.MILLIS_PER_MINUTE;
|
||||
durationMillis = durationMillis - (minutes * DateUtils.MILLIS_PER_MINUTE);
|
||||
}
|
||||
if (Token.containsTokenWithValue(tokens, s) ) {
|
||||
seconds = (int) (durationMillis / DateUtils.MILLIS_PER_SECOND);
|
||||
seconds = durationMillis / DateUtils.MILLIS_PER_SECOND;
|
||||
durationMillis = durationMillis - (seconds * DateUtils.MILLIS_PER_SECOND);
|
||||
}
|
||||
if (Token.containsTokenWithValue(tokens, S) ) {
|
||||
milliseconds = (int) durationMillis;
|
||||
milliseconds = durationMillis;
|
||||
}
|
||||
|
||||
return format(tokens, 0, 0, days, hours, minutes, seconds, milliseconds, padWithZeros);
|
||||
|
@ -411,8 +411,8 @@ public class DurationFormatUtils {
|
|||
* @param padWithZeros whether to pad
|
||||
* @return the formatted string
|
||||
*/
|
||||
static String format(final Token[] tokens, final int years, final int months, final int days, final int hours, final int minutes, final int seconds,
|
||||
int milliseconds, final boolean padWithZeros) {
|
||||
static String format(final Token[] tokens, final long years, final long months, final long days, final long hours, final long minutes, final long seconds,
|
||||
long milliseconds, final boolean padWithZeros) {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
boolean lastOutputSeconds = false;
|
||||
final int sz = tokens.length;
|
||||
|
@ -424,40 +424,32 @@ public class DurationFormatUtils {
|
|||
buffer.append(value.toString());
|
||||
} else {
|
||||
if (value == y) {
|
||||
buffer.append(padWithZeros ? StringUtils.leftPad(Integer.toString(years), count, '0') : Integer
|
||||
.toString(years));
|
||||
buffer.append(paddedValue(years, padWithZeros, count));
|
||||
lastOutputSeconds = false;
|
||||
} else if (value == M) {
|
||||
buffer.append(padWithZeros ? StringUtils.leftPad(Integer.toString(months), count, '0') : Integer
|
||||
.toString(months));
|
||||
buffer.append(paddedValue(months, padWithZeros, count));
|
||||
lastOutputSeconds = false;
|
||||
} else if (value == d) {
|
||||
buffer.append(padWithZeros ? StringUtils.leftPad(Integer.toString(days), count, '0') : Integer
|
||||
.toString(days));
|
||||
buffer.append(paddedValue(days, padWithZeros, count));
|
||||
lastOutputSeconds = false;
|
||||
} else if (value == H) {
|
||||
buffer.append(padWithZeros ? StringUtils.leftPad(Integer.toString(hours), count, '0') : Integer
|
||||
.toString(hours));
|
||||
buffer.append(paddedValue(hours, padWithZeros, count));
|
||||
lastOutputSeconds = false;
|
||||
} else if (value == m) {
|
||||
buffer.append(padWithZeros ? StringUtils.leftPad(Integer.toString(minutes), count, '0') : Integer
|
||||
.toString(minutes));
|
||||
buffer.append(paddedValue(minutes, padWithZeros, count));
|
||||
lastOutputSeconds = false;
|
||||
} else if (value == s) {
|
||||
buffer.append(padWithZeros ? StringUtils.leftPad(Integer.toString(seconds), count, '0') : Integer
|
||||
.toString(seconds));
|
||||
buffer.append(paddedValue(seconds, padWithZeros, count));
|
||||
lastOutputSeconds = true;
|
||||
} else if (value == S) {
|
||||
if (lastOutputSeconds) {
|
||||
milliseconds += 1000;
|
||||
final String str = padWithZeros
|
||||
? StringUtils.leftPad(Integer.toString(milliseconds), count, '0')
|
||||
: Integer.toString(milliseconds);
|
||||
? StringUtils.leftPad(Long.toString(milliseconds), count, '0')
|
||||
: Long.toString(milliseconds);
|
||||
buffer.append(str.substring(1));
|
||||
} else {
|
||||
buffer.append(padWithZeros
|
||||
? StringUtils.leftPad(Integer.toString(milliseconds), count, '0')
|
||||
: Integer.toString(milliseconds));
|
||||
buffer.append(paddedValue(milliseconds, padWithZeros, count));
|
||||
}
|
||||
lastOutputSeconds = false;
|
||||
}
|
||||
|
@ -466,6 +458,12 @@ public class DurationFormatUtils {
|
|||
return buffer.toString();
|
||||
}
|
||||
|
||||
// Helper method to simplify repetive code in format method above
|
||||
private static String paddedValue(final long value, final boolean padWithZeros, final int count) {
|
||||
final String longString = Long.toString(value);
|
||||
return padWithZeros ? StringUtils.leftPad(longString, count, '0') : longString;
|
||||
}
|
||||
|
||||
static final Object y = "y";
|
||||
static final Object M = "M";
|
||||
static final Object d = "d";
|
||||
|
|
|
@ -519,7 +519,17 @@ public class DurationFormatUtilsTest {
|
|||
new int[] { 1997, 1, 28, 0, 0, 0 }, "M d");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLANG984() { // Long durations
|
||||
assertEquals("0", DurationFormatUtils.formatDuration(0, "S"));
|
||||
assertEquals(Integer.toString(Integer.MAX_VALUE), DurationFormatUtils.formatDuration(Integer.MAX_VALUE, "S"));
|
||||
long maxIntPlus=Integer.MAX_VALUE;
|
||||
maxIntPlus++;
|
||||
assertEquals(Long.toString(maxIntPlus), DurationFormatUtils.formatDuration(maxIntPlus, "S"));
|
||||
assertEquals(Long.toString(Long.MAX_VALUE), DurationFormatUtils.formatDuration(Long.MAX_VALUE, "S"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDurationsByBruteForce() {
|
||||
bruteForce(2006, 0, 1, "d", Calendar.DAY_OF_MONTH);
|
||||
|
|
Loading…
Reference in New Issue