Con un navegador, ¿cómo sé qué separador decimal usa el sistema operativo?

6 minutos de lectura

Avatar de usuario de Quassnoi
quassnoi

Estoy desarrollando una aplicación Web.

Necesito mostrar algunos datos decimales correctamente para que puedan copiarse y pegarse en una determinada aplicación GUI que no está bajo mi control.

La aplicación GUI es sensible a la configuración regional y solo acepta el separador decimal correcto que está configurado en el sistema.

Puedo adivinar el separador decimal de Accept-Language y la conjetura será correcta en el 95% de los casos, pero a veces falla.

¿Hay alguna forma de hacerlo en el lado del servidor (preferiblemente, para que pueda recopilar estadísticas) o en el lado del cliente?

Actualizar:

El objetivo de la tarea es hacerlo automáticamente.

De hecho, esta aplicación web es una especie de interfaz en línea para una GUI heredada que ayuda a completar los formularios correctamente.

El tipo de usuarios que lo usan en su mayoría no tienen idea de qué es un separador decimal.

El Accept-Language La solución está implementada y funciona, pero me gustaría mejorarla.

Actualización2:

Necesito recuperar una configuración muy específica: separador decimal establecido en Panel de control/Opciones regionales y de idioma/Opciones regionales/Personalizar.

Trato con cuatro tipos de sistemas operativos:

  1. Windows ruso con una coma como DS (80%).
  2. Inglés Windows con un punto como DS (15%).
  3. Windows ruso con un punto como DS para hacer funcionar aplicaciones en inglés mal escritas (4%).
  4. Windows en inglés con una coma como DS para hacer que funcionen las aplicaciones rusas mal escritas (1%).

Todos los clientes se encuentran en Rusia y la aplicación heredada se ocupa de los formularios emitidos por el gobierno ruso, por lo que solicitar un país arrojará el 100 % de la Federación Rusa y GeoIP arrojará el 80 % de la Federación Rusa y el 20 % de otras respuestas (incorrectas).

Avatar de usuario de Chris Nielsen
chris nielsen

Aquí hay una función de JavaScript simple que devolverá esta información. Probado en Firefox, IE6 e IE7. Tuve que cerrar y reiniciar mi navegador entre cada cambio en la configuración en Panel de control/Opciones regionales y de idioma/Opciones regionales/Personalizar. Sin embargo, recogió no solo la coma y el punto, sino también cosas extrañas personalizadas, como la letra “a”.

function whatDecimalSeparator() {
    var n = 1.1;
    n = n.toLocaleString().substring(1, 2);
    return n;
}
function whatDecimalSeparator() {
    var n = 1.1;
    n = n.toLocaleString().substring(1, 2);
    return n;
}

console.log('You use "' + whatDecimalSeparator() + '" as Decimal seprator');

¿Esto ayuda?

  • Esto funcionó para mí en Firefox e IE8, pero no en Google Chrome. No tengo Ópera.

    – Mateo Talbert

    20 de agosto de 2009 a las 20:04

  • @Matthew: funcionó para mí en Chrome. @Quassnoi: no entiendo lo que significa el último comentario. Si está diciendo que la función no funciona, entonces ¿qué importa lo que la persona sepa?

    – Matchú

    11 de mayo de 2010 a las 1:27

  • ¡Cuidado! En Chrome, toLocaleString solo funciona correctamente si se llama directamente a un número. En mi sistema: [1.1,1.2].toLocaleString() -> “1.1,1.2” | (1.1).toLocaleString() -> “1,1”

    – Tarnay Kalman

    23 de agosto de 2013 a las 16:41


  • La función falla en las configuraciones regionales que usan más de un carácter para su DecimalSeparator (p.ej ,,). ventanas LOCALE_SDECIMAL permite que un separador decimal contenga hasta tres caracteres. (Por eso falla en mi PC). Mejor usar el Accept-Language del navegador en ese caso. Lo que todavía no tiene en cuenta la capacidad de especificar sus propios DecimalSeparator p.ej \o/

    – Ian Boyd

    25/09/2013 a las 21:01

  • @IanBoyd tiene razón sobre las configuraciones regionales con una cadena de más de un carácter como separador decimal, pero n = /^1(.+)1$/.exec(n.toLocaleString())[1] lo haría, y es más fácil que usar el Accept-Language encabezamiento.

    – ygormutti

    30 de abril de 2014 a las 12:56


Es posible recuperar separadores para la configuración regional actual o dada usando Intl.NumberFormat#formatToParts.

function getDecimalSeparator(locale) {
    const numberWithDecimalSeparator = 1.1;
    return Intl.NumberFormat(locale)
        .formatToParts(numberWithDecimalSeparator)
        .find(part => part.type === 'decimal')
        .value;
}

Solo funciona para navegadores compatibles con la API internacional. De lo contrario, requiere un polirelleno internacional

Ejemplos:

> getDecimalSeparator()
"."
> getDecimalSeparator('fr-FR')
","

Prima:

Podríamos extenderlo para recuperar el decimal o grupo separador de un lugar dado:

function getSeparator(locale, separatorType) {
        const numberWithGroupAndDecimalSeparator = 1000.1;
        return Intl.NumberFormat(locale)
            .formatToParts(numberWithGroupAndDecimalSeparator)
            .find(part => part.type === separatorType)
            .value;
    }

Ejemplos:

> getSeparator('en-US', 'decimal')
"."
> getSeparator('en-US', 'group')
","
> getSeparator('fr-FR', 'decimal')
","
> getSeparator('fr-FR', 'group')
" "

  • Actualmente, esta es la forma más adecuada de obtener dicha información. POR CIERTO Intl es compatible incluso en IE 11: caniuse.com/#feat=internacionalización

    – Konstantin Smolyanin

    25 de septiembre de 2018 a las 13:03

  • Esto no funcionará en IE 11 ya que formatToParts no es compatible.

    – Gajendra Kumar

    4 de marzo de 2019 a las 9:45

avatar de usuario de user3023011
usuario3023011

Por qué no

console.log(0.1.toLocaleString().replace(/\d/g, ''));

  • ¿tal vez algún lugar extraño puede omitir el cero inicial? Prefiero tener uno allí, solo para estar seguro.

    – Juangui Jordán

    1 de junio de 2017 a las 11:04

  • Me gusta que el pensamiento lateral mire lo que está haciendo el navegador en lugar de lo que se le ha dicho. Pero di mi voto positivo a la respuesta de @ashleedawg, actualmente a continuación, porque tiene la implementación que encuentro más fácil.

    – zsalya

    6 sep 2022 a las 11:17

avatar de usuario de laalto
laalto

Pregunta al usuario, no adivines. Tenga una configuración para ello en su aplicación web.

Editado para agregar:

Creo que está bien adivinar el por defecto configuración que funciona, digamos, el 95% del tiempo. Lo que quise decir es que el usuario aún debería poder anular cualquier suposición que haya hecho el software. Ya me he sentido frustrado demasiadas veces cuando un software intenta ser demasiado inteligente y no permite que se corrija.

function getDecimalSeparator() {
    //fallback  
       var decSep = ".";

        try {
            // this works in FF, Chrome, IE, Safari and Opera
            var sep = parseFloat(3/2).toLocaleString().substring(1,2);
            if (sep === '.' || sep === ',') {
                decSep = sep;
            }
        } catch(e){}

        return decSep;
    }

  • el respaldo a “.” en el caso de algunos navegadores oscuros… de otras maneras es más o menos lo mismo…

    – Dr. Oblak

    3 de febrero de 2015 a las 14:32

Avatar de usuario de Michael Borgwardt
miguel borgwardt

Puedo adivinar el separador decimal de Accept-Language y la conjetura será correcta en el 95% de los casos, pero a veces falla.

Este es, en mi opinión, el mejor curso de acción. Para manejar las fallas, agregue un enlace para configurarlo manualmente al lado del área de visualización.

  • el respaldo a “.” en el caso de algunos navegadores oscuros… de otras maneras es más o menos lo mismo…

    – Dr. Oblak

    3 de febrero de 2015 a las 14:32

Avatar de usuario de Juangui Jordan
Juangui Jordán

Usando las respuestas de otras personas, compilé las siguientes funciones de utilidad de separadores decimales y de miles:

var decimalSeparator = function() {
    return (1.1).toLocaleString().substring(1, 2);
};
var thousandSeparator = function() {
    return (1000).toLocaleString().substring(1, 2);
};

¡Disfrutar!

  • Sí, utilicé este método como polyfill para navegadores que no admiten formatToParts (Safari e IE).

    – Marko Bonaci

    02/09/2019 a las 20:31

  • Algunas configuraciones regionales no usan separadores de miles por debajo de 10000. Por ejemplo (1000).toLocaleString("es-PE") # "1000"

    – Madacol

    5 de febrero de 2020 a las 2:15


  • @Madacol `(1000).toLocaleString(“es-PE”)` actualmente me está dando 1,000 en Chrome, Firefox y Edge. ¿Hay alguna otra configuración que interviene, o se ha corregido/hecho mal en algún momento de los últimos 2,5 años?

    – zsalya

    6 sep 2022 a las 11:15


  • @zsalya ¡probablemente se haya arreglado!, porque Perú no usaba ese formato. Pero aún puedes ver cómo funciona en la versión en español de algunos países no españoles, por ejemplo, la Inglaterra española. (1000).toLocaleString("es-EN") # "1000". Mi punto es que se ha implementado deliberadamente, por lo que probablemente sea cierto para algunas configuraciones regionales.

    – Madacol

    7 sep 2022 a las 12:28


¿Ha sido útil esta solución?