From 7f0f508d2c842f80efee9e03a6656f5adb424c3e Mon Sep 17 00:00:00 2001 From: jpawlowski Date: Thu, 13 Jun 2019 23:11:25 +0000 Subject: [PATCH] UConv: use locale for decimal_mark git-svn-id: https://svn.fhem.de/fhem/trunk@19614 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/UConv.pm | 71 ++++++++++++++++++++++++++++------------------ fhem/FHEM/Unit.pm | 4 +-- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/fhem/FHEM/UConv.pm b/fhem/FHEM/UConv.pm index dddfa0bea..b0fb758cc 100644 --- a/fhem/FHEM/UConv.pm +++ b/fhem/FHEM/UConv.pm @@ -20,22 +20,6 @@ use Time::Local; my $DEG = pi / 180.0; my $RAD = 180. / pi; -my %roman = ( - 1 => 'I', - 5 => 'V', - 10 => 'X', - 50 => 'L', - 100 => 'C', - 500 => 'D', - 1000 => 'M', - 5000 => '(V)', - 10000 => '(X)', - 50000 => '(L)', - 100000 => '(C)', - 500000 => '(D)', - 1000000 => '(M)', -); - sub GetSeason (;$$$); sub _GetSeasonPheno ($$;$$); sub _ReplaceStringByHashKey($$;$); @@ -1066,6 +1050,22 @@ sub arabic2roman ($) { return $n if ( $n >= 1000001. ); # numbers above cannot be displayed/converted + my %roman = ( + 1 => 'I', + 5 => 'V', + 10 => 'X', + 50 => 'L', + 100 => 'C', + 500 => 'D', + 1000 => 'M', + 5000 => '(V)', + 10000 => '(X)', + 50000 => '(L)', + 100000 => '(C)', + 500000 => '(D)', + 1000000 => '(M)', + ); + for my $v ( sort { $b <=> $a } keys %roman ) { my $c = int( $n / $v ); next unless ($c); @@ -2088,19 +2088,34 @@ sub _GetSeasonPheno ($$;$$) { #################### # HELPER FUNCTIONS -sub decimal_mark ($$) { - my ( $val, $f ) = @_; - return $val unless ( looks_like_number($val) && $f ); +sub decimal_mark ($;$) { + return $_[0] unless ( looks_like_number($_[0]) ); + my $d = reverse $_[0]; + my $locale = ( $_[1] ? $_[1] : undef ); - my $text = reverse $val; - if ( $f eq "2" ) { - $text =~ s:\.:,:g; - $text =~ s/(\d\d\d)(?=\d)(?!\d*,)/$1./g; - } - else { - $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; - } - return scalar reverse $text; + my $old_locale = setlocale(LC_NUMERIC); + setlocale(LC_NUMERIC, $locale) if ($locale); + use locale ':not_characters'; + my ( $decimal_point, $thousands_sep, $grouping ) = + @{ localeconv() }{ 'decimal_point', 'thousands_sep', 'grouping' }; + setlocale(LC_NUMERIC, ""); + setlocale(LC_NUMERIC, $old_locale); + no locale; + + $thousands_sep = ($decimal_point && $decimal_point eq ',' ? '.' : ',') + unless ($thousands_sep); + my @grouping = + $grouping && $grouping =~ /^\d+$/ ? unpack( "C*", $grouping ) : (3); + + if ( $thousands_sep eq '.' ) { + $d =~ s/\./$decimal_point/g; + $d =~ s/(\d{$grouping[0]})(?=\d)(?!\d*,)/$1$thousands_sep/g; + } + else { + $d =~ s/(\d{$grouping[0]})(?=\d)(?!\d*\.)/$1$thousands_sep/g; + } + + return scalar reverse $d; } sub _round($;$) { diff --git a/fhem/FHEM/Unit.pm b/fhem/FHEM/Unit.pm index f00c5cc64..ffdd3ad15 100644 --- a/fhem/FHEM/Unit.pm +++ b/fhem/FHEM/Unit.pm @@ -3391,7 +3391,7 @@ sub replaceTemplate ($$$$;$) { my $vdm = $desc->{$k}; next if ( ref($vdm) ); - $vdm = UConv::decimal_mark( $vdm, $desc->{decimal_mark} ) + $vdm = UConv::decimal_mark( $vdm ) if ( defined( $desc->{decimal_mark} ) ); $txt =~ s/%$k%/$vdm/g; Unit_Log3( $device, $reading, $odesc, 10, @@ -3466,7 +3466,7 @@ sub replaceTemplate ($$$$;$) { my $vdm = $desc->{$k}; next if ( ref($vdm) ); - $vdm = UConv::decimal_mark( $vdm, $desc->{decimal_mark} ) + $vdm = UConv::decimal_mark( $vdm ) if ( defined( $desc->{decimal_mark} ) ); $txt_long =~ s/%$k%/$vdm/g; Unit_Log3( $device, $reading, $odesc, 10,