Avoid precision loss for signed duration

This commit is contained in:
kxbmap 2016-04-06 07:53:40 +09:00
parent 1d01e52c94
commit 2d1553e52e
3 changed files with 15 additions and 2 deletions

View File

@ -610,7 +610,7 @@ final class SimpleConfig implements Config, MergeableValue, Serializable {
// if the string is purely digits, parse as an integer to avoid // if the string is purely digits, parse as an integer to avoid
// possible precision loss; // possible precision loss;
// otherwise as a double. // otherwise as a double.
if (numberString.matches("[0-9]+")) { if (numberString.matches("[+-]?[0-9]+")) {
return units.toNanos(Long.parseLong(numberString)); return units.toNanos(Long.parseLong(numberString));
} else { } else {
long nanosInUnit = units.toNanos(1); long nanosInUnit = units.toNanos(1);

View File

@ -59,7 +59,10 @@
"secondAsNumber" : 1000, "secondAsNumber" : 1000,
"halfSecond" : 0.5s, "halfSecond" : 0.5s,
"millis" : 1 milli, "millis" : 1 milli,
"micros" : 2000 micros "micros" : 2000 micros,
"largeNanos" : 4878955355435272204ns,
"plusLargeNanos" : "+4878955355435272204ns",
"minusLargeNanos" : -4878955355435272204ns
}, },
"memsizes" : { "memsizes" : {

View File

@ -765,6 +765,9 @@ class ConfigTest extends TestUtils {
assertEquals(Seq(asNanos(1), asNanos(2), asNanos(3), asNanos(4)), assertEquals(Seq(asNanos(1), asNanos(2), asNanos(3), asNanos(4)),
conf.getNanosecondsList("durations.secondsList").asScala) conf.getNanosecondsList("durations.secondsList").asScala)
assertEquals(500L, conf.getMilliseconds("durations.halfSecond")) assertEquals(500L, conf.getMilliseconds("durations.halfSecond"))
assertEquals(4878955355435272204L, conf.getNanoseconds("durations.largeNanos"))
assertEquals(4878955355435272204L, conf.getNanoseconds("durations.plusLargeNanos"))
assertEquals(-4878955355435272204L, conf.getNanoseconds("durations.minusLargeNanos"))
// get durations as java.time.Duration // get durations as java.time.Duration
assertEquals(1000L, conf.getDuration("durations.second").toMillis) assertEquals(1000L, conf.getDuration("durations.second").toMillis)
@ -776,8 +779,12 @@ class ConfigTest extends TestUtils {
assertEquals(Seq(asNanos(1), asNanos(2), asNanos(3), asNanos(4)), assertEquals(Seq(asNanos(1), asNanos(2), asNanos(3), asNanos(4)),
conf.getDurationList("durations.secondsList").asScala.map(_.toNanos)) conf.getDurationList("durations.secondsList").asScala.map(_.toNanos))
assertEquals(500L, conf.getDuration("durations.halfSecond").toMillis) assertEquals(500L, conf.getDuration("durations.halfSecond").toMillis)
assertEquals(4878955355435272204L, conf.getDuration("durations.largeNanos").toNanos)
assertEquals(4878955355435272204L, conf.getDuration("durations.plusLargeNanos").toNanos)
assertEquals(-4878955355435272204L, conf.getDuration("durations.minusLargeNanos").toNanos)
def assertDurationAsTimeUnit(unit: TimeUnit): Unit = { def assertDurationAsTimeUnit(unit: TimeUnit): Unit = {
def ns2unit(l: Long) = unit.convert(l, NANOSECONDS)
def ms2unit(l: Long) = unit.convert(l, MILLISECONDS) def ms2unit(l: Long) = unit.convert(l, MILLISECONDS)
def s2unit(i: Int) = unit.convert(i, SECONDS) def s2unit(i: Int) = unit.convert(i, SECONDS)
assertEquals(ms2unit(1000L), conf.getDuration("durations.second", unit)) assertEquals(ms2unit(1000L), conf.getDuration("durations.second", unit))
@ -791,6 +798,9 @@ class ConfigTest extends TestUtils {
assertEquals(ms2unit(500L), conf.getDuration("durations.halfSecond", unit)) assertEquals(ms2unit(500L), conf.getDuration("durations.halfSecond", unit))
assertEquals(ms2unit(1L), conf.getDuration("durations.millis", unit)) assertEquals(ms2unit(1L), conf.getDuration("durations.millis", unit))
assertEquals(ms2unit(2L), conf.getDuration("durations.micros", unit)) assertEquals(ms2unit(2L), conf.getDuration("durations.micros", unit))
assertEquals(ns2unit(4878955355435272204L), conf.getDuration("durations.largeNanos", unit))
assertEquals(ns2unit(4878955355435272204L), conf.getDuration("durations.plusLargeNanos", unit))
assertEquals(ns2unit(-4878955355435272204L), conf.getDuration("durations.minusLargeNanos", unit))
} }
assertDurationAsTimeUnit(NANOSECONDS) assertDurationAsTimeUnit(NANOSECONDS)