DateTime Parse unexpected behaviour - c#

I have to convert / parse a string into a DateTime
DateTime resultDate = new DateTime(2000,01,01);
string input = "24.24.2000";
string format = "dd.MM.yyyy";
bool success = DateTime.TryParseExact(input, format, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out resultDate);
now if the string is invalid and the conversion fails (in this example the 24 isn't a valid month) the Method TryParseExact changes the variable resultDate into DateTime.Min.
Why should I want to have DateTime.Min instead of the origin value if the conversion fails?

This isn't actually related to DateTime.TryParseExact nor is it unexpected behaviour. The result is an out parameter which means the method will always assign a value to it. The language actually requires the out keyword to avoid any confusion. out parameters are expected to be empty, which is why you can declare them without assigning a value.
A method's code can't even try to read an out parameter without initializing it to something. The following example will fail compilation with Use of unassigned out parameter 'result':
bool TryParse(string text,out DateTime result)
{
var original=result; //this fails compilation
result=DateTime.Today;
return true;
}
An out parameter is always assigned by the method unless the method throws an exception.
The documentation of DateTime.TryParseExact explains what the default value will be if conversion fails. It also explains that the parameter should be passed uninitialized
When this method returns, contains the DateTime value equivalent to
the date and time contained in s, if the conversion succeeded, or
MinValue if the conversion failed. The conversion fails if either the
s or format parameter is null, is an empty string, or does not contain
a date and time that correspond to the pattern specified in format.
This parameter is passed uninitialized.

Why should I want to have DateTime.Min instead of the origin value if the conversion fails
Because that is what the documentation states will happen.
When this method returns, contains the DateTime value equivalent to the date and time contained in s, if the conversion succeeded, or MinValue if the conversion failed.
With a simple modification to your code you can take advantage of the result and not have to repeat your default value.
DateTime resultDate;
string input = "24.24.2000";
string format = "dd.MM.yyyy";
if(!DateTime.TryParseExact(input, format, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out resultDate))
resultDate = new DateTime(2000,01,01);

Related

How to parse a DateTime string with like 03-22-2022 03:28 p.m. in C#

As my question says i would like to parse a datetime with format like 03-22-2022 03:28 p.m. (month-day-year hour:minute a.m. or p.m.) into t DateTime object in C#, not sure how to do this.
I tried the following but it doesn't work:
var ss = "03-22-2022 03:28 p.m.";
format = "MM-dd-yyyy hh:mm t.t.";
success = DateTime.TryParseExact(ss, format, System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None, out DateTime result);
First of all, I recommend you not use a var, but a string instead for ss. It's also hard to tell where the "success" variable came from. You don't normally assign a value on the left-hand side if you are using an out variable in the right-hand side, unless you are trying to capture the boolean to determine if it worked. There is a way to do that without the success variable.
If I were to do it your way, where I use the var instead of string, and I use TryParse with an out variable, here's what I would do.
var ss = "03-22-2022 03:28 p.m.";
DateTime.TryParse(ss, out DateTime result);
return (result != DateTime.MinValue);
By using the DateTime in the out parameter, you are defining the variable inline. That allows you to use result later. Also, a DateTime variable is never null, so you can check to see if it is equal to DateTime.MinValue instead of creating another variable you are going to use in a conditional statement. Checking DateTime.MinValue will produce the same result. In my example, I am returning the result as if it were a function with a return value. You could use that any way you wanted.
If you are not returning a boolean value, but are using it later, you might do:
string ss = "03-22-2022 03:28 p.m.";
DateTime.TryParse(ss, out DateTime result)
if (result != DateTime.MinValue)
{
//ToDo: continue process here
}
Others may have better advice, but this works for me.

When is empty string "" a valid DateTime string format?

Seeing a strange issue where on some systems the below code steps into the if statement (i.e. it returns true) while in other systems it returns false and steps into the else statement. What environmental conditions or framework version changes am I missing where this was changed? For example .net Fiddle returns true, but my own console apps return false.
DateTime time;
formatText = "";
if (DateTime.TryParse (DateTime.Now.ToString(formatText), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out time))
{
// If TryParseExact Worked
Console.WriteLine ("True: " + time.ToString ());
}
else
{
// If TryParseExact Failed
Console.WriteLine ("Failed to Parse Date");
}
String representations of DateTime are culture specific.
Passing an empty string or null as the format parameter of the ToString overload of DateTime is the same as passing the standard format specifier "G" - from the remarks section of the DateTime.ToString Method (String) msdn page:
If format is null or an empty string, the general format specifier, 'G', is used.
The TryParse overload you are using attempts to parse the DateTime value using the date and time formats available in the IFormatProvider format parameter - InvariantCulture in your case - so when you use TryParse with InvariantCulture, unless your current culture's ShortDatePattern and LongTimePattern properties are the same as in InvariantCulture, the tryParse will fail.

Converting string to datetime is returning the min value

I am using Visual Studio and I want to convert the string I have in my textbox into the DateTime format. I am using the function Convert.ToDateTime() but the value that is returned is the min value (0/0/0001 00:00:00).
What is the problem?
The code where I retrieve the string from my textbox.
//pass startdate end date to studentResult.aspx
Session["startdate"] = txtStartDate.Text.ToString();
Session["enddate"] = txtEndDate.Text.ToString();
The code where I convert the string to datetime format.
string startdate = (string)(Session["startdate"]);
string enddate = (string)(Session["enddate"]);
DateTime one = Convert.ToDateTime(startdate);
DateTime two = Convert.ToDateTime(enddate);
As pointed in my comment, Convert.ToDateTime method returns DateTime.MinValue if the parameter is null.
Return Value
Type: System.DateTime
The date and time equivalent of the value of value, or the date and time equivalent of DateTime.MinValue if value is null.
Probably your parameter is null but since you didn't gave us more details, we can't know what the exact problem is.
As a comman mistake, make sure that you are passing as a parameter .Text property of your TextBox, not itself. See Squid's comment.
use try parse, it'll return false if any conversion error occurs
Datetime #dateTime;
if(DateTime.TryParse(txtStartDate.Text, out #dateTime)) {
return #dateTime;
}

Cannot implicitly convert type bool to System.DateTime (C#)

I'm trying to convert a string to datetime to validate if user input is actually a date.
The error I'm getting is:
Cannot implicitly convert type bool to System.DateTime.
I've been looking online for a while and can't find anything specific enough to help me understand.
Code:
public bool is21YearsOfAge(string argument)
{
DateTime _parsedDateArgument;
DateTime convertStringToDate = System.DateTime.TryParse(argument, out >_parsedDateArgument);
if (convertStringToDate > DateTime.Now)
{
//do something
}
}
Thanks in advance.
The TryParse method returns a bool that informs you whether the parse was successful, rather than throwing an exception like the Parse method does. Try doing this:
DateTime convertStringToDate;
bool isDate = DateTime.TryParse(argument, out convertStringToDate);
If argument is a date, convertStringToDate will contain that date as a DateTime.
DateTime.TryParse returns bool to indicate if parsing was successeful. So you should do
System.DateTime.TryParse(argument, out _parsedDateArgument);
DateTime convertStringToDate =_parsedDateArgument
Look at the documentation for DateTime.TryParse - it returns a bool, but has an out parameter for the parsed result:
DateTime dateTime;
bool success = DateTime.TryParse(text, out dateTime);
If success is false, that means the text couldn't be parsed. (So typically at this point you'd display an error to the user.)
You've already got the out parameter - why did you expect to end up with two different DateTime values (one as the return value and one from the out parameter)?
When you get an error like this, always read the documentation as the first step towards diagnosing the problem.
It should be
DateTime convertStringToDate;
if(System.DateTime.TryParse(argument, out convertStringToDate))
{
//Now you will have converted date in convertStringToDate
if (convertStringToDate > DateTime.Now)
{
//do something
}
}
else
{
//argument not have a valid date
}
System.DateTime.TryParse will retrun true if, argument will have a valid date string to convert. and the converted date will be store in its out parameter.
DateTime.TryParse do not return a DateTime value. It returns a bool indicating if it could parse it.
Instead use
DateTime convertStringToDate;
if(DateTime.TryParse(argument, out convertStringToDate)){
//ok value is good
}else{
//Not ok value is not good
}
use this instead,
DateTime _parsedDateArgument;
bool success = System.DateTime.TryParse(argument, out _parsedDateArgument);
Always remember that Tryparse always return boolean.
TryParse returns a bool, use just Parse instead, or assign the out variable to the new you have:
System.DateTime.TryParse(argument, out _parsedDateArgument);
DateTime convertStringToDate = _parsedDateArgument;
or like this:
DateTime convertStringToDate = DateTime.Parse(argument);
add the following namespace
using System.Globalization;
Create object of CultureInfo class
CultureInfo MyCI = new CultureInfo("en-US");
DateTime convertStringToDate = System.DateTime.TryParse(argument.ToString("MM/dd/yy", MyCI), out _parsedDateArgument);

Working with nullable DateTime

I am using LINQ and have a few properties thats DateTime? type.
If i now want to add the value from a textbox i cant seem to get this to work.
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ScoringLastUpgrade", DbType="Date")]
public System.Nullable<System.DateTime> ScoringLastUpgrade
The textbox i use i have made sure with javascript that the format will be '2011-06-17'
But now when i try to do this:
myObject.ScoringLastUpgrade = Convert.ToDateTime(txtScoringUpgradeDate.Text).ToShortDateString();
I get this error: "Cannot convert type string to DateTime?"
How to do this?
The .ToShortDateString() call is converting it into a string. You should remove that call.
Also, you say you've made sure of the format with javascript. What if the user doesn't have javascript, you should do server-side checks too. Also, since it's in a given format, you can use DateTime.ParseExact or DateTime.TryParseExact (so an invalid format doesn't throw an exception) since its more efficient. (The format string would be "yyyy-MM-dd") i believe.
Don't convert it to string using 'ToShortDateTimeString', just set the result of Convert.ToDateTime:
myObject.ScoringLastUpgrade = Convert.ToDateTime(txtScoringUpgradeDate.Text);
Assuming you've done sufficient validation on txtScoringUpgradeDate.Text?
My preference when dealing with these type conversions is to use the TryParse method, e.g.:
DateTime date;
if (DateTime.TryParse(txtScoringUpgradeDate.Text, out date))
myObject.ScoringLastUpgrade = date;
The Convert.ToDateTime, much like the explicit DateTime.Parse will throw an InvalidCastException when an excepional value occurs. It's better to make your code fault tollerant then needlesly catch an exception.
UPDATE: based on your last comment:
You shouldn't return DateTime.MinValue in this case, as MinValue is less than the supported min value of a datetime column. the CLR DateTime supports a date range down to 0000-01-01, whereas the SQL datetime (as well as the comparative CLR SqlDateTime type) supports a minimum value of 1753-01-01. As it as a nullable DateTime, you should set it to null:
public static DateTime? ToNullableDateTime(this string date)
{
DateTime dateTime;
return (DateTime.TryParse(date, out dateTime))
? (DateTime?)dateTime
: null;
}
The problem is that you have put ToShortDateString() at the end there, effectively converting the DateTime back to a string again. Try removing that part of the line.
In my case (.cshtml):
<td>#item.InvoiceDate.Value.ToShortDateString().ToString()</td>
Where InvoiceDtae is Nullable Date in DB

Categories