Leniwce.com | blog technologiczny
Separator dziesiętny w C#
Bartosz Lewandowski, 2009-06-29 23:15:23
kategoria: C#

Ustawienia regionalne polskiego systemu Windows jako separator dziesiętny liczb przyjmują symbol przecinka. Oczywiście, każda aplikacja powinna być napisana tak, aby niezależnie od otoczenia działała prawidłowo. Czasami może się więc przydać, by nasza aplikacja korzystała z formatu liczb (czy innego elementu związanego z ustawieniami regionalnymi) wymuszonego przez nas, a nie nadanego przez system.
Kropka może stanowić problem przy konwersji stringów na liczby, czy też przy budowaniu zapytań SQL. W końcu dla SQLa przecinek jest separatorem kolumn w zapytaniu, wykonanie więc zapytania zawierającego liczbę zawierającą separator dziesiętny w postaci przecinka niewątpliwie skończy się błędem. Oczywiście, w przypadku .NET warto wykorzystywać SqlParameter, a nie budować zapytania SQL w stringu. 
Programiści Delphi czy CBuildera dysponują kilkoma zmiennymi globalnymi, które pozwalają na manipulację ustawieniami regionalnymi systemu, takimi jak: DecimalSeparator (separator dziesiętny), ThousandSeparator (separator tysięcy).
W przypadku C# nie mamy takich globalnych zmiennych jak użytkownicy kompilatorów Borlanda. Ale dysponujemy klasą CultureInfo (System.Globalization), która odpowiada za wszelkie ustawienia regionalne. Klasa dostarcza nie tylko informacji o formacie liczb (NumerFormatInfo), ale też o formacie daty i czasu (DateTimeFormatInfo) czy porównywaniu stringów (CompareInfo).

Przejdźmy więc do meritum. Gdy przy standardowych, polskich ustawieniach regionalnych uruchomimy kod:

string testString = "123.45";
double testDouble = Convert.ToDouble(testString);

Otrzymamy komunikat z błędem:
System.FormatException was unhandled
Message="Nieprawidłowy format ciągu wejściowego.”

Przestawmy więc w naszej aplikacji format liczby, wymuśmy kropkę:
//Pobieramy bieżące ustawienia
string currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
CultureInfo ci = new CultureInfo(currentCulture);
//Ustawiamy nowy format
ci.NumberFormat.NumberDecimalSeparator = ".";            
System.Threading.Thread.CurrentThread.CurrentCulture = ci;


Gdy w dalszej częsci aplikacji ponownie przetestujemy nasz kod konwertujący tekst na liczbę, błąd już się nie pojawi. 

Warto zapoznać się z możliwościami wykorzystania klasy CultureInfo. Znajduje się w niej wiele innych formatów do zdefiniowania.

Powiązane artykuły
Atraktor Lorenza (2011-08-29)
Równoległy może więcej(?) - czyli kilka słów o Parallel.For (2011-02-06)
Święta, święta - czas pochwalić się (fraktalną) choinką (2010-12-25)
Własny wygaszacz ekranu (2010-06-03)
3.1415926535897932385... (2010-05-19)
Metody rozszerzające (2010-05-07)
GPS w lekkostrawnym sosie podany (2009-08-05)
Wszechświat na ekranie, czyli słowo o skalowaniu (2009-07-15)
OleDbConnection – Excel jako baza danych(C#) (2009-07-13)
Animacje 3D (OpenGL) (2009-07-05)


Komentarze


kkk [2009-07-02 23:58:33]
jest ok
Paweł [2009-07-14 20:44:07]
Nie robi się czegoś takiego jak wymuszanie kropek. Metody Convert.ToDouble, posiadają przeciążoną wersję dzięki, której można podać IFormatProvider. Jeśli masz liczbę bez żadnego konkretnego formatu używaj kultury InvariantCulture, która jest dostępny we Frameworku i z niego weź NumberFormatProvider.

Trochę więcej do poczytania napisałem w tym pościę na blogu:
http://pawlos.blogspot.com/2009/03/nie-zapominaj-o-kulturze.html

Pozdrawiam,
Paweł
Tomek [2009-08-11 20:39:11]
Dlaczego. Kolega dobrze robi. Zmienia aktualne ustawienia i zastępuje je innymi. W tym wypadku tylko ustawienia kropki.
Rozwiązanie widze działa ładnie i estetycznie.

macias [2010-09-03 18:42:27]
Opieranie sie w obliczeniach na tzw. ustawieniach regionalnych jest kompletnym idiotyzmem. Nie po to mamy w fizyce skale SI, zeby pozniej miec uniwersalne jednostki, tylko wartosci wielkosci fizycznych zapisane nie-uniwersalnie:
v = 1,5 km/h

I zgadnij drogi Jasiu za jaka predkoscia jedzie samochod?

Niestety nauka ustapila matolkom, ktorzy "od zawsze" poslugiwali sie <tu wpisz znaki separatorow>... Ech ;-)
Karol [2010-11-16 20:24:45]
Przydało się, dzięki

Dodaj komentarz:
Autor:*

WWW:

Treść:*

Wprowadź kod zabezpieczający*:


        * - pola wymagane
Kategorie
C# (13)
Inne (6)
Java (3)
Matlab (1)
OpenGL (1)
PHP (2)


Najnowsze wpisy

Ostatnie komentarze