DateTime.Parse with custom formats - c#

I'm trying to use DateTime.Parse in order to parse a string containing a DateTime in a custom format.
The format is yy-MMM MMMM-dddd-ddd-dd, the string is 15-jan. január-szerda-Sze-07.
I've modified the ShortDatePattern in the OS' regional settings, and you can see it in the CultureInfo.CurrentCulture while debugging.
I'm using the following code:
var date = DateTime.Parse(dateInString, CultureInfo.CurrentCulture);
But it fails with exception String was not recognized as a valid DateTime.
Using ParseExact it does work.
var date = DateTime.ParseExact(
dateInString,
CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern,
CultureInfo.CurrentCulture);
Shouldn't Parse work as well?
Any help would be appreciated.
Edit:
Assuming Parse is just not good enough, should this be okay or can it cause problem I can't think of right now (it works with the aforementioned problem)?
DateTime date = new DateTime();
bool success = false;
foreach (var format in currentCulture.DateTimeFormat.GetAllDateTimePatterns())
{
success = DateTime.TryParseExact(dateString, format, culture, DateTimeStyles.AllowWhiteSpaces, out date);
if (success)
break;
}
if (!success)
throw new Exception();

I played a little bit with your example and I couldn't make it work. I think that DateTime.Parse is simply not clever enough to parse your string and MSDN documentation confirms that. Here is a section from ParseExact documentation according to which Parse should not be used with custom cultures/patterns and why:
If you parse a date and time string generated for a custom culture, use the ParseExact method instead of the Parse method to improve the
probability that the parse operation will succeed. A custom culture
date and time string can be complicated, and therefore difficult to
parse. The Parse method attempts to parse a string with several
implicit parse patterns, all of which might fail.
And here is another interesting fragment from SetAllDateTimePatterns documentation:
The Parse and TryParse methods do not fully iterate all strings in patterns when parsing the string representation of a date and time. If
you require a date and time string to have particular formats in a
parsing operation, you should pass the array of valid formats to the
DateTime.ParseExact...

Related

DateTime.TryParse() not working with formatted date dd/MM/yyyy

This code returns (min time 1/1/0001 12:00:00 AM) not Date.Time.Now . Try Parse works for MM/dd/yyyy but not dd/MM/yyyy . Any suggestions
Here is code
DateTime start, end;
DateTime.TryParse(EPSDate12.Text, out start);
string TNow = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"); // Works
// string TNow = DateTime.Now.ToString();// works but gives MM/dd/yyyy as expected
DateTime.TryParse(TNow, out end); // No. gives min time (1/1/0001 12:00:00 AM)
Use TryParseExact and supply the format string.
Also examine the return value from TryParseExact to know if it failed or not (it returns a bool)
I see "EPSDate12.Text" which i suspect may be a TextBox: If you're doing this in a UI, make life easy and use a DateTimePicker - you can set the format, the user can type into them just like a textbox, but they don't accept invalid inputs, and all you have to do is get the .Value property which gives you a DateTime
As to why your attempts to parse the string you made don't work, I think it most likely that the date format Parse is using (which is based on the culture settings of the executing thread) is not the same format as the string you prepared using your forced format. Either make sure your forced format is matched to the current culture, or use a culture that matches your forced format, or use [Try]ParseExact to force the format for parsing like you did when creating the string
See https://learn.microsoft.com/en-us/dotnet/api/system.datetime.parse?view=net-5.0#Culture for more info
The datetime value is internally the same. But, ToString() return value, depends on
the local machine culture setup.
Reference article
The default DateTime.ToString() method returns the string
representation of a date and time value using the current culture's
short date and long time pattern. The following example uses the
default DateTime.ToString() method.
For en-US culture(MM/dd/yyyy hh:mm:ss) , it will be in
7/28/2021 11:37:40 AM
If you want to see in en-GB(dd/MM/yyyy hh:mm:ss), you can apply conversion as given below:
var culture = new CultureInfo("en-GB");
MessageBox.Show($"{DateTime.Now.ToString(culture)}");
28/07/2021 11:45:09 AM
you can also specify exact custom format, in which you want to display.
MessageBox.Show($"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss tt")}");
28/07/2021 11:45:09 AM
Thanks for suggestions . Yes DateTime.TryParse is not working and it could be format issue
This line of code.
string TNow = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");
generates
29/07/2021 14:49:03
which looks OK but fails TryParse

String was not recognized as a valid DateTime format exception

I am trying to do a simple parsing using following statements:
//In actual code the date time value comes from db
var dateTime = new DateTime(2018, 04, 26);
var dtExtact = DateTime.ParseExact(dateTime.ToString(), "dd MMM yyyy HH:mm:ss:fff",null);
Now when I try doing this getting error,
System.FormatException: 'String was not recognized as a valid DateTime.'
I did have a look at the MSDN sample, but it does not provide any pointers on whats wrong with my date time.
If you would like to parse a date-time string in a specific format, make sure that your formatted date/time string matches the format of your parser.
In your example "round-tripping" a date/time is easy to achieve by reusing the same format string for formatting the date and for parsing:
var dateTime = new DateTime(2018, 04, 26);
const string dateFormat = "dd MMM yyyy HH:mm:ss:fff";
var dtExact = DateTime.ParseExact(
dateTime.ToString(dateFormat)
, dateFormat
, null
);
Console.WriteLine("{0} {1}", dateTime, dtExact);
Demo.
Both ToString() and Parse() are designed to automagically extract the Region setting from Windows. It is rarely a good idea to override this behavior. And apparently your pattern is not a valid one. For all we know, ':' is not actually the proper cultural seperator for Time elements
Overall this seems rather suspect - you turn a DateTime to string, only to parse it again right there. I can only guess it is for testing. But testing for what is the question.
I have 3 general rules when dealing with DateTimes:
Always store, retrieve and transmit the UTC value. You do not want ot add timezones to your issues. That way lies madness. There are rare exceptions, but then you are pretty much on your own to deal with that mess
Avoid storing, retreival or transmission as Text. keep it in proper DataTypes as long as possible
If you can follow the 2nd rule (using XML or some other serialsiation), at least pick a fixed Culture Format, Format String and string encoding at all endpoints. You do not want to add those issues to your worries
Following those rules, I rarely had any issues.

Convert date in string to DateTime with same format

I have a string that has a date stored in it.
String date = "03-05-2013 00:00:00";
I parsed it to Datetime as follows:
DateTime Start = DateTime.Parse(date);
Start.ToString() gave me "3/5/2013 12:0:00 AM"
I also used:
DateTime Start = DateTime.ParseExact(date,"dd-MM-yyyy HH:mm:ss",CultureInfo.InvariantCulture);
Then, Start.ToString() gave me "3/5/2013 12:0:00 AM", which is the exact same result as the previous one. I need to keep the original formatting. How may I do it? Thanks.
The format you parse with does not dictate how the DateTime is formatted when you convert the date back to a string. When you call ToString on a date it pulls the format from the current culture of the thread your code is executing on (which defaults to the culture of the machine your on).
You can override this by passing the format into ToString() i.e.
Start.ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
See Custom Date and Time Formats.
You need to pass the format in the ToString() call.
Start.ToString("dd-MM-yyy HH:mm:ss");
I need to keep the original formatting.
Then you need to apply the same pattern again when you call ToString:
string formatted = Start.ToString("dd-MM-yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
(Note that you should specify the same culture when formatting as you did when parsing, to avoid things like the time separator from changing.)
Note that for some formats this still might not give the exact original representation - if you're using a format which includes the text for a month, for example, that would match case-insensitively, so input including "MARCH" would be reformatted as "March".
A DateTime value is just a date and time (and a "kind", but that's another story) - it doesn't maintain a textual representation any more than an integer does. It's important to differentiate between the inherent data in a value and a textual representation of that data. Most types which have multiple possible textual representations have no notion of keeping "the original representation" alongside the data.

How to make DateTime independent from the current culture?

I cam trying to convert a datetime to string and back, but making it so that it works for all cultures.
I basically have a Textbox (tbDateTime) and a label (lbDateTime). The label tells the user, in which format the software expects the input of tbDateTime. The input of the Textbox will be used for an MySQL command.
Currently it works like this:
lbDateTime.Text = "DD.MM.YYYY hh:mm:ss"; // I live in germany
DateTime date = Convert.ToDateTime(tbDateTime.Text);
String filter = date.ToString("yyyy-MM-dd HH:mm:ss");
Now my question:
Is it possible to determine the format-string for lbDateTime.Text based on the current culture?
Which format does the Convert.ToDateTime function uses?
I hope you can help me. I have actually no pc here to test different cultures, so I'm very afraid that I make something wrong.
Instead of using the Convert.ToDateTime method you can use the DateTime.Parse or DateTime.ParseExact methods. Both allow you to pass a culture that tells how you expect the date to be formatted.
The DateTime.ParseExact method also allows you to specify the format you expect, so you can parse more or less any format with this method.
Edit:
Regarding Convert.ToDateTime. The documentation says that the current culture is used when parsing: http://msdn.microsoft.com/en-us/library/xhz1w05e.aspx
The current culture can be found using the System.Threading.Thread.CurrentThread.CurrentCulture property.
Edit2:
Oh. You may also want to use DateTime.TryParse and DateTime.TryParseExact if you are unsure whether the given format is invalid.
Edit3:
Lots of edits here... I see that you want to determine the culture string that matches the date the user has entered. There is no general solution that is guaranteed to work here. Say for instance that the user has entered the date 01.02.11. There is no way to be certain if this date is in day.month.year or month.day.year or year.month.day and so on.
The best you can do is to have a list of expected input cultures and start with the most likely and try to parse the date using that. If that fails, you can try the second most likely and so on...
But this is really not recommended. Either give the user an expected format, or better, use a date input box that ensures that you receive the selected date in an appropriate format.
The Convert.ToDateTime method will call DateTime.Parse to parse the string, using the current culture (CultureInfo.Current).
You can specify a culture when parsing the string. Example:
DateTime data = DateTime.Parse(tbDateTime.Text, new CultureInfo("en-GB"));
You can use DateTime.ParseExact (or DateTime.TryParseExact) to parse the string using a custom date format. Example:
DateTime data = DateTime.ParseExact(tbDateTime.Text, "dd'.'MM'.'yyyy HH':'mm':'ss", CultureInfo.InvariantCulture);
Another solution :
// Specify the current language (used in the current system you are working on)
CultureInfo currentCulture = CultureInfo.GetCultureInfo(CultureInfo.CurrentCulture.ToString());
// Specify the language that we need
CultureInfo myLanguage = CultureInfo.GetCultureInfo("en-US");
// Adapt the DateTime here, we will use the current time for this example
DateTime currentDate = DateTime.Now;
// The date in the format that we need
string myDate = DateTime.Parse(currentDate.ToString(), currentCulture).ToString(myLanguage);

String was not recognized as a valid DateTime - when string format is different from system datetime format

My system short date time format is d/M/yyyy. I'm passing "03/29/2011 02:38:18 PM", so it is giving error "String was not recognized as a valid DateTime"
DateTime.Parse("03/29/2011 02:38:18 PM")
If date time format of machine is set to m/d/yyyy, it works perfectly.
Edit:
My application is a winform application, it contains a data gridview, this grid view contains a custom DateTime control (columns), which is created by other developer.
This error is occurring when I try to change value of this datetime column in grid. VS debugger is not catching the exception, so I'm not able to find location where I should try fixing it.
Thanks
According to the format d/M/yyyy, 03/29/2011 would amount to month number 29 that does obviously not exist.
The other format has day and month switched, and the string then represents 29. March which is a perfectly valid date.
From MSDN:
Important Because the Parse(String)
method tries to parse the string
representation of a date and time
using the formatting rules of the
current culture, trying to parse a
particular string across different
cultures can either fail or return
different results. If a specific date
and time format will be parsed across
different locales, use the
DateTime.Parse(String,
IFormatProvider) method or one of the
overloads of the ParseExact method and
provide a format specifier.
Yes, well, the DateTime.Parse function uses the system format to parse the date, unless you provide a FormatProvider. Obviously in case of d/m/yyyy there is no month 29 so the parsing fails
Use DateTime.ParseExact() instead. You can specify exactly how to parse the date if you know what the string looks like going into the function by passing in the correct FormatString. If the standard DateTime Format Strings don't work, you can use a custom DateTime Format String.
Use DateTime.ParseExact to parse datetime from string
Example:
DateTime.ParseExact("2001-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
You could try to change the culture information, so your input matches the format of the system.
So try to add this in the web.config:
<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="en-US" />
You can find the answer here: String was not recognized as a valid DateTime " format dd/MM/yyyy"
You can parse the Date with a corresponding CultureInfo, which defines the date format and the order of the date parts (Month,Day,Year) or (Day,Month,Year).
Or you could use the ParseExact and give it a format string as described in the answer above.
See "convert Different formate of DateTime to specific String format in c#"
private DateTime ConvertToDateTime(string strDateTime)
{
DateTime dtFinaldate; string sDateTime;
try { dtFinaldate = Convert.ToDateTime(strDateTime); }
catch (Exception e)
{
string[] sDate = strDateTime.Split('/');
sDateTime = sDate[1] + '/' + sDate[0] + '/' + sDate[2];
dtFinaldate = Convert.ToDateTime(sDateTime);
}
return dtFinaldate;
}

Categories

Resources