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
// possible precision loss;
// otherwise as a double.
if (numberString.matches("[0-9]+")) {
if (numberString.matches("[+-]?[0-9]+")) {
return units.toNanos(Long.parseLong(numberString));
} else {
long nanosInUnit = units.toNanos(1);

View File

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

View File

@ -765,6 +765,9 @@ class ConfigTest extends TestUtils {
assertEquals(Seq(asNanos(1), asNanos(2), asNanos(3), asNanos(4)),
conf.getNanosecondsList("durations.secondsList").asScala)
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
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)),
conf.getDurationList("durations.secondsList").asScala.map(_.toNanos))
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 ns2unit(l: Long) = unit.convert(l, NANOSECONDS)
def ms2unit(l: Long) = unit.convert(l, MILLISECONDS)
def s2unit(i: Int) = unit.convert(i, SECONDS)
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(1L), conf.getDuration("durations.millis", 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)