This is a very strange date fromat I have never seen before coming back from some API in JSON.
"Tue Aug 04 2015 00:17:38 GMT+0000 (UTC)"
That is generating the following error:
System.FormatException: String was not recognized as a valid DateTime.
Which is understandable when using the following method to parse:
DateTime.Parse(x.process_date.Value)
Anyone dealt with complex date formats that may know how to parse that?
You can use the DateTime.ParseExact method (or DateTime.TryParseExact, to cleanly handle parsing failures) to accomplish this. These methods allow you to explicitly specify the format string.
Something like this could work:
var dateString = "Tue Aug 04 2015 00:17:38 GMT+0000 (UTC)";
var format = "ddd MMM dd yyyy HH:mm:ss GMT+0000 (UTC)";
var parsed = DateTime.ParseExact(
dateString,
format,
System.Globalization.CultureInfo.InvariantCulture);
Or, using TryParseExact:
DateTime parsed;
if (DateTime.TryParseExact(
dateString,
format,
System.Globalization.CultureInfo.InvariantCulture,
DateTimeStyles.None,
out parsed)
{
// parsing was successful
}
else
{
// parsing failed
}
Here's a breakdown of the format string used here:
ddd - The abbreviated name of the day of the week.
MMM - The abbreviated name of the month.
dd - The day of the month, from 01 through 31.
yyyy - The year as a four-digit number.
HH:mm:ss - The hour, using a 24-hour clock from 00 to 23; the minute, from 00 through 59; and the second, from 0 through 59 (delimited by : characters).
GMT+0000 (UTC) - just static text that the format string assumes will always be present. This is pretty brittle and could cause your parsing to fail if the API ever returns different text here. Consider truncating this text, or using NodaTime which offers great support for time zones.
You might need to tweak this format string slightly to your usage -- for example, it wasn't clear from your question whether or not you are using a 12-hour clock or a 24-hour clock.
For more information on how to build a format string, see Custom Date and Time Format Strings on MSDN.
Alternatively, you could eschew using System.DateTime in favor of NodaTime. I'm less familiar with NodaTime myself, but great documentation is available both here on StackOverflow and on NodaTime's site.
Related
I'm having difficulty figuring out the correct way to convert a nonstandard format string into a DateTime object.
Consider the following string:
Mon Nov 25 14:07:13 2019
I'm attempting to convert using the following code snippet with a custom format:
CultureInfo provider = CultureInfo.InvariantCulture;
var sInstallDate = "Mon Nov 25 14:07:13 2019";
DateTime.TryParseExact(sInstallDate, "0:ddd MMM d h:mm:ss tt yyyy", provider, DateTimeStyles.None, out parsedDate);
The format I'm using does not work, it throws an exception.
How do I complete this conversion?
This works for me:
CultureInfo provider = CultureInfo.InvariantCulture;
var sInstallDate = "Mon Nov 25 14:07:13 2019";
DateTime.TryParseExact(sInstallDate, "ddd MMM d HH:mm:ss yyyy", provider, DateTimeStyles.None, out var parsedDate);
Just slightly adjusting the format string to ddd MMM d HH:mm:ss yyyy results in 11/25/2019 2:07:13 PM.
You need to use HH because the hour is in 24 hours format, while h expects 12. H would also work, if your input hour does not have a leading zero on single digit hours, but based on your minutes, the leading zero would be consistent.
The tt can be removed, because there is no "AM" / "PM" designator in your input, as it is covered by the 24 hour format.
I'm not sure what you were trying to do with the 0:, but it was causing issues. The 0 would be treated as a literal, meaning your input would have been required to start with "0", which it didn't. The : is treated as a time separator, which would have really confused the parser in that location. Removing these characters allowed the string to be parsed correctly.
If needed, all custom format strings can be found here: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
As a side note, the exception you were getting must have been coming from a different part of your code. TryParseExact won't throw an exception if it fails to parse the input string with the given format, it will just return false.
I'm trying to parse DateTime data from podcast XML.
Basically, it comprises http header format.
(Format-A) Fri, 28 Aug 2015 00:00:00 EST
But, sometimes it has the different format with 4 digit days and month like below.
(Format-B) Thur, 30 July 2015 00:00:00 EST
I don't know why the Podcast provides 2 different formats at the same time.
I thought I could simply parse this format as this website mentioned.
https://www.dotnetperls.com/datetime-parse
But it didn't work with just DateTime.Parse() method
So I wrote this code.
try
{
dtPubDate = DateTime.ParseExact(strhttpTime,
"ddd, dd MMM yyyy HH:mm:ss 'EST'",
CultureInfo.InvariantCulture.DateTimeFormat,
DateTimeStyles.AssumeUniversal);
}
catch (FormatException)
{
dtPubDate = DateTime.ParseExact(strhttpTime,
"dddd, dd MMMM yyyy HH:mm:ss 'EST'",
CultureInfo.InvariantCulture.DateTimeFormat,
DateTimeStyles.AssumeUniversal);
}
As I wrote this code, if the first format doesn't work, try the second one.
But it still got the exception with Format-B.
This URL is what am having the problem with.
http://www.thebreathingmusic.com/podcast/podcast.xml
As you can see, there are 2 different formats with pubDate tag.
What am I missing?
The format string dddd will match against the entire day name, e.g. "Thursday", not 4 characters.
From the docs:
The "dddd" custom format specifier (plus any number of additional "d" specifiers) represents the full name of the day of the week. The localized name of the day of the week is retrieved from the DateTimeFormatInfo.DayNames property of the current or specified culture.
You could just trim everything before the comma and parse that instead.
var tidyDate = strhttpTime.Split(',')[1].Trim();
dtPubDate = DateTime.ParseExact(
tidyDate,
"ddd, dd MMM yyyy HH:mm:ss 'EST'",
CultureInfo.InvariantCulture.DateTimeFormat,
DateTimeStyles.AssumeUniversal);
How can I convert Tue, 01 Nov 2016 02:00 PM EET datetime string to DateTime in C#? What is a good practice to do it?
Use DateTime.TryParseExact with a format string that represents a generic datetime.
If you can have multiple formats then use the DateTime.TryParseExact overload that takes an array of formats.
You can find all the format strings here:
Custom Date and Time Format Strings
For example, "Tue" is represented by "ddd", "Nov" by "MMM" etc.
NOTE: The string formats are case sensitive so while "M" represents the month number, "m" represents the minute number. Getting them mixed up will cause the parse to fail.
By replacing timezone abbreviation with zone offset you can convert using DateTime.ParseExact
string date = "Tue, 01 Nov 2016 02:00 PM EET";
DateTime dt = DateTime.ParseExact(date.Replace("EET", "+2"), "ddd, dd MMM yyyy hh:mm tt z", CultureInfo.InvariantCulture);
and if you want more safer way by checking exception then you can using DateTime.TryParseExact method
Use DateTime.TryParseExact where the format string is built using this table.
Custom date and time formats does not recognize timezone abbrevations. You need to escape them as a string literal delimiter.
var dt = DateTime.ParseExact("Tue, 01 Nov 2016 02:00 PM EET",
"ddd, dd MMM yyyy hh:mm tt 'EET'",
CultureInfo.InvariantCulture);
dt.Dump();
I have an MVC application.
At controller(from view) I am getting start date as string "Tue Jan 01 2008 00:00:00 GMT 0100 (Central Europe Standard Time)".
Could anybody please tell me how to convert this datetime to normal dd-mmy-yyyy hh:mm:ss at Controller level.
Thanks in advance....
You need to use the DateTime.ParseExact method and supply the correct format string so the code knows what each part of the input string represents.
CultureInfo provider = CultureInfo.InvariantCulture;
string format = "ddd MMM dd yyyy hh:mm tt zzz";
result = DateTime.ParseExact(dateString, format, provider);
Double check the format strings against the documentation there are several subtle and not so subtle gotchas:
"h" represents the hour in 12 hour clock
"hh" represents the hour in 12 hour clock with leading zero
"HH" represents the hour in 24 hour clock with leading zero
"m" represents a minute from 0 to 59
"M" represents a month from 1 to 12
etc.
So you may find that you think your format string is OK for the examples you have, but then a new string will come along which won't parse. You'll have to examine it to see if you've got hours in 12 or 24 hour format, etc.
Though you will have to strip of the timezone name from the end of the string first as that won't be recognised by ParseExact.
I am currently trying to parse a string that is obtained from an xml that is downloaded from the web every few minutes. The string looks like this:
Thu Jul 12 08:39:56 GMT+0100 2012
At first I just did a string.split and took out everything after the time (GMT+0100 2012) and inserted 2012 after the date.
This worked great until the date changed to:
Thu Jul 12 08:39:56 GMT+0000 2012
So I would like to dynamically pasre the GMT+ whatever as they send me that string in c#.
Any advice would be appreciated.
You can use DateTime.ParseExact with a custom date and time format string:
DateTime.ParseExact("Thu Jul 12 08:39:56 GMT+0000 2012",
"ddd MMM dd hh:mm:ss 'GMT'K yyyy",
CultureInfo.InvariantCulture)
This will throw a format exception if the string and format string do not match exactly, so you may want to use DateTime.TryParseExact that will return a false if it fails.
Instead of DateTime you may want to use DateTimeOffset that preserved timezone information , as #Keith commented - this may be important to your application.
Two things you can do: First, you should be able to use a custom format string with a ParseExact method, either from DateTime or DateTimeOffset (I would use DateTimeOffset if the actual time zone of the stamp is important, and not just the equivalent time in UTC or your local time zone).
Have a look: DateTime custom format string
The format string would probably be something like #"ddd MMM dd HH:mm:ss 'GMT'zzzz yyyy".
However, there's one snag; the .NET time zone offset ("zzzz" or simply "K") always includes a colon between the hour and minute when expressed as a string, which your input strings do not have. There is no way I know of to specify that the time zone offset doesn't/shouldn't have this colon, and I'm pretty sure that trying to parse it without a colon would cause an error.
The simplest workaround is to remove that specific colon from the string prior to parsing it. The code for that given your input is simply to remove the last colon character in the string:
var updatedString = inputString.Remove(inputString.LastIndexOf(':'), 1);
Try DateTime.Parse method to parse your date.
This should work:
XmlConvert.ToDateTime(textBox1.Text, "ddd MMM dd HH:mm:ss 'GMT'zzzz yyyy");