Double.Parse not giving correct result - c#

I'm trying this in two application; a console application and a web application.
In the console app when I try Double.Parse("0.5") it gives 0.5 or Double.Parse(".5") gives 0.5
But in the web application Double.Parse("0.5") gives 5.0 and Double.Parse(".5") gives exception
Input string was not in a correct format.
Can any one tell how can resolve the issue in web app?

You should provide culture information otherwise it uses the culture info from the currently running thread. Try this instead:
CultureInfo cultureInfo = CultureInfo.InvariantCulture; // or whatever you prefer
double result = double.Parse(".5", cultureInfo);

Related

AWS lambda C# core CultureInfo ToString issue

I am trying to change the format of ToLongDateString to be in my local culture (da-DK).
For now I am doing the following, and if it can be done in a better way, then it will be very appreciated:
CultureInfo cCulture = new CultureInfo("da-DK");
string dateTimeStr = freeSeat.FreeDate.ToLongDateString().ToString(cCulture);
This works as expected on my local development environment, but when I deploy it to AWS lambda, I just get the English culture format. I am pretty sure the issue is that in AWS the C# core code is running on Linux.
I hope someone can give me some input how to solve this.
The ToLongDateString method returns a string formatted according to the current thread culture. Calling ToString method later is useless.
Do it like this:
CultureInfo cCulture = new CultureInfo("da-DK");
string format = cCulture.DateTimeFormat.LongDatePattern;
string dateTimeStr = freeSeat.FreeDate.ToString(format, cCulture);

DateTime.ToString format inconsistent between Web App and Windows Service

We are experiencing weird behaviour between a web application and windows service when trying to perform a ToString() on a DateTime value.
See the example below.
DateTime parsedReportDate;
reportDate = DateTime.Now.ToString("yyyyMMdd");
reportDateWithSlash = DateTime.Now.ToString("dd/MM/yyyy");
if (DateTime.TryParse(MyDateValue, out parsedReportDate))
{
reportDate = parsedReportDate.ToString("yyyyMMdd");
reportDateWithSlash = parsedReportDate.ToString("dd/MM/yyyy");
}
--reportDateWithSlash on Web Application: 28/03/2017
--reportDateWithSlash on Windows Service: 28-03-2017
The Windows Service calls the same function as the Web Application does, so why is the formatting different then?
The formatting of dates to strings uses a CultureInfo object to know what format to use.
Each Thread has a Thread.CurrentCulture property.
You can find out what CultureInfo the current Thread is set by getting the current Thread using Thread.CurrentThread and then inspecting it's Thread.CurrentCulture property.
public class Program
{
public static void Main()
{
Console.WriteLine(Thread.CurrentThread.CurrentCulture.Name);
}
}
https://dotnetfiddle.net/dsA3VT
Output: en-US
You can set the CultureInfo for the the Thread, or pass it with each call to ToString.
Setting Thread.CultureInfo
You can set the Thread.CultureInfo using the same property as you use to read it.
Thread.CurrentCulture = new CultureInfo("en-gb");
Unfortunately .Net Fiddle doesn't support changing thread properties.
I didn't know this, but bradbury9 pointed out that since .net 4.6 you can set the CultureInfo.CurrentCulture property as well.
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("nl-NL");
Unfortunately .Net Fiddle doesn't support changing the culture this way either.
Passing CultureInfo to ToString
'DateTime.ToString' has overloads which can take an IFormatProvider, and CultureInfo impliments IFormatProvider.
DateTime.Now.ToString(new CultureInfo("en-gb"));
https://dotnetfiddle.net/qkS5HF
public class Program
{
public static void Main()
{
var dateTime = DateTime.Now;
Console.WriteLine(Thread.CurrentThread.CurrentCulture.Name);
Console.WriteLine(dateTime.ToString(CultureInfo.InvariantCulture));
Console.WriteLine(dateTime.ToString(new CultureInfo("en-us")));
}
}
Output:
en-US
03/28/2017 09:43:49
3/28/2017 9:43:49 AM
The problem must come from having different cultures. Using the DateTime.ToString (String, IFormatProvider) overload with the CultureInfo.InvariantCulture property should solve the problem:
DateTime.Now.ToString("dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture);
it may be what is calling the Windows service is formatting the date. the code certainly is clear enough. Try debugging the windows service by attaching to the running process and see what it generates. If your service consumer is a web app, look at F12 developer tools and see what is getting sent back int he response stream.

Converting Dates between Calendars in Xamarin.Android

I have the following snippet of Code for Convert Gregorian Date to Hijri Date.
public static string GregoriantoHijri(DateTime gregorianDate)
{
CultureInfo arCI = new CultureInfo("ar-SA");
var hijriCalendar = new HijriCalendar();
hijriCalendar.HijriAdjustment = App_Code.StoreRetrieveSettingsAssist.getHA();
arCI.DateTimeFormat.Calendar = hijriCalendar; //CODE FAILS HERE
string hijriDate = gregorianDate.ToString("dd-MM-yyyy", arCI);
return hijriDate;
}
This code runs perfectly for my Windows Mobile App which is also posted on Store.
However the same code is giving me issues in Xamarin.Android
The Error:
System.ArgumentOutOfRangeException:
Not a valid calendar for the given culture.
Parameter name: value
I don't understand why codes using same .NET base class have issues on different platforms. Can you suggest a workaround cause this doesn't seem to work.
You might want to consider NodaTime. It is supposedly more robust than the native .NET datetime handling, and is supposed to support Hijri.

CurrentThread.CurrentCulture and Unit Testing

I have a bug report where double.Parse(input) is throwing the following exception with the input "0.69803923368454":
FormatException: Unknown char: .
System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Double.cs:209)
System.Double.Parse (System.String s) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Double.cs:180)
After some searching it seems that this issue occurs when the default culture does not support the decimal character . (see float.Parse fails on decimals and commas);
I need to create a unit test which reproduces this issue by forcing a different default culture for the duration of the test. Naturally this must not interfere with any existing unit test. I am using the unit testing framework which is provided with Visual Studio.
Here is what I have tried, but unfortunately this does not cause the reported error to occur:
[TestMethod]
private void DoubleParseWithCultureOverride() {
var restoreCulture = Thread.CurrentThread.CurrentCulture;
var restoreUICulture = Thread.CurrentThread.CurrentUICulture;
try {
// Arrange
Thread.CurrentThread.CurrentCulture = new CultureInfo("ko-KR");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("ko-KR");
// Act
double value = double.Parse("0.69803923368454");
// Assert
Assert.AreEqual(0.69803923368454, value);
}
finally {
Thread.CurrentThread.CurrentCulture = restoreCulture;
Thread.CurrentThread.CurrentUICulture = restoreUICulture;
}
}
I was expecting the above unit test to fail (i.e. become red in the test explorer panel), but it passed. At the moment I am purely attempting to force the error with standard Mono/.NET usage. I intend to replace the "Act" section with application specific logic.
You've just picked a culture which happens to use . as a decimal point:
var culture = new CultureInfo("ko-KR");
Console.WriteLine(culture.NumberFormat.NumberDecimalSeparator); // Prints .
I typically use French (fr-FR) for this - and that does fail with your current code.
Alternatively, you could construct your own CultureInfo specifically for testing, with whatever separator you want.
For testing like this, you might want a simpler way of setting the culture, too. Options:
Write a method taking an action to execute "within" a culture, then call it as:
ExecuteInCulture("fr-Fr", () =>
{
// Parse a double, or whatever
});
Create an IDisposable implementation which sets the culture and restores it on Dispose:
using (CultureHelper.SetCulture("fr-FR"))
{
// Parse a double, or whatever
}
The former approach is probably cleaner - it's not like you've really got a "resource" here.

Datetime error in iis 7 server

I have screen in c# asp.net webapplication, where i add news on particular dates.And can edit those dates also.It workes in my local sytem.But shows datetime error when it was running in iis 7 server(Used sql database).And i knew that the short date and long date format in server was different from local system.So i changed date format in local system same as in iis.But still it is working properly.
Instead of guessing culture settings write code that sets one you need before reading from database/restore after unsing Thread.CurrentCulture property. Simialr to code below (need to also use CurrentUICulture, chose cuture you need and wrap code around setting/restoring into try/finally for real code)
var oldCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
// read from DB
...
Thread.CurrentThread.CurrentCulture = oldCulture;

Categories

Resources