I have a text file that needs parsing in the app and this was tested on my UK device and a US device. This same text file is used by Android and iPhone apps that work fine. It has been reported to me that some people on Windows Phones this does not work!
It turns out if the device is set to a region like Germany that uses the comma "," as the decimal point then the following code does not work properly!
GeoCoordinate tempCoord = new GeoCoordinate();
tempCoord.Latitude = Convert.ToDouble(words[0]);
tempCoord.Longitude = Convert.ToDouble(words[1]);
As words comes in as a string I'm not sure how else I can get this into a double from a string?
EDIT:
On a slightly related note the following is also causing me grief!
geoWatcher.Position.Location.Latitude.ToString()
This will return 56,888 for European and 56.888 for US/UK!
Arrrgh!
Instead of using Convert.ToDouble, use double.parse(...):
double d = double.Parse("3.500,02", CultureInfo.GetCultureInfo("de-DE").NumberFormat);
There is also an overload of double.ToString() that takes a formatter, and you can use this overload to produce string representations of a double in whatever manner you wish.
Related
I am new to C # and I am currently having problems with the following. In C #, I have a Pi floating point number and I want to convert it to a string using the ToString() method. But the conversion gives a string result with a comma "3,1415". On another machine, the same gives the string result with the dot "3.1415". What is the reason for this and what should I do to get a dotted string result?
EDIT: The problem is, I can't change the code, but I can install and uninstall .Net frameworks, change my OS settings, etc.
Edit: if you can't change the code. Change the language/localization of the system to one which uses dot as decimal separator. In Control Panel or Settings.
You should look at internationalization and localization in the System.Globalization namespace.
The advice here is to use one CultureInfo specific for parsing numbers or writing numbers to string.
var flt = 232.23f;
var str = flt.ToString(CultureInfo.InvariantCulture); //for example, you can use CultureInfo.CurrentCulture
This allows you to keep the ThreadCulture without change it.
But take a look at this link https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo?view=net-5.0 .Take your time, is dense.
I would just set the current culture at the entry point of your program.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
However I would also check the regional settings and so forth on the machine where the comma separator appears.
It is related with current culture info. You can specify the culture info in ToString method as a parameter like;
var convertedFloat = floatVariable.ToString(new CultureInfo("en-GB"));
Thanks to GSerg, for comment about Windows regional settings. That solves my problem. In the Windows Control panel enter Region and Language. In the Formats tab click Additional Settings and in the Decimal symbol field specify what decimal separator must be used when converting a floating point number to a string.
string TestVarStrg = "3.1";
double TestVarDoub = Convert.ToDouble(TestVarStrg);
MessageBox.Show(TestVarDoub.ToString());
with this code I get within the message box on the emulator "31". same on my lumia 920. but on my lumia 1520 I get "3.1". bouth devices have the last lumia black update. anyway actually I need "3.1" as double. "31" would be ok too but on all devices please. any idea about this behavior? Or an other way to convert string to double?
Please consider that the decimal sign is dependent on the culture settings. Use the overload where you can provide an IFormatProvider:
http://msdn.microsoft.com/de-de/library/9s9ak971(v=vs.110).aspx
So your code would look like:
string TestVarStrg = "3.1";
double TestVarDoub = Convert.ToDouble(TestVarStrg, System.Globalization.CultureInfo.InvariantCulture);
MessageBox.Show(TestVarDoub.ToString());
Please consider that this only works if your decimal sign is always a ".".
So i am working on an application that does some calculations. It reads some numbers from a txt, it converts them to double and after it multiplies them it gives the result.
Lets say the txt has the numbers 10.5 and 2
string string1 = "10.5", string2 = "2";
double double1 = Convert.ToDouble(string1), double2=Convert.ToDouble(string2);
double double3=double1*double2;
textbox.text= double3.ToString();
The result I always get on emulator is 21 while on my device i get 210. I tried reinstalling the app from the phone, restarting the phone and the pc and i tried this over 10 times. I still get different results on my phone. What should i do?
PS: i tried double.parse but still the same
On the basis that the phone and emulator are working under different locales, then this SO question answers what is really being asked how-to-convert-string-to-double-with-proper-cultureinfo
Of course you are now going to have to match your text file to the corrected locale.
Also see what-does-cultureinfo-invariantculture-mean
I'm having some problems in Windows 8 Metro apps (XAML & C#) regarding the user's regional settings. It seems that the apps won't respect user's regional settings, so even if your Windows 8 is set to display dates and times in Finnish format, the apps will still display them using US-formatting. But this is such a big problem that there must be something I'm missing?
To test this I started by creating a WPF-application. The application just prints out the CurrentCulture and the formatted DateTime.Now:
private void Culture_Loaded_1(object sender, RoutedEventArgs e)
{
this.Culture.Text = System.Globalization.CultureInfo.CurrentCulture.DisplayName;
}
private void Date_Loaded_1(object sender, RoutedEventArgs e)
{
this.Date.Text = DateTime.Now.ToString();
}
Here's my default regional settings:
When run, the app displayed the date in Finnish format:
Then I changed the regional settings to US:
And when the app was run again, the culture and formatting changed:
This is as I expected everything to work and this is also how I expected WinRT apps to work.
So as a next step, I created a WinRT (XAML & C#) app with the same code and reverted the regional settings back to Finnish. The problem:
Even when I've defined through regional settings that the formatting should be "Finnish", the WinRT app displays the datetime with US-formatting. I then modified the app's project file and made fi-FI the default language:
This change also modified the app's culture:
Strange. I changed the Default Language back to its default value and the formatting was restored to US. I then created folders "Strings - fi-FI" inside the project and added an empty "Resources.resw" to the project. This empty file seems to be enough, as I was now getting the Finnish formatting:
As soon as I remove the empty resource file, the formattings reverts back to US:
Very strange.
This leads to few questions, but the main one I think is: Is it intentional that the WinRT-apps don't follow the user's regional settings like the WPF apps do?
It's been a while, but the question is not fully answered, so let me share my little research. Depechie is mostly right, but he provided only a link and wasn't really sure.
Yes, this unexpected change is intentional. We shouldn't use CultureInfo anymore as it contains legacy codes and Microsoft want us to use Windows.Globalization APIs instead.
To obtain current region we can use:
GeographicRegion userRegion = new GeographicRegion();
string regionCode = userRegion.CodeTwoLetter;
But as I noticed it contains only region information, there's no language code. To obtain language we can use:
string langRegionCode = Windows.Globalization.Language.CurrentInputMethodLanguageTag; // depends on keyboard settings
List<string> langs = Windows.System.UserProfile.GlobalizationPreferences.Languages; // all user languages, like in languages control panel
List<string> applicationlangs = Windows.Globalization.ApplicationLanguages.Languages; // application languages (user languages resolved against languages declared as supported by application)
They return BCP47 language tags in format language-REGION like "en-US" if language has dialects or just language like "pl" if the language doesn't have major dialects.
We can also set one primary language which will override all the rest:
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "en-US";
(This is a persisted setting and is supposed to be used at user request)
There is also new API for date, time and numbers:
Windows.Globalization.DateTimeFormatting.DateTimeFormatter dtf = new DateTimeFormatter("longdate", new[] { "en-US" }, "US", CalendarIdentifiers.Gregorian, ClockIdentifiers.TwentyFourHour);
string longDate = dtf.Format(DateTime.Now);
Windows.Globalization.NumberFormatting.DecimalFormatter deciamlFormatter = new DecimalFormatter(new string[] { "PL" }, "PL");
double d1 = (double)deciamlFormatter.ParseDouble("2,5"); // ParseDouble returns double?, not double
There's really a lot more in Windows.Globalization APIs, but I think that this gives us the general idea. For further reading:
date & time formatting sample:
http://code.msdn.microsoft.com/windowsapps/Date-and-time-formatting-2361f348/sourcecode?fileId=52070&pathId=561085805
number formatting & parsing sample:
http://code.msdn.microsoft.com/windowsapps/Number-formatting-and-bb10ba3d/sourcecode?fileId=52249&pathId=1462911094
there's also a nice article titled "How to use patterns to format dates and times" on msdn, but I can add only 2 links
You can also find some topics about the issue on windows 8 dev center forum with some Microsoft employee answers, but they mainly send you to the documentation.
It is intentional. Microsoft is moving away from forcing applications to be in the language of the OS. Instead, each application uses information declared by the application (manifest languages, observable at Windows.Globalization.ApplicationLanguages.ManifestLanguages) and declared by the user (user languages, observable at Windows.System.UserProfile.GlobalizationPreferences.Languages) to determine how to display resources and globalized dates and times. This set of languages is called the application languages (observable at Windows.Globalization.ApplicationLanguages.Languages). The behavior you are seeing is because you are fiddling with the user languages and the manifest languages and you will get different application languages.
Could it be we now need to query other classes? Like the example given here: http://code.msdn.microsoft.com/windowsapps/Globalization-preferences-6654eb36/sourcecode?fileId=52104&pathId=236099476
This post still seems to be relevant even though it was asked two years ago.
I just came across it as I was looking for an answer to about the same thing.
I also wanted to display dates in the regional format in my WP8.1 WinRT app.
The information posted here helps, but it was a bit hard to piece it together.
This is what I came up with and it seems to work for me as the answer I needed:
using Windows.Globalization;
using Windows.Globalization.DateTimeFormatting;
private string FormatDate(int year, int month, int day)
{
GeographicRegion userRegion = new GeographicRegion();
string regionCode = userRegion.CodeTwoLetter;
var formatter = new DateTimeFormatter("year month day", new[] { regionCode });
DateTime dateToFormat = new DateTime(year, month, day);
var formattedDate = formatter.Format(dateToFormat);
return formattedDate;
}
I'm currently doing an app, that needs to be able to work with the US number layout (123,456.78) as well as with the German layout (123.456,78).
Now my approach is to use NumberFormatInfo.InvariantInfo about like this:
temp = temp.ToString(NumberFormatInfo.InvariantInfo);
this works great when for example reading a number from a textbox. When System is set to English format it will take the . as separator, when it's set to German it will use the ,.
So far so good....but here's the problem: I have a device that returns info in the American format, and that won't change (transmitted via RS232). So I receive something like 10.543355E-00.
Now when on German setting the . will be discarded since it's just the group separator
and the number I will end up with is 10543355....which is a lot more :)
I tried with the same technique thinking this would make the whole thing kind of 'cultureless' to be able to process it independently from the system language but it didn't work :)
I hope you can maybe help me here...I'd love to use a way without having to implement the whole culture stuff etc since all I need here is really numbers that get calculated the right way.
You should use CultureInfo.InvariantCulture when parsing strings from the device. This will cause it to use the invariant culture, which has the US rules for decimal separation.
Edit in response to comments:
The issue is not when you call .ToString(), but rather when you read the string from the device, and convert it to a number:
string inputFromRS232Device = GetDeviceInput();
double value;
// You need this when converting to the double - not when calling ToString()
bool success = double.TryParse(
inputFromRS232Device,
NumberStyles.Float,
CultureInfo.InvariantCulture,
out value);