¿Por qué el separador de grupos de números de referencia cultural .NET "de-CH" es diferente localmente y en Azure?

Aug 19 2020

Veo un carácter Unicode diferente como separador de grupo de números para la cultura "de-CH" cuando se ejecuta en un escritorio local y en Azure.

Cuando el siguiente código se ejecuta en mi escritorio en .NET Core 3.1 o .NET Framework 4.7.2, genera un resultado 2019que parece un apóstrofe pero no es el mismo.

Cuando se ejecuta en Azure, por ejemplo en https://try.dot.neto (ligeramente modificado) en una función de Azure que se ejecuta en .NET Core 3.1 (en un App Service basado en Windows) da como resultado 0027un apóstrofo ASCII estándar.

using System;
using System.Linq;
using System.Globalization;

Console.WriteLine(((int)(CultureInfo
    .GetCultureInfo("de-CH")
    .NumberFormat
    .NumberGroupSeparator
    .Single())) // Just getting the single character as an int
    .ToString("X4") // unicode value of that character
    );

El resultado de esto es que el intento de analizar la cadena 4'200.000(donde el apóstrofo es Unicode 0027) en el escritorio local usando la cultura "de-CH" falla, pero funciona en Azure.

¿Por qué la diferencia?

Respuestas

NineBerry Sep 04 2020 at 10:55

Este blog de Microsoft de Shawn Steele explica por qué no debe confiar en que una configuración cultural específica sea estable (se cita en su totalidad porque ya no está en línea en MSDN):

https://web.archive.org/web/20190110065542/https://blogs.msdn.microsoft.com/shawnste/2005/04/05/culture-data-shouldnt-be-considered-stable-except-for-invariant/

Los datos de CultureInfo y RegionInfo representan una preferencia cultural, regional, de administrador o de usuario para entornos culturales. Las aplicaciones NO deben hacer suposiciones que dependan de que estos datos sean estables. La única excepción (esta es una regla, por lo que, por supuesto, hay una excepción) es para CultureInfo.InvariantCulture. Se supone que CultureInfo.InvariantCulture permanece estable, incluso entre versiones.

Hay muchas razones por las que los datos culturales pueden cambiar. Con Whidbey y Custom Cultures, la lista se alarga un poco más.

  • La razón más obvia es que hay un error en los datos y tuvimos que hacer un cambio. (Lo crea o no, cometemos errores ;-)) En este caso, nuestros usuarios (y los suyos también) quieren datos culturalmente correctos, por lo que tenemos que corregir el error incluso si rompe las aplicaciones existentes.
  • Otra razón es que las preferencias culturales pueden cambiar. Hay muchas formas en que esto puede suceder, pero sucede:
    • La conciencia global, el intercambio cultural, el papel cambiante de las computadoras, etc., pueden afectar una preferencia cultural.
    • Los tratados internacionales, el comercio, etc. pueden cambiar valores. La adopción del euro cambió el símbolo de la moneda de muchos países a €.
    • Las regulaciones nacionales o regionales también pueden afectar estos valores.
    • La ortografía preferida de las palabras puede cambiar con el tiempo.
    • Los formatos de fecha preferidos, etc. pueden cambiar.
  • Pueden existir múltiples preferencias para una cultura. La mejor opción preferida puede cambiar con el tiempo.
  • Los usuarios pueden haber anulado algunos valores, como los formatos de fecha u hora. Estos se pueden solicitar sin que el usuario las anule, sin embargo, recomendamos que las aplicaciones consideren usar las anulaciones del usuario.
  • Los usuarios o administradores podrían haber creado una cultura de reemplazo, reemplazando los valores predeterminados comunes para una cultura con variaciones específicas de la empresa, regionales específicas u otras variaciones de los datos estándar.
    • Algunas culturas pueden tener preferencias que varían según el entorno. Una empresa puede tener una forma más formal que un cibercafé.
    • Una empresa puede requerir un formato de fecha o de hora específico para toda la organización.
  • Diferentes versiones de la misma cultura personalizada, o una que es personalizada en una máquina y una cultura solo de Windows en otra máquina.

Entonces, si formatea una cadena con un formato de fecha / hora en particular, y luego intenta analizarla más tarde, el análisis puede fallar si la versión cambió, si la máquina cambió, si la versión del marco cambió (datos más nuevos) o si una cultura personalizada fue cambiado. Si necesita conservar los datos en un formato confiable, elija un método binario, proporcione su propio formato o use InvariantCulture.

Incluso sin cambiar los datos, recordar usar Invariant sigue siendo una buena idea. Si tiene diferentes. y, sintaxis para algo como 1,000.29, entonces Parsing puede confundirse si un cliente esperaba 1,000,29. He visto este problema con aplicaciones que no se dieron cuenta de que la cultura de un usuario sería diferente a la cultura del desarrollador. El uso de Invariant u otra técnica resuelve este tipo de problema.

Por supuesto, no puede tener una visualización "correcta" para el usuario actual y un recorrido de ida y vuelta perfecto si cambian los datos de cultivo. Entonces, en general, recomendaría conservar los datos usando InvariantCulture u otro formato inmutable, y siempre usar las API de formato adecuadas para la visualización. Su aplicación tendrá sus propios requisitos, así que considérelos detenidamente.

Tenga en cuenta que para la intercalación (orden de clasificación / comparaciones), incluso el comportamiento Invariante puede cambiar. Deberá utilizar el control de versiones de clasificación para solucionarlo si necesita órdenes de clasificación consistentemente estables.

Si necesita analizar datos automáticamente formateados para que sean fáciles de usar, existen dos enfoques:

  • Permita que el usuario especifique explícitamente el formato utilizado.
  • Primero elimine todos los caracteres excepto los dígitos, el signo menos y el separador decimal de la cadena antes de intentar analizar esto. Tenga en cuenta que primero debe conocer el separador decimal correcto. No hay forma de adivinar esto correctamente y adivinar mal podría resultar en problemas importantes.

Siempre que sea posible, trate de evitar analizar números formateados para que sean fáciles de usar. En su lugar, siempre que sea posible, intente solicitar números en un formato estrictamente definido (invariante).