Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force StringUtil.toString(double) method to use Locale.ENGLISH #398

Closed

Conversation

FObermaier
Copy link
Contributor

@FObermaier FObermaier commented Mar 27, 2019

Currently StringUtil.toString(double) function uses Locale.getDefault() to write a double to a String.
This function is being used from within CoordinateSequences.toString(CoordinateSequence) making the output un[read|use]able in environments that have a comma as a decimal seperator (like e.g. german).

This PR contains

  • Fix for StringUtil.toString(double) method to use Locale.ENGLISH
  • Add methods to change decimal format pattern
  • Add unit test

Signed-off-by: Felix Obermaier felix.obermaier@netcologne.de

* Add methods to change decimal format pattern
* Add unit test

Signed-off-by: Felix Obermaier <felix.obermaier@netcologne.de>
@dr-jts
Copy link
Contributor

dr-jts commented Mar 28, 2019

Seems like a good fix. Does this problem affect WKTWriter as well?

@FObermaier
Copy link
Contributor Author

FObermaier commented Mar 28, 2019

No, WKTWriter uses its own DecimalFormat. It is created like this:

private static DecimalFormat createFormatter(PrecisionModel precisionModel) {
// the default number of decimal places is 16, which is sufficient
// to accommodate the maximum precision of a double.
int decimalPlaces = precisionModel.getMaximumSignificantDigits();
// specify decimal separator explicitly to avoid problems in other locales
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator('.');
String fmtString = "0" + (decimalPlaces > 0 ? "." : "")
+ stringOfChar('#', decimalPlaces);
return new DecimalFormat(fmtString, symbols);
}

@dr-jts
Copy link
Contributor

dr-jts commented Mar 28, 2019

Yes, I'm just wondering why the two approaches are so different.

@FObermaier
Copy link
Contributor Author

The only real difference I see is that the WKTWriter sets the number of decimal places according to a PrecisionModel. StringUtil.toString(double) lacks that, instead it always used to print out at most one decimal place ("0.#"). Now that is changable.

WKTWriter could reuse a static DecimalFormatSymbols instance.
StringUtil could adjust its DecimalFormatSymbols like WKTWriter does

@dsmiley
Copy link

dsmiley commented Mar 28, 2019

I recommend Locale.ROOT. In Lucene/Solr we use https://github.com/policeman-tools/forbidden-apis to catch such issues at compile time in a comprehensive way.

@FObermaier
Copy link
Contributor Author

Locale.ROOT is fine for me, seems to be what resembles CultureInfo.InvariantInfo in the dotNet world most.

Allow setting RoundingMode for string conversion.

Signed-off-by: Felix Obermaier <felix.obermaier@netcologne.de>
@dr-jts
Copy link
Contributor

dr-jts commented Apr 9, 2019

I agree 100% that number formating needs to be done more consistently in JTS. I just ran across another place where the formatting is ad hoc and hence wrong for some numbers.

But this should be done in a better place than StringUtil I think. It's probably better off in NumberUtil (and the StringUtil class can delegate to that).

It might make sense for WKTWriter to then use this code as well (which will require a method to set the maximum digits as well).

I'm happy to make a PR for this to replace this one if that's ok with @FObermaier ?

@dr-jts
Copy link
Contributor

dr-jts commented Apr 9, 2019

Is Locale.ROOT guarenteed to use a period as the decimal separator? Wouldn't it be clearer to specify the decimal separator explicitly?

@dr-jts
Copy link
Contributor

dr-jts commented Apr 9, 2019

Is it really necessary to be able to set the rounding mode?

@dr-jts
Copy link
Contributor

dr-jts commented Apr 9, 2019

Hmm.. and apparently DecimalFormat is not thread-safe, which complicates this further. This hasn't been a problem so far to my knowledge, but this kind of issue tends to be subtle.

Perhaps the toString(double) method should be synchronized to avoid potential issues (in spite of the potential performance hit).

@dr-jts
Copy link
Contributor

dr-jts commented Apr 9, 2019

This is also a bug in the WKTWriter static toXXX methods as well.

@FObermaier
Copy link
Contributor Author

@dr-jts, I'm fine totally fine with you creating your own PR

@dr-jts
Copy link
Contributor

dr-jts commented Apr 9, 2019

@dr-jts, I'm fine totally fine with you creating your own PR

Great - working on it now.

@dr-jts
Copy link
Contributor

dr-jts commented Apr 10, 2019

@FObermaier have a look at #409 as an alternative and extension to this PR

@dr-jts
Copy link
Contributor

dr-jts commented Apr 13, 2019

Fixed by #409

@dr-jts dr-jts closed this Apr 13, 2019
@FObermaier FObermaier deleted the fix/StringUtil_with_locale branch April 16, 2019 10:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants