DateTime.TryParse - What was actually parsed? - c#

I'm struggling a little bit in C# with DateTime.TryParse().
Essentially, given a string I need to extract the year and/or month and day in the current display culture. Sometimes I only get a year, or a month, or all three. Depending on what I get, I have a different control flow.
So far, I managed to parse a variety of strings into a DateTime; that isn't my problem.
My problem is that I wish to know WHAT was actually parsed (i.e. did I get a month or a year, or both).
The uninitialized DateTime defaults to 01/01/0001, and I cannot set everything to an invalid date, such as 99/99/9999 and then see what was filled.
I was thinking maybe I need to do regex, but the DateTime class provides that parsing for multiple cultures, which is very important in this project.
I've tried searching for this, but maybe I'm not using the right terms, because surely someone else must have had this issue before.
Update:
Here's some sample code of what I've got:
string strIn = Console.ReadLine();
DateTimeStyles enStyles = DateTimeStyles.AllowInnerWhite | DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite | DateTimeStyles.AssumeLocal;
bFound = DateTime.TryParse(strIn, CultureInfo.CreateSpecificCulture("en-US"), enStyles, out cDT);
Now, bFound will be true if something was parsed successfully. However, I need to know which parts of the date were parsed successfully

I dont understand you but are you looking for a specified format for your datetime?
string dateAndTimeFormat = "yyyy.MM.dd HH:mm:ss:fff"; // example of format
string dateAndTime = yourdatetimevalue;
DateTime toDateTime = DateTime.ParseExact(dateTime, dateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)
How formats are used:
http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx
EDIT 1
The tryparse returns true or false. False if it fails. Maybee that can be usefull?
Otherwise you can set the culture before the tryparse, if you are able to do so.
DateTime.TryParse(dateString, culture, styles, out dateResult)
Check the examples here :http://msdn.microsoft.com/en-us/library/9h21f14e.aspx
Under remarks:
"This method tries to ignore unrecognized data, if possible, and fills in missing month, day, and year information with the current date. If s contains only a date and no time, this method assumes the time is 12:00 midnight. If s includes a date component with a two-digit year, it is converted to a year in the current culture's current calendar based on the value of the Calendar.TwoDigitYearMax property. Any leading, inner, or trailing white space character in s is ignored. The date and time can be bracketed with a pair of leading and trailing NUMBER SIGN characters ('#', U+0023), and can be trailed with one or more NULL characters (U+0000)."
Hope some of that helps.

The DateTime.TryParse() returns value only on success.
So for below code example the variable dt is initialized to 01/01/0001 00:00:00 when declared.
When TryParse tries to extract date from string(MM/DD/YYYY format), and if it failes, then dt variable is having value 01/01/0001 00:00:00. Otherwise dt will contain the actual extracted datetime value (as in 2).
1)
DateTime dt;
DateTime.TryParse("23/15/2013", out dt);
// dt contains "01/01/0001 00:00:00"`
2)
`DateTime dt;
DateTime.TryParse("23/12/2013 6:25", out dt);
// dt contains "23/12/2013 06:25:00"`
There is no need to check WHAT was actually parsed.
Datetime value will be parsed if it's valid otherwise default datetime value will be returned.

Related

DateTime.ParseExact "Hmmssff" FormatException [duplicate]

I have tried like below:
DateTime.ParseExact("Feb520161000PM",
"MMMdyyyyhhmmtt", CultureInfo.InvariantCulture)
But it's giving FormatException.
Interestingly
DateTime.ParseExact(DateTime.Now.ToString("MMMdyyyyhhmmtt"), "MMMdyyyyhhmmtt",
CultureInfo.InvariantCulture)
This is also giving format exception.
Alexei's answer is quite right, I wanna explain little bit deep if you let me..
You are thinking 5 should match with d specifier, right? But this is not how DateTime.ParseExact works under the hood.
Since The "d" custom format specifier represents number from 1 through 31, this specifier will map 52 in your string, not just 5. That's why your code throws FormatException.
As you can see, your string format can't parsed unless you do it some string manipulations with it.
In such a case, .NET Team suggests either using two digit forms like 05 or insert separators for your date and time values.
You can create a custom method that parse this MMMdyyyyhhmmtt format for only parse this kind of formatted strings like;
public static DateTime? ParseDate_MMMdyyyyhhmmtt(string date)
{
if (date == null)
return null;
if (date.Length < 14)
return null;
if (date.Length == 14)
date = date.Insert(3, "0");
DateTime dt;
if (DateTime.TryParseExact(date, "MMMdyyyyhhmmtt",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
return dt;
return null;
}
The format is not parseable with regular parsing which work from left to right - you need custom code that parses value from right to left instead as you want leftmost number to be variable width ("Feb111111111PM").
If possible - change format to one with fixed width fields (preferably ISO8601). Otherwise split string manually and construct date from resulting parts (time part would work fine by itself, so just need to manually parse date part).
Some other approaches and info can be found in similar post about time - DateTime.ParseExact - how to parse single- and double-digit hours with same format string?

How to convert datetime string in format MMMdyyyyhhmmtt to datetime object?

I have tried like below:
DateTime.ParseExact("Feb520161000PM",
"MMMdyyyyhhmmtt", CultureInfo.InvariantCulture)
But it's giving FormatException.
Interestingly
DateTime.ParseExact(DateTime.Now.ToString("MMMdyyyyhhmmtt"), "MMMdyyyyhhmmtt",
CultureInfo.InvariantCulture)
This is also giving format exception.
Alexei's answer is quite right, I wanna explain little bit deep if you let me..
You are thinking 5 should match with d specifier, right? But this is not how DateTime.ParseExact works under the hood.
Since The "d" custom format specifier represents number from 1 through 31, this specifier will map 52 in your string, not just 5. That's why your code throws FormatException.
As you can see, your string format can't parsed unless you do it some string manipulations with it.
In such a case, .NET Team suggests either using two digit forms like 05 or insert separators for your date and time values.
You can create a custom method that parse this MMMdyyyyhhmmtt format for only parse this kind of formatted strings like;
public static DateTime? ParseDate_MMMdyyyyhhmmtt(string date)
{
if (date == null)
return null;
if (date.Length < 14)
return null;
if (date.Length == 14)
date = date.Insert(3, "0");
DateTime dt;
if (DateTime.TryParseExact(date, "MMMdyyyyhhmmtt",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
return dt;
return null;
}
The format is not parseable with regular parsing which work from left to right - you need custom code that parses value from right to left instead as you want leftmost number to be variable width ("Feb111111111PM").
If possible - change format to one with fixed width fields (preferably ISO8601). Otherwise split string manually and construct date from resulting parts (time part would work fine by itself, so just need to manually parse date part).
Some other approaches and info can be found in similar post about time - DateTime.ParseExact - how to parse single- and double-digit hours with same format string?

C# - Date/Time Formatting

Using C#, I am trying to format a date in to the following string format:
YYYYMMDD_HHMM.xlsx
Here is my code:
DateTime.Today.AddDays(0).ToString("yyyymmdd") + "_" + DateTime.Today.AddDays(0).ToString("hhmm")
Here is my output:
20130027_1200.xlsx
Month is not correct, nor is the time.
You're using mm, which is minutes, not months - and you're trying to print the time using DateTime.Today, which always returns midnight at the start of the day.
It's not clear why you're adding 0 days, either. I'd use:
DateTime now = DateTime.Now;
string name = now.ToString("yyyyMMdd'_'HHmm'.xlsx'");
(The ' quoting for the _ isn't strictly necessary, but personally I find it simplest to take the approach of quoting everything that isn't a format specifier.)
Or:
DateTime now = DateTime.Now;
string name = string.Format("{0:yyyyMMdd}_{0:HHmm}.xlsx", now);
Note the use of HH instead of hh to get a 24-hour clock rather than 12-hour, too.
Additionally, consider using UtcNow instead of Now, depending on your requirements. Note that around daylight saving transitions, the clock will go back or forward, so you could end up with duplicate file names.
Also note how in my code I've used DateTime.Now once - with your original code, you were finding the current date twice, which could have given different results on each invocation.
Finally, you might also want to specify CultureInfo.InvariantCulture when you format the date/time - otherwise if the current culture is one which doesn't use a Gregorian calendar by default, you may not get the results you were expecting.
DateTime.Today returns DateTime with all time-related properties set to 0. Use DateTime.Now instead.
Property value
An object that is set to today's date, with the time component set to 00:00:00.
from DateTime.Today Property
Use MM in your format to get month. mm returns minutes. You can check all format specifiers on MSDN: Custom Date and Time Format Strings

Comparison between dates in C# application

I have an asp.net application in which i have these three dates:
now = 08-10-13 15:56:19
cloture1 = 01-10-13 00:00:00
cloture2= 01-01-50 00:00:00
The format of dates is DD-MM-YY HH:MM:SS. the problem is that the function DateTime.Compare() gives me the same result ie
DateTime.Compare(now,cloture1) > 0 and DateTime.Compare(now,cloture2) > 0.
So what is the reasons of this problem? How can i fix my snippet?
The problem is your program most probably interpreting cloture2 as 1950, not 2050.
Because you have not posted the code in which you set cloture2, I cannot offer a concrete solution, but the best I can offer is that you use 01-10-2050 explicitly in your code.
From The "yy" Custom Format Specifier
In a parsing operation, a two-digit year that is parsed using the "yy"
custom format specifier is interpreted based on the
Calendar.TwoDigitYearMax property of the format provider's current
calendar.
In a parsing operation, a two-digit year that is parsed using the "yy"
custom format specifier is interpreted based on the
Calendar.TwoDigitYearMax property of the format provider's current
calendar. The following example parses the string representation of a
date that has a two-digit year by using the default Gregorian calendar
of the en-US culture.
From GregorianCalendar.TwoDigitYearMax
This property allows a 2-digit year to be properly translated to a
4-digit year. For example, if this property is set to 2029, the
100-year range is from 1930 to 2029. Therefore, a 2-digit value of 30
is interpreted as 1930, while a 2-digit value of 29 is interpreted as
2029.
Your application should set this value to 99 to indicate that 2-digit
years are to be taken literally. For example, if this property is set
to 99, the 100-year range is from 0 (not a valid value for most
calendars) to 99. Therefore, a 2-digit value of 30 is interpreted as
30.
Even when you decompile GregorianCalendar.TwoDigitYearMax property, you can see yourself;
public override int TwoDigitYearMax
{
get
{
if (this.twoDigitYearMax == -1)
this.twoDigitYearMax = Calendar.GetSystemTwoDigitYearSetting(this.ID, 2029);
return this.twoDigitYearMax;
}
Boluc's answer is completely right. I want to point also your format part.
You can't format two digit year with YYYY format. You need to use yy format which allows two digit formatting.
DateTime dt = DateTime.ParseExact("01-01-50 00:00:00", "dd-MM-yy HH:mm:ss", CultureInfo.InvariantCulture);
Prints
01.01.1950 00:00:00
Here a DEMO.
Check out for more informations from Custom Date and Time Format Strings
If now is later than cloture1 then the returned value will be 1 (or Greater than Zero).
The code you have supplied along with the example dates seems to work fine in reference to the MSDN article for DateTime.Compare method.
Please check the following link for more information on the DateTime.Compare method:
http://msdn.microsoft.com/en-us/library/system.datetime.compare.aspx
If you believe that your code is still incorrect please elaborate on your question.

String to mmm-yy format of time in C#

I need to perform some date operations in ASP.net using C#.
The date i would enter should be of format 'Jul-05' (mmm-yy Format and type-string)...
how can i check with this????
Or how can i validate this with whatever user is entering as a string???
After validating that, i need to compare tht with a value in Database(say a column name buy_period which has a value (say) 04/31/2007).
How can i write a Query for comparing both?? (as both dates would be of different formats)
Can u pls help me in this ???
DateTime myDateTime = DateTime.ParseExact( input, "MMM-yy" );
You can then happily pass it to a stored procedure (etc.) as a parameter to do your comparison on the server (or just use the DateTime returned as the result of an existing query)
Use the TryParseExact method to validate the string and parse it to a DateTime value:
DateTime month;
if (DateTime.TryParseExact("MMM-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out month)) {
// parsing was successful
}
The DateTime value will use the first day of month and the time 0:00 to fill up a complete value, so a string like "jul-05" will be parsed into a complete DateTime value like 2005-07-01 00:00:00.0000, so it will be the starting point of that month.
To compare this to a date in the database you also need the starting point of the next month, which you get with:
DateTime nextMonth = month.AddMonths(1);
Now you can just compare a date to the starting and ending point of the month in this manner:
where date >= #Month and date < #NextMonth
The .NET framework has some nice methods on the DateTime struct :: Parse, TryParse, ParseExact, TryParseExact.
This info is discussed on MSDN.
Becuase you're providing a custom date string, we should then use the ParseExact or TryParseExact. The later doesn't throw an exception if it fails to parse.
So.. lets try this...
using System.Globalization;
CultureInfo MyCultureInfo = new CultureInfo("en-US");
string myString = "Jul-05";
DateTime myDateTime = DateTime.ParseExact(myString, "MMM-yy", MyCultureInfo))
Console.WriteLine();
the value myDateTime can then be passed to a database as a DateTime property and checked against that.
EDIT: Damn, beaten by Rowland by a min, as i was typing it!
EDIT 2: Please note the "MMM-yy". As stated on the MSDN page, MMM is "Represents the abbreviated name of the month as defined in the current System.Globalization.DateTimeFormatInfo.AbbreviatedMonthNames property." mmm (lower case) is invalid.
1: read this
2: is the column is a datetime or varchar?
well your validation and comparison have to be two different operations. so you could do alot of things for validation.
Validation Options:
1.) Split your string on "-" and check to see if the mmm part is in your list of months, and then check to see if the number is valid.
2.) Regular Expression, this is advanced but can be reduced to one line. Look up RegEx if you are interested.
After you've validated the string, convert it to a DateTime object and compare it to the other value using DateTime.Compare().
Hope that helps.
You could use
DateTime date = DateTime.ParseExact(value, "MMM-yy", null); //checked at http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
and then use that date in a sql command parameter.

Categories