CultureInfo's NumberFormat.PercentPositivePattern has been changed on my Windows 10 Machine

702 views Asked by At

While selenium testing a .net core application on my local machine, I noticed that my percent strings (.ToString("p2")) were showing no space between the number and the %, different from our testing server's page. After some research, it seems the Culture info has been changed somehow on my Windows 10 box. Does anyone know how to reset it back to the defaults? Or change the settings?

get-culture

LCID             Name             DisplayName
----             ----             -----------
1033             en-US            English (United States)


(get-culture).NumberFormat

CurrencyDecimalDigits    : 2
CurrencyDecimalSeparator : .
IsReadOnly               : True
CurrencyGroupSizes       : {3}
NumberGroupSizes         : {3}
PercentGroupSizes        : {3}
CurrencyGroupSeparator   : ,
CurrencySymbol           : $
NaNSymbol                : NaN
CurrencyNegativePattern  : 0
NumberNegativePattern    : 1
PercentPositivePattern   : 1
PercentNegativePattern   : 1
NegativeInfinitySymbol   : -∞
NegativeSign             : -
NumberDecimalDigits      : 2
NumberDecimalSeparator   : .
NumberGroupSeparator     : ,
CurrencyPositivePattern  : 0
PositiveInfinitySymbol   : ∞
PositiveSign             : +
PercentDecimalDigits     : 2
PercentDecimalSeparator  : .
PercentGroupSeparator    : ,
PercentSymbol            : %
PerMilleSymbol           : ‰
NativeDigits             : {0, 1, 2, 3…}
DigitSubstitution        : None

PercentPositivePattern & PercentNegativePattern are set to 1 instead of 0. Also, IsReadOnly seems to be true when other boxes show false.

Checked my region info. Everything looks correct.

1

There are 1 answers

0
mklement0 On BEST ANSWER

Indeed, the formatting of percentages in the en-US culture has changed in a recent version of Windows 10:[1]

Windows 7:

PS> (1).ToString("p2")
100.00 %  # Space between number and "%"

Windows 10, version 1903:

PS> (1).ToString("p2")
100.00%   # NO space between number and "%"

To get the old behavior back for the current thread only (not globally, and not persistently), you can do the following:

$c = [cultureinfo]::CurrentCulture.Clone()  # Clone the current culture.
$c.NumberFormat.PercentPositivePattern = 0  # Select the old percentage format.
$c.NumberFormat.PercentNegativePattern = 0  # For negative percentages too.
[cultureinfo]::CurrentCulture = $c  # Make the cloned culture the current one.

Thereafter, (1).Tostring('p2') again yields 100 %.

Note: In Windows PowerShell / .NET Framework, you can also modify the properties of [cultureinfo]::CurrentCulture directly (no cloning required). While that simplifies the solution, note that it is no longer supported in PowerShell Core / .NET Core, where the predefined cultures are read-only.

# Windows PowerShell / .NET Framework (as opposed to  .NET Core) ONLY
PS> [CultureInfo]::CurrentCulture.NumberFormat.PercentPositivePattern = 0; (1).ToString("p2")
100.00 %

Taking a step back:

As Eric MSFT notes:

Culture-specific formatting can and will change over time.

For stability of formats across times and cultures you should use the the invariant culture, InvariantCulture (emphasis added):

Unlike culture-sensitive data, which is subject to change by user customization or by updates to the .NET Framework or the operating system, invariant culture data is stable over time and across installed cultures and cannot be customized by users. This makes the invariant culture particularly useful for operations that require culture-independent results, such as formatting and parsing operations that persist formatted data, or sorting and ordering operations that require that data be displayed in a fixed order regardless of culture.


[1] Sean1215 (the OP) reports that the change must have occurred sometime after OS build 14393 and before 16299. Due to different group-policy-based Windows update schedules across teams in his organization, his machine happened to use a more recent build than that of colleagues'.