Exception on DateTime Conversion - c#

I'm trying to format a list of datetime. One date is in the format same as what i provided but the factors are not in place. That line of code is given below. Can someone tell me how to skip the error for the below line?
Convert.ToDateTime("22-01-2013 00:00:00").ToString("yyyy-MM-dd");

I would avoid using Convert.ToDateTime to start with. I would suggest using DateTime.TryParse or (preferrably) DateTime.TryParseExact. Both of these will return a value indicating whether the conversion succeeded, so you don't need to start catching exceptions in order to skip bad data. For example:
DateTime parsed;
if (DateTime.TryParse(text, out parsed))
{
string reformatted = parsed.ToString("yyyy-MM-dd");
// Use reformatted
}
else
{
// Log error, perhaps?
}
If you have multiple possible formats, you should consider using the overload of TryParseExact which allows you to specify multiple formats in a single call.
As well as the format, you should consider the culture you want to use. In the above code (and your code) it will use the executing thread's culture. Is that always what you want? The culture can affect all kinds of things - usually if you're specifying a custom format, you want to use the invariant culture. Otherwise you could end up using a non-Gregorian calendar unexpectedly, for example...
EDIT: If your input is always in the format dd-MM-yyyy, then you should probably use:
DateTime parsed;
if (DateTime.TryParseExact(text, "dd-MM-yyyy", CultureInfo.InvariantCulture,
DateTimeStyles.Default, out parsed))
{
string reformatted = parsed.ToString(CultureInfo.InvariantCulture,
"yyyy-MM-dd");
// Use reformatted
}
else
{
// Log error, perhaps?
}

Instead of Convert.ToDateTime use DateTime.Parse or DateTime.ParseExact
ParseExact gives you more control over the format, so for example:
DateTime.ParseExact("22-01-2013 00:00:00","dd-MM-yyyy HH:mm:ss",CultureInfo.InvariantCulture).ToString("yyyy-MM-dd");
There is also a TryParseExact variant, which allows you to gracefully handle parse errors.

Try with:
DateTime.ParseExact("22-01-2013 00:00:00","dd-MM-yyyy HH:mm:ss",CultureInfo.InvariantCulture).ToString("yyyy-MM-dd");
This way you can specify the exact format for your date-string.

Try to use DateTime.ParseExact() method instead of.
Converts the specified string representation of a date and time to its
DateTime equivalent.
public static void Main(string[] args)
{
Console.WriteLine(DateTime.ParseExact("22-01-2013 00:00:00", "dd-MM-yyyy HH:mm:ss", CultureInfo.CurrentCulture).ToString("yyyy-MM-dd"));
}
Here is a DEMO.
Also check out Coding Best Practices Using DateTime in the .NET Framework which I think every .NET developer should read.

Related

Best way to validate a date string in C#

I was trying to validate a date read from app.config file using DateTime.TryParse() method. However, it returned true when the input was "12/05/201". This was actually a typo, and should have been, "12/05/2018". When I stepped through the code it automatically converted the date to "12/05/0201" and returned true. However when I used DateTime.TryParseExact(), it correctly returned false for the above input. So, should we always use DateTime.TryParseExact()? I am little confused because earlier I used use DateTime.TryParse() whenever I had to validate a date string! Both the code is given below:
Boolean isValidStartDate = DateTime.TryParse(startDate, out DateTime startDateVerified);
CultureInfo enUS = new CultureInfo("en-US");
Boolean isValidStartDate = DateTime.TryParseExact(startDate,"MM/dd/yyyy",enUS, DateTimeStyles.None, out DateTime startDateVerified);
Thanks
The year 201 being invalid is business logic - if you want to have logical safeguards on your imported data (and you should), do them explicitly. With C# you can easily add an extension method to DateTime if you want, something like
public static DateTime ParseDateWithSanity(this DateTime, string date)
{
dt = DateTime.Parse(date);
if dt.Year < 1900
{
throw BadInputException()
}
}
Best way to Validate date depends upon the use case and input data source and its formate
DateTime.TryParse is parsed using formatting information in the current DateTimeFormatInfo object so let's say if you use TryParse "12/05/201" it will return the parsed data according to your current culture settings. Which is "12/05/0201" ie in date format "MM/DD/YYYY"
Its always good practice to specify date formate and culture variance while parsing date and use TryParseExact instead of TryParse
(Note: To know about current culture settings you can look for a member of classes CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture)

Convert to datetime from Oracle

i know there are a lot of similar questions, but I couldn't find what I was looking for.
Here is my oracle date:
string testdate= "2014-01-07 15:00:00.0000000";
And here is how I tried to convert to datetime:
DateTime.ParseExact(testdate, "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)
This throws a format exception. Any ideas?
My quick test also throws the string not valid datetime exception. Quick test:
Console.WriteLine(DateTime.ParseExact(testdate, "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture).ToShortDateString());
I'd start by trying to avoid getting it as a string in the first place. Make sure you're using the appropriate data type in Oracle, and you should be able to call GetDateTime on the appropriate DataReader (or whatever you're using).
If you must parse it as text, then you need to specify a format which matches the value - so use 7 fs instead of 3, given that your value has ".0000000" at the end.
DateTime.ParseExact(testdate, "yyyy-MM-dd HH:mm:ss.fffffff",
CultureInfo.InvariantCulture)
But again, I'd strongly urge you to avoid having to deal with the value as text at all.
Why use ParseExact at all? Reqular Parse seems to work.
var dt = DateTime.Parse("2014-01-07 15:00:00.0000000", CultureInfo.InvariantCulture);
// Prints out 2014-01-07T15:00:00.0000000
Console.WriteLine(dt.ToString("o"));

Checking if valid date in C# not working properly

I am using the following function to determine whether input string is valid date or not.
public static bool IsDate(string date)
{
DateTime Temp;
if (DateTime.TryParse(date, out Temp))
return true;
else
return false;
}
Problem is when I give input "1997-09" then it returns true. I want it to check complete date like "1997-08-12"
And no there is no fix date format. Input could also be "19-Feb-2012"
And no there is no fix date format. Input could also be "19-Feb-2012"
There must be, otherwise it's nonesense. If you haven't defined how your system must behave you'd better stop coding and take a moment to define it.
You could use the TryParseExact method which allows you to specify one or more formats you would like to handle.
one easy condition you can add:
public static bool IsDate(string date)
{
DateTime Temp;
return(DateTime.TryParse(date, out Temp)&&date.Length>=10)
}
You should establish list of a correct date formats and then check with DateTime.TryParseExact, something like this:
string format = "yyyy-MM-dd";
DateTime dateTime;
if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture,
DateTimeStyles.None, out dateTime))
Use DateTime.TryParse, you can specify the format then, more here. http://msdn.microsoft.com/en-us/library/9h21f14e.aspx
To resolve this you should define a datetime-format in your applicaiton.
On any webpage you go, if you see a compilation form, you probabbly will will see some date field too, and near it something like:
DD-MM-YYYY, or MM/DD/YY, or somethign else .
Define for your application format, make it esplicit for the user and check on correctness according to your format.
Just an hypothetic example:
say user inserted a date and you store it into the string like DD-MM-YYYY, one of possible choice could be simply say :
if(dateTimeUserString.Split('-').Length < 3)
//not valid string !
I repeat, this is just an example you should choose more appropriate way for your application.
DateTime.TryParse does have an overload that takes an IFormatProvider to allow specification of custom formats. You may need to define multiple IFormatPrividers to check the various strings you may expect as valid.
Also, rather than the if/else, you could also shorten your code a bit by
return DateTime.TryParse(date, out Temp);
You can return result of parsing directly:
public static bool IsDate(string value)
{
DateTime date;
return DateTime.TryParse(value, out date);
}
And it works with formats you have provided (at least when current culture "en-US").
Your code will run just fine and check the given date string if it can be a valid date using all of the current culture's date formats including this 19-Feb-2012 or 1997-09 of yours or even 19 february.
This makes you flexible in date input.
But if flexibility is not what your are looking for then try to parse for one or more specific formats using TryParseExact.

converting string to valid datetime

string strdate="15/06/2010";
DateTime dt =
DateTime.Parse(strdate,
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat);
i cannot able to get the datetime value as dd/mm/yyyy.
it is giving exception 'string is not recognized as a valid datetime'
oly if it is in 06/15/2010 it is working. how to get the same format in dt.
Well, presumably your thread's current culture expects MM/dd/yyyy. If you want to use dd/MM/yyyy then you should specify that explicitly. Personally I prefer ParseExact instead of Parse, as that gives more control. I would use something like:
DateTime dt = DateTime.ParseExact(strdate, "dd/MM/yyyy",
CultureInfo.InvariantCulture);
Note that if this is user input, you may want to use TryParseExact instead.
You're currently using the current culture, which seems to be set up for US style date formats. Try this instead:
DateTime.Parse(strdate, System.Globalization.CultureInfo.CreateSpecificCulture("en-GB"));
This tells the function to use UK date style format which works. You might want to change the en-GB to whatever culture your dates will be in. If you have many calls where the culture is important it might also be worth to set it for the whole thread rather than call by call.

Problem with DateTime datatype

I have problem with the DateTime data type. Through a textbox I want to add person dateofbirth. As there is no date datatype in C# i am forced to use the DateTime datatype, but while converting TxtDateofBirth to DateTime i am getting an error, "String was not recognized as a valid DateTime." Here is my conversion the code. I kept this code in add event.
DateTime dateofbirth = Convert.ToDateTime(TxtDateOfBirth.Text);
What should I do?
Thanks,
Masum
Use DateTime.ParseExact with a format string which only specifies the date part.
Alternatively, as this is user input, use DateTime.TryParseExact so you don't need to catch an exception if the user has entered a bad date:
using System;
class Test
{
static void Main()
{
TestParsing("24/10/2009");
TestParsing("flibble");
}
static void TestParsing(string text)
{
DateTime dt;
if (DateTime.TryParseExact(text, "d", null, 0, out dt))
{
Console.WriteLine("Parsed to {0}", dt);
}
else
{
Console.WriteLine("Bad date");
}
}
}
Note that the format string "d" means "short date format" (see the "standard date and time form at strings" and "custom date and time format strings" pages in MSDN). "null" means "use the current culture" - so the above works for me in the UK, but you'd need to make the string "10/24/2009" in the US. You could specify a particular culture if you don't want to use the thread's current default. 0 means the default date and time style. Look at the MSDN page for more information.
Alternatively , use a mask so that users can only enter valid dates. (See the c# section under examples on the link given)
There is hardly anything one could add to Jon's answers, but in this case I'd like to make a point:
Try to understand that your problem is not because of the DateTime datatype but because your date string does not match the expected format (based on regional settings/thread culture) that the DateTime constructor.
You say that you are "forced" to use the DateTime datatype. You should keep in mind that Dates should always be treated as Dates. I've seen too many developers fall into the trap of using dates as strings (and performing split/search operations) rather than using DateTime because they feel that the latter is too complicated.

Categories