Locales in command line

I want a command line program consider my current locale. If the program is running in Germany, the decimal separator for float numbers should be a comma.

print(Locale.current.identifier) // de_DE ✔️
print(String(format: "%.1f",
             locale: Locale.current, 0.5)) // 0.5 ✖️
print(String(format: "%.1f",
             locale: Locale(identifier: Locale.current.identifier), 0.5)) // 0,5 ✔️
  1. The locale is correctly recognized: de_DE
  2. Direct input of Locale.current doesn't work! (Dot instead of comma)
  3. Creating new Locale with Locale.current.identifier works!

(Same behavior when using NumberFormatter)

Could somebody explain this behavior? A bug?

Interesting. I get only the (expected) output 0,5, both in a Swift REPL and in a command-line application:

% cat x.swift
import Foundation

print(Locale.current.identifier)
print(String(format: "%.1f", locale: Locale.current, 0.5))
print(String(format: "%.1f", locale: Locale(identifier: Locale.current.identifier), 0.5))

% swift < x.swift 
Welcome to Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29).
Type :help for assistance.
de_DE
0,5
0,5

Then what goes awry on my Computer? Can I rely on Locale.current when using Swift for the command line?
That's my REPL output with the same problem as before:

% cat y.swift 
import Foundation

print(Locale.current.identifier)
print(String(format: "%.1f",
             locale: Locale.current, 0.5))
print(String(format: "%.1f",
             locale: Locale(identifier: Locale.current.identifier), 0.5))

% swift < y.swift 
Welcome to Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29).
Type :help for assistance.
de_DE
0.5
0,5

Some informations about my system:

% locale
LANG="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_CTYPE="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_ALL=

% system_profiler SPSoftwareDataType
Software:

    System Software Overview:

      System Version: macOS 10.15.4 (19E287)
      Kernel Version: Darwin 19.4.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal
      Computer Name:
      User Name:
      Secure Virtual Memory: Enabled
      System Integrity Protection: Enabled
      Time since boot: 4 days 9:48

After changing the language settings on my computer several times back and forth, the program suddenly shows the expected behavior and the decimal comma appears correctly. I don't know why...

The region itself only directly affects a few things, such as the names of the months. When you change it with the system preferences interface, it changes a lot of other things under the hood too according to the defaults for that region. But most of that other stuff can be overridden. For example, I could select German but then override the date format to correspond to that of English, and the result would be be März 13, 2020. Or I could manually set the decimal and thousands separators to 0 as a prank. All of these customizations would be picked up by Locale.current, even though the underling identifier wouldn’t change.

My guess is you had the decimal separator overridden in the system settings (on purpose or by accident). When you switched the language to something else and back again, it restored everything to the intended language’s defaults.

(And creating a locale from an identifier initializes it with the defaults, which is why the third line of your code doesn’t take the customizations into account.)

6 Likes

You are absolutely right. That's definitely the reason! Thank you!

:scream::scream::pleading_face:

1 Like