C# - Convert a string [ Month DD, YYYY ] to DateTime [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to convert a string with this format Month DD, YYYY to a DateTime object, and performance is so important here.
String examples:
string AlaaJoseph = "October 23, 1996";
string JennetteMcCurdy = "June 26, 1992";

DateTime dt = DateTime.ParseExact("October 23, 1996",
"MMMM d, yyyy",
new CultureInfo("en-US"));

Have a look at using something like
DateTime.TryParseExact Method (String, String[], IFormatProvider, DateTimeStyles, DateTime)
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified array of formats,
culture-specific format information, and style. The format of the
string representation must match at least one of the specified formats
exactly. The method returns a value that indicates whether the
conversion succeeded.
Something like
string AlaaJoseph = "October 23, 1996";
DateTime AlaaJosephDateTime;
if (DateTime.TryParseExact(AlaaJoseph, "MMMM dd, yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out AlaaJosephDateTime))
Console.WriteLine("DateTimeTryParseExact Passed");
string JennetteMcCurdy = "June 26, 1992";
DateTime JennetteMcCurdyDateTime;
if (DateTime.TryParseExact(JennetteMcCurdy, "MMMM dd, yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out JennetteMcCurdyDateTime))
Console.WriteLine("DateTimeTryParseExact Passed");
Also, another good thing to know about is Custom Date and Time Format Strings

You can Do in this way:
DateTime dt = DateTime.ParseExact("October 23, 1996",
"MMMM d, yyyy",
new CultureInfo("en-US"));

performance is so important here
i Think performance is of secondary importance. Proper functioning of program in all scenarios is foremost. if it is fast in one scenario and fails on nine than it is useless to have a fast program. You should first make your program to work in all scenarios and then consider making if optimised. Even if you write your own parser to parse string you will still have to do all exception handling at any stage.
So, instead of reinventing the wheel and to ensure that you don't have to deal with any sort of exception handling and let the framework do that for you. You should use
DateTime.TryParseExact
it also has an overload that takes string[] formats where you can specify all the formats that you expect user to give
string[] formats= {"MMMM dd, yyyy","MMM dd, yyyy","M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
DateTime resultantDate;
string AlaaJoseph = "October 23, 1996";
if (DateTime.TryParseExact(AlaaJoseph, formats,
new CultureInfo("en-US"),
DateTimeStyles.None,
out resultantDate))
{
//your rest of code
}

Related

Why doesn't DateTime.ParseExact work for this example outside of the US?

I have a string:
var stringDate = "8/19/2016 5:00:00 PM"
and I try using:
var dateTime = DateTime.ParseExact(stringDate,"M/d/yyyy h:mm:ss tt", null);
or
var dateTime = DateTime.ParseExact(stringDate, "M/d/yyyy h:mm:ss tt",
CultureInfo.Invariant);
or
var dateTime = DateTime.ParseExact(stringDate,"M/d/yyyy h:mm:ss tt",
CultureInfo.GetCultureInfo("en-us"));
It works fine if the machine is in the US but and for all 3 options I get the following error when running from a machine in London:
String was not recognized as a valid DateTime
what am I missing here?
As far as I can see, you need to use h specifier instead of hh specifier since your hour part does not have leading zero for single digit values.
var stringDate = "8/19/2016 5:00:00 PM";
var dateTime = DateTime.ParseExact(stringDate, "M/d/yyyy h:mm:ss tt",
CultureInfo.InvariantCulture);
Also I would suggest to use specific culture settings instead of null for any case. In your example, since null means CurrentCulture settings for DateTime parsing methods, your CurrentCulture settings;
May not use / as a DateSeparator or
May not use : as a TimeSeparator or
May not use GregorianCalendar as a Calendar property or
May not have AM or PM as a PMDesignator or AMDesignator properties.
For those, your ParseExact method throws exception even if your string and format perfectly matches.

String was not recognized as a valid datetime exception with DateTime.PraseExact

I want to convert date time in to a particular format and save it in to a variable of type Object , but I am facing the error as String was not recognized as a valid DateTime
below the code which I tried
string regDate = DateTime.ParseExact("05/07/2015 19:41:06 PM", "MM-dd-yyyy HH:mm tt", CultureInfo.InvariantCulture);
The input will be in the format of "05/07/2015 19:41:06 PM" and i want the output in the mm/dd/yyyy format with hours-mins-secs also.
The error you get is reasonable, because the string you pass hasn't the exact format, you pass to the ParseExact.
Please try the following:
var regDate = DateTime.ParseExact("05/07/2015 19:41:06 PM", "MM/dd/yyyy HH:mm:ss tt", CultureInfo.InvariantCulture);
Furthermore, there is no need you convert a string to a string, like you did here Convert.ToString("05/07/2015 19:41:06 PM").
Check this .NET Fiddle.
I can't comment or I would. You need to combine Christos' answer and Imranullah Khan's comment
var regDate = DateTime.ParseExact("05/07/2015 19:41:06", "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
or
var regDate = DateTime.ParseExact("05/07/2015 07:41:06 PM", "MM/dd/yyyy hh:mm:ss tt", CultureInfo.InvariantCulture);
You can't include AM/PM with 24 hour times (19:41:06). So either drop the PM and tt or include the tt and change the HH to hh and then change the time to 07:41:06.

mono: DateTimeOffset.TryParseExact works on full .NET but not on debian

My C# project is taking xml and extracting pertinent data, one of which pieces is a date time value. The following code works correctly on my desktop running Win8.1 and .NET4. However when I run it through mono, it's failing to parse the data.
using glob = System.Globalization;
DateTimeOffset dt = DateTimeOffset.MinDate;
string[] fmts = new string[]
{
"MMM dd, yyyy hh:mm tt EDT",
"MMM dd, yyyy hh:mm tt EST",
"MMM dd, yyyy hh:mm tt CDT",
"MMM dd, yyyy hh:mm tt CST",
"MMM dd, yyyy hh:mm tt MDT",
"MMM dd, yyyy hh:mm tt MST",
"MMM dd, yyyy hh:mm tt AKST",
"MMM dd, yyyy hh:mm tt AKDT",
"MMM dd, yyyy hh:mm tt HST",
"MMM dd, yyyy hh:mm tt PST",
"MMM dd, yyyy hh:mm tt PDT"
};
var dtString = z.Substring(pos1 + 5, pos2 - pos1 - 1 - 5).Replace("ft", "").Trim();
dtString = dtString.Substring(0, 1).ToUpper() + dtString.Substring(1);
dtString = dtString.Substring(0, dtString.Length - 7)
+ dtString.Substring(dtString.Length - 7).ToUpper();
DateTimeOffset.TryParseExact(dtString, fmts,
glob.CultureInfo.InvariantCulture, glob.DateTimeStyles.None, out dt);
To check if the conversion worked ok, I do this:
if (dt == DateTimeOffset.MinDate)
Console.WriteLine("failed to convert dt = MinValue -> " + dtString);
Here's an example of the data string being processed:
raw: mar 21, 2015 10:30 am cdt
after my formatting: Mar 21, 2015 10:15 AM CDT
It's not specific to the CDT tz - I get the same issue for all timezones.
When I run $ date on the Linux box, it's reporting the same date, time and tz as my desktop, in this format (Mon Mar 23 11:31:16 EDT 2015).
The section is wrapped in a try/catch, but no exceptions are being thrown (also have Console output in there).
I can code around it by changing the string around before TryParse, but it would seem this method was designed so that this is not necessary.
Is this a bug (or am I missing something)? If so where does one report them?
Thanks
A few points:
In the code you posted, the part where you manipulate the dtString variable is meaningless to us, because you didn't include values for pos1 or pos2. It seems quite messy, and in general - that sort of manipulation should be avoided if possible. I'm not sure what it has to do with your question, if anything.
You are using the TryParseExact method, which returns a boolean true on success - so the comparison check is unnecessary. (Also, the field is called MinValue, not MinDate)
Time zone abbreviations are not valid in format strings. The letters in the string could be confused with actual custom formatting values. If you wanted to exclude them, you would place them in single-tick or double-tick quotation marks.
In general, time zone abbreviations should not be used for input. There are just too many ambiguities. For example, this list of abbreviations shows 5 possible interpretations of "CST".
The parsers that come with the DateTime and DateTimeOffset types do not understand time zone abbreviations at all. You claim it works fine on your desktop under .NET 4, but I call BS.
As you can see, it did not interpret the offset as CDT (-05:00). Instead it took the local time zone from my computer, which happens to be PDT (-07:00).
The correct way to deal with this is to parse the date input as a DateTime, then use some other mechanism to determine the offset. If you MUST use the time zone abbreviation, and you are absolutely sure you only have the time zones you showed above, and they're all from the united states, then it would go something like this:
// define the list that you care about
private static readonly Dictionary<string, TimeSpan> Abbreviations = new Dictionary<string, TimeSpan>
{
{"EDT", TimeSpan.FromHours(-4)},
{"EST", TimeSpan.FromHours(-5)},
{"CDT", TimeSpan.FromHours(-5)},
{"CST", TimeSpan.FromHours(-6)},
{"MDT", TimeSpan.FromHours(-6)},
{"MST", TimeSpan.FromHours(-7)},
{"PDT", TimeSpan.FromHours(-7)},
{"PST", TimeSpan.FromHours(-8)},
{"AKDT", TimeSpan.FromHours(-8)},
{"AKST", TimeSpan.FromHours(-9)},
{"HST", TimeSpan.FromHours(-10)}
};
static DateTimeOffset ParseInput(string input)
{
// get just the datetime part, without the abbreviation
string dateTimePart = input.Substring(0, input.LastIndexOf(" ", StringComparison.Ordinal));
// parse it to a datetime
DateTime dt;
bool success = DateTime.TryParseExact(dateTimePart, "MMM dd, yyyy hh:mm tt",
CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
// handle bad input
if (!success)
{
throw new ArgumentException("Invalid input string.", "input");
}
// get the abbreviation from the input string
string abbreviation = input.Substring(input.LastIndexOf(" ", StringComparison.Ordinal) + 1)
.ToUpperInvariant();
// look up the offset from the abbreviation
TimeSpan offset;
success = Abbreviations.TryGetValue(abbreviation, out offset);
if (!success)
{
throw new ArgumentException("Unknown time zone abbreviation.", "input");
}
// apply the offset to the datetime, and return
return new DateTimeOffset(dt, offset);
}
Now it will return the correct output:
string dtString = "Mar 21, 2015 10:15 AM CDT";
DateTimeOffset dto = ParseInput(dtString);
Console.WriteLine(dto);
Also note that if you were really trying to cover all legal US time zones, you should also consider adding HAST, HADT, CHST, SST, and AST to the list.

C# DateTime Conversion from yyyy-MM-ddTHH:mm:ss to dd MMM yyyy

How to convert "yyyy-MM-ddTHH:mm:ss" into "dd MMM yyyy" format? For Instance, i want to convert 2013-04-16 05:30:05 into 16 April 2013. What is the correct method to achieve this?
First ParseExact then do ToString (I assume that you have string object, if you have DateTime object, skip first line)
var dateTime = DateTime.ParseExact(yourDateString, "yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);
var yourNewString = dateTime.ToString("dd MMM yyyy");
Note that representation of DateTime you see in debugger is dependant on your current culture.
First, a DateTime has no format. But if you've already a string that represents a DateTime with the format yyyy-MM-ddTHH:mm:ss and you want to convert it to a string-date with format dd MMM yyyy you need to parse it to DateTime first.
Therefore use DateTime.ParseExact:
DateTime dt = DateTime.ParseExact("2013-04-16 05:30:05", "yyyy-MM-dd HH:mm:ss", null);
Now you can use DateTime.ToString:
string result = dt.ToString("dd MMM yyyy");
Note that you need to pass a different CultureInfo object to ParseExact/ToString if you want to parse with another DateTimeFormat than your current (f.e. force english month names instead of german: dt.ToString("dd MMM yyyy", CultureInfo.InvariantCulture)).
As others mentioned, a DateTime has no format. To parse a string literal to a Date you need to call DateTime.Parse (if the string is in a culture-specific format) or DateTime.ParseExact if you need to pass a format string.
The format can be a custom format like yyyy-MM-dd HH:mm:ss or one of the standard format strings, eg. s for yyyy-MM-ddTHH:mm:ss.
2013-04-16 05:30:05 it not in one of the standard formats, so you have to parse by passing a custom format string:
var dt = DateTime.ParseExact("2013-04-16 05:30:05", "yyyy-MM-dd HH:mm:ss", null);
On the other hand, yyyy-MM-ddTHH:mm:ss is the s standard format so you can just write:
var dt = DateTime.ParseExact("2013-04-16T05:30:05", "s", null);

String was not recognized as a valid DateTime

DateTime dtEndTime = DateTime.ParseExact(
appToDate,
timeFormats,
null,
System.Globalization.DateTimeStyles.None);
appToDate = 21-02-2013 12:30 AM
string[] timeFormats = {
"dd-MM-yyyy H:m tt",
"dd-MM-yyyy H:mm tt",
"dd-MM-yyyy HH:m tt",
"dd-MM-yyyy HH:mm tt"
};
String was not recognized as a valid DateTime.
I suspect the problem is your use of H combined with tt. H and HH indicate an hour in the range 0-23, where 12 is noon, and therefore PM.
I suspect you want h and hh instead of H... although you shouldn't need every combination of h/H/m/mm. (Do you really expect to see "1:5 PM"?) I suspect just "dd-MM-yyyy H:mm tt" should cover you.

Categories

Resources