Newsgroup: it.comp.www.php
Titolo: impostazioni locali e numeri...

- Sistema operativo Windows XP Home
- Apache 2.2.3
- PHP 5.2.0
////////////////inizio codice////////////////
echo "<pre>";
$impostazione_locale=setlocale(LC_ALL,"ita_ITA");
echo $impostazione_locale."<br>";
$numero=0.0+"1234.56";
echo (float)$numero."<br>";
printf("Indipentente dalle impostazioni locali: %F \n",$numero);
printf("Dipentente dalle impostazioni locali: %f \n",$numero);
$x=localeconv();
print_r($x);
echo "</pre>";
////////////////fine codice////////////////
1) Perché, nonostante il [thousands_sep] sia il punto ".", nella 
visualizzazione esso non appare?
2) Perché se imposto come valore di stringa "ita_ita.iso-8859-1" non mi 
assegna la codifica che voglio, ma mi dà sempre la windows 1252?
3) In pratica, come faccio per visualizzare un numero nel formato che 
voglio io?
4) Infine, in php quando scrivo un numero in virgola mobile, questo 
_DEVE_ necessariamente avere il separatore decimale con il punto e 
_NON-DEVE_ avere il separatore delle migliaia?
--
rob4you

 _NON-DEVE_ avere il separatore delle migliaia?
Se intendi 
$a = 12.34;
si`, deve avere il punto decimale (e non la virgola) e non deve avere il
separatore per le migliaia.
Se intendi convertirlo da una stringa, mi sa che devi farti un parser.
Non credo esistano funzioni di conversione localizzate.
Bye.

 Non credo esistano funzioni di conversione localizzate.
Ahia....il problema è proprio questo.
Come espresso in un post precedente intitolato "number_format", un 
utente per scrivere ad esempio il numero float 
"milleduecentotrentaquattro virgola cinquantasei" potrebbe scrivere:
"1234.56"
"1234,56"
"1.234,56"
"1,234.56"
"1 234,56"
"1 234.56"
Solo che la sintassi corretta di un numero float è solo la prima 
"1234.56".
Credo che con qualche espressione regolare e opportuni replacement ci 
si potrebbe in ogni caso ricondurre alla forma corretta, però è un 
peccato che non ci siano funzioni di conversione localizzate.
A parte questo, ciò che non mi torna è la cosa seguente.
Se io eseguo lo script che ho postato nel messaggio precedente (su 
sistema windows, su altri non ho ancora provato), mi dà il seguente 
output:
///////////////////Inizio output///////////////////
Italian_Italy.1252
1234,56
Indipentente dalle impostazioni locali: 1234.560000
Dipentente dalle impostazioni locali: 1234,560000
Array
(
    [decimal_point] => ,
    [thousands_sep] => .
    [int_curr_symbol] => EUR
    [currency_symbol] => €
    [mon_decimal_point] => ,
    [mon_thousands_sep] => .
    [positive_sign] =>
    [negative_sign] => -
    [int_frac_digits] => 2
    [frac_digits] => 2
    [p_cs_precedes] => 1
    [p_sep_by_space] => 1
    [n_cs_precedes] => 1
    [n_sep_by_space] => 1
    [p_sign_posn] => 3
    [n_sign_posn] => 3
    [grouping] => Array
        (
            [0] => 3
        )
    [mon_grouping] => Array
        (
            [0] => 3
        )
)
///////////////////Fine output///////////////////
Bene, cioè *MALE*: la cosa che _NON_ mi torna è che come puoi vedere il 
[thousands_sep] è il punto "." (come giustamente in accordo a 
impostazioni italiane). MA il numero stampato a video è "1234,560000": 
cioè il separatore decimale [decimal_point] è correttamente per le 
impostazioni italiane la virgola "," mentre invece _MANCA_ il 
separatore delle migliaia (che dovrebbe essere il punto in accordo a 
quanto detto prima)!!!!  Perché questo comportamento? Mi sfugge 
qualcosa??
--
rob4you
www.outofmind.eu

 comportamento? Mi sfugge qualcosa??
Non hai nessuna idea in proposito a questo comportamento?
--
rob4you



Oggi sono un po' incasinato col lavoro, e volevo prima assicurarmi di una
cosa... :)
Non mi ricordavo che printf fosse localizzato. :)
Comunque ho provato sul mio sistema (Linux, pero`), e dopo aver
controllato con "locale -a" cosa era supportato, l'ho messo nel tuo
script, e funziona senza problemi (nel mio caso e` "it_IT@euro" o
"it_IT.iso885915@euro". Pero` il mio locale non definisce il separatore
delle migliaia, solo quello dei decimali.
A questo punto penso sia solo un problema di quali locale hai installato.
Bye.

 A questo punto penso sia solo un problema di quali locale hai installato.
In windows manca il comando "locale", e per le impostazioni locali 
bisogna andare a pescare dal pannello di controllo la voce "Opzioni 
internazionali e della lingua". Con il pulsante "Personalizza" si può 
poi vedere che, ad esempio, relativamente ai "numeri", per il formato 
"italiano" è utilizzato come "separatore decimale" la virgola "," e 
come "simbolo di raggruppamento cifre" (cioè il separatore delle 
migliaia) il punto ".". Infatti riporta un numero di esempio: 
"123.456.789,00" che come vedi usa il punto per le migliaia e la 
virgola per i decimali.
In accordo a queste impostazioni, quando eseguo la print_r di 
"localeconv()", mi dice, tra le altre cose:
    [decimal_point] => ,
    [thousands_sep] => .
in accordo a quanto su visto.
MA, quando gli chiedo di rappresentarmi un numero (es. "1234.56"), con 
le impostazioni "localizzate" (e cioè usando il %f nella printf), php 
sembra dimenticare di avere come impostazione per il [thousands_sep] il 
punto "." e ahimé mi dà in output "1234,560000" anziché "1.234,560000".
Ma non riesco proprio a capirne il motivo!!!
Tu mi dici che su linux il separatore delle migliaia non c'è proprio in 
"it_IT". Sarebbe interessante trovare un locale che abbia invece il 
separatore delle migliaia incluso, e vedere se php lo fa visualizzare o 
meno.
Che sia un "buco" (per la versione win)? :-)
--
rob4you

 Che sia un "buco" (per la versione win)? :-)
Mi sa che e` un buco di php in generale, non solo Win... :/
Ma anche nel bugtracker non trovo niente. O non se n'e` accorto nessuno o
l'hanno chiuso o marcato bogus.
Bye.

 l'hanno chiuso o marcato bogus.
Di discussioni "bugs" relativi al setlocale io qualcuna ne ho trovata.
Una cosa "terribile" è all'indirizzo:
http://bugs.php.net/bug.php?id=17079
Ti riporto il codice dell'esempio incriminato:
<?
$rate1 = 1.123;
$amount1 = 5;
$rate2 = "1.123";
$amount2 = "5";
// set locale to English to handle the floatingpoints correctly
// first calculation with floats
setlocale (LC_ALL, 'en_US');
echo "This should be correct:<br><br>";
echo $rate1." * ".$amount1." = ".($rate1*$amount1);
// second calculation with floats converted from strings
echo "<br><br>This should be correct as well:<br><br>";
echo $rate2." * ".$amount2." = ".($rate2*$amount2);
// set locale to Dutch to show misbehaviour
// first calculation with floats
setlocale (LC_ALL, 'nl_NL');
echo "<br><br>This should still be correct:<br><br>";
echo $rate1." * ".$amount1." = ".($rate1*$amount1);
// second calculation with floats converted from strings
echo "<br><br>This should be wrong:<br><br>";
echo $rate2." * ".$amount2." = ".($rate2*$amount2);
?>
Ecco l'output:
//////////////////////////////////////////////
This should be correct:
1234.567 * 2 = 2469.134
This should be correct as well:
1234.567 * 2 = 2469.134
This should still be correct:
1234,567 * 2 = 2469,134
This should be wrong:
1234.567 * 2 = 2469,134
//////////////////////////////////////////////
Assurdo, l'ultima riga mostra il numero "1234.567" anziché "1234,567".
E meno male che dicevano di averlo risolto questo bug già nel 2002!!!
Io sto usando la 5.2.0 e come vedi l'output è ancora errato.
Per non parlare appunto del problema del separatore delle migliaia, di 
cui tutto "tace". :-(
--
rob4you
www.outofmind.eu

 Assurdo, l'ultima riga mostra il numero "1234.567" anziché "1234,567".
Mi correggo da solo, ma solo riguardo questa frase :-) è ovvio che il 
numero "1234.567" sia rappresentato con il punto, perché qui è visto 
come una stringa e non come un numero.
Definendolo come $num=0+"1234.567" (o usando floatval ad esempio, o il 
casting forzato) va tutto ok.
Resta però il problema del separatore delle migliaia.
Intanto ho notificato il probabile bug. Vediamo se diranno qualcosa.
--
rob4you
www.outofmind.eu

 Intanto ho notificato il probabile bug. Vediamo se diranno qualcosa.
Mi è stato detto che _NON_ è un bug, perché dicono che se voglio avere 
il separatore delle migliaia devo usare number_format.
IMHO è un'assurdità il fatto che, se imposto un locale che ha punto 
come separatore delle migliaia, e virgola come separatore decimale, e 
faccio:
echo sprintf("%f",1234.56);
mi dà
1234,56
cioè _IMPOSTA_ il separatore decimale locale, e _DIMENTICA_ quello 
delle migliaia.
A questo punto....se loro dicono che esiste la funzione 
number_format....l'uso di %f è una cacata inutile, visto che comunque 
ad esempio non si possono nemmeno eseguire operazioni numeriche sulla 
stringa restituita da quella sprintf (in quanto un float deve essere 
sempre rappresentato con il punto e basta), né dalla number_format.
MAH....speriamo un giorno ci ripensino.
--
rob4you
www.outofmind.eu