How do I parse an RFC822 date in .NET? - c#

I have the following datetime string as returned to me by the Twitter API:
"Thu Apr 26 11:38:36 +0000 2012"
I need to convert this to a DateTime object so I call ParseExact with a custom format specifier:
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime publishDate = DateTime.ParseExact(tweet["created_at"].ToString(), "ddd MMM dd hh:mm:ss zzz yyyy", provider);
However, this raise a FormatException exception for any variant of z, zz or zzz for the time zone:
String was not recognized as a valid DateTime.
Looking at the MSDN documentation it's clear that that format specifier is expecting the time zone to be in the format zz:zz where there is a colon in the time zone to delimit the hours and minutes.
I've checked other questions on Stack Overflow like:
How do I parse and convert DateTime’s to the RFC 822 date-time format?
Parsing an RFC822-Datetime in .NETMF 4.0
and none of them really help.
Is there a time zone specifier I can use that will correctly parse this format?

Really silly this one.
The problem was the hour specifier. I'd used "hh" which is for 12 hour clock times. For 24 hour times I should have used "HH".
Note the subtle difference.
Changing that it all works as expected.

Related

C# Parse to the yyyy-MM-ddTHH:mm:ss format String was not recognized as a valid DateTime

I'm trying to Parse Mon, 11 Mar 2019 09:13:16 +0100 to 2019-03-11T09:13:16
string dataa = "Mon, 11 Mar 2019 09:13:16 +0100";
DateTime d = new DateTime();
d = DateTime.ParseExact(dataa,"yyyy-MM-ddTHH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine("data: "+d);
But the error is:
String was not recognized as a valid DateTime.
Is there any method to do this parsing automatically? Thanks to everyone.
update
As mentioned below, like the other users replied to me, I needed the function ToString(String, IFormatProvider) in the first place.
When you use ParseExact, your string and format should match exactly.
The proper format is: ddd, d MMM yyyy hh:mm:ss zzz (or HH which depends on your hour format)
After you parse it, you need to use ToString to format it with yyyy-MM-dd'T'hh:mm:ss format (or HH which depends you want 12-hour clock or 24-hour clock format)
I think I have to add little bit more explanation that a lot of people confuse (specially who are beginner about programming). A DateTime instance does not have any format. It just have date and time values which is basicly a numeric value called Ticks. When you talk about "format" concept, that points to textual representation which is string.
Since you said "Mon, 11 Mar 2019 09:13:16 +0100 to 2019-03-11T09:13:16", I (and probably a lot of people also) assume that you have a string as Mon, 11 Mar 2019 09:13:16 +0100 and you want to get 2019-03-11T09:13:16 as a string from it. For that, you need to parse your string to DateTime first. For that, as you do, ParseExact is one option.
When you parse it to DateTime, you get it's textual representation, which is string, with ToString method. This method have a few overloads and you should use ToString(String, IFormatProvider) overload. With that, you specify your output format as a first parameter, and your culture info as a second parameter which it might effect on your result string because of the : and / format specifiers since they can change based on the current culture or supplied culture.
Further reading: Custom Date and Time Format Strings
You need to specify the format that the input data has (the second parameter of DateTime.ParseExact). In your case, the data you provide has the format ddd, d MMM yyyy hh:mm:ss zzz. Also, in the last line, where you print the result you have to format it.
So, this is how you have to do it:
string dataa = "Mon, 11 Mar 2019 09:13:16 +0100";
DateTime d = new DateTime();
d = DateTime.ParseExact(dataa, "ddd, d MMM yyyy hh:mm:ss zzz", System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine("data: " + d.ToString("yyyy-MM-dd'T'hh:mm:ss"));

DateTime.ParseExact issue with non-standard timezone string

I'm talking to web service that is returning me a date in this format
Fri, 02 Oct 2009 05:33:11 - 0500
I've been trying to parse it into a DateTime in C# and get an invalid string error.
String was not recognized as a valid DateTime
Here is the code:
string text = "Fri, 02 Oct 2009 05:33:11 - 0500";
DateTime date = DateTime.ParseExact(text,"ddd, dd MMM yyyy h:mm:ss - zzzzz", null);
If I remove the - 0500 and the - zzzz from the ParseExact argument, it works just fine. Not sure what I'm doing wrong on the timezone though. Any direction would be appreciated. I've tried different counts of the "z" and removing the "-" also assuming it was confusing that for negative.
You simply, can't.
Your input is not a valid string which can parsed to DateTime unless you do some string manipulation in it. And your offset part must have semi colon (:) to parse it.
Also you need to use hh specifier (or preferable HH) since your hour part has a leading zero.
I can only think one way, get the last index of white space, remove it, insert : between your hours and minutes of offset, and parse it to DateTimeOffset since your string has UTC Offset part.
string text = "Fri, 02 Oct 2009 05:33:11 -05:00";
var dto = DateTimeOffset.ParseExact(text, "ddd, dd MMM yyyy HH:mm:ss zzz",
CultureInfo.InvariantCulture, DateTimeStyles.None);
Now you have a DateTimeOffset as 2.10.2009 05:33:11 -05:00 and you can use it's DateTime, LocalDateTime or UtcDateTime properties.

Issue regarding convert numeric value to 24 hrs format time

I was trying to convert a numeric value to 24 hours format time but the code is not working. Here is my code:
string xx =
Convert.ToDateTime(TimeSpan.FromHours(01).ToString())
.ToString("HH", System.Globalization.CultureInfo.InvariantCulture);
OR
string xx1 =
new DateTime(TimeSpan.FromHours(01).Ticks)
.ToString("HH", System.Globalization.CultureInfo.InvariantCulture);
OR
var t = DateTime.Now.TimeOfDay;
string xx2 =new DateTime(t.Ticks).ToString("hh:mm:ss tt");
OR
string ss = TimeSpan.FromHours(01).ToString("HH");
The above code is not working. I searched Google and everyone said use HH for getting hour in 24 hours format. Can anyone tell me if this is specific issue to my PC?
getting no error rather first line of code return 01 instead of 13.
Because you adding 1 hour from midnight. You should add 13 hour instead like;
string xx = Convert.ToDateTime(TimeSpan.FromHours(13).ToString())
.ToString("HH", System.Globalization.CultureInfo.InvariantCulture);
Since TimeSpan.FromHours(01).ToString() returns 01:00:00 as a string, Convert.ToDateTime parse this string as 13/01/2015 01:00:001.
And 24-hour clock representation of a 01 will be the same as itself no matter you use hh or HH specifier.
On your second example, you calculate your TimeSpan as a Ticks and DateTime(Int64) constructor calculates this time from 01/01/0001 and your DateTime evantually will be 01/01/0001 01:00:00 and still, it's 24-hour clock representation will be 01.
On your third example, you are calling DateTime(Int64) constructor with TimeOfDay property, that's why your DateTime will be 01.01.0001 15:10:36 (when I run your example right now) and it's hh:mm:ss tt representation will be 03:11:31 PM in InvariantCulture.
Your fourth line throws FormatException because there is no standard or custom HH format specifier of a TimeSpan.
1: Since you parse only hour without date, this method returns date part as a today

Date conversion

I need help to convert current date to "Tue Nov 4 00:00:00 UTC+0530 2014" date format
using C#.
Say I have date like : DateTime dt = DateTime.Now;
Now, how can I convert it in mentioned format.
DateTime.ToString(string) allows you to specify a format for your date. You can construct a custom format using Custom Date and Time Format Strings.
I feel like taking risk to answer your question but anyway..
A DateTime doesn't have any implicit format. It just have date and time values etc.. That's why it is not possible to have any format. But string representations of them can have a format. Formatting a DateTime is easy, just need to use DateTime.ToString() method with a specific culture. (In your case looks like InvariantCulture is a good candidate)
DateTime dt = DateTime.Now;
dt.ToString("ddd MMM d HH:mm:ss 'UTC+0530' yyyy", CultureInfo.InvariantCulture);
returns
Tue Nov 4 14:20:36 UTC+0530 2014
AFAIK, time zone abbreviations are not standardized and that's why there is way to parse them besides literal string delimiter. Also since a DateTime doesn't keep offset value, you need also parse it as a literal string delimiter
If you would want to +05:30 instead +0530 as a result, "zzz" custom format specifier would be a nice choice since it gets + or - sign, hours and minutes part offset of local operating system's time zone from UTC.
Based upon your suggestions, I build this code
DateTimeOffset localTime = DateTimeOffset.Now;
string.Format("{0:ddd MMM d HH:mm:ss} UTC+{1} {0:yyyy}", localTime, localTime.Offset.ToString("hhmm"));
and its generating correct format:
"Tue Nov 4 18:25:48 UTC+0530 2014"

Parsing custom date formats (c#)

An api im using is providing me a date. This date is of type string and is presented in the format:
Mon Nov 16 19:15:09 +0000 2009
DateTime.TryParse() fails when this value is provided. Can anyone point me in the right direction?
Using the DateTimeOffset class in order to handle the offset.
[TestMethod]
public void test()
{
string s = "Mon Nov 16 19:15:09 +0000 2009";
var result = DateTimeOffset.ParseExact(
s,
"ddd MMM dd HH:mm:ss zzz yyyy",
System.Globalization.CultureInfo.InvariantCulture);
Assert.AreEqual(16, result.Day);
Assert.AreEqual(11, result.Month);
Assert.AreEqual(2009, result.Year);
Assert.AreEqual(19, result.Hour);
Assert.AreEqual(15, result.Minute);
Assert.AreEqual(9, result.Second);
Assert.AreEqual(0, result.Offset.Hours);
}
Change the offset in the string - e.g. '0600' and then change the offset assertion to match, it'll work.
You can then convert this into a DateTime if you have to - but you lose the offset information; so you have to decide whether you're going to keep it as the original local time (19:15:09), or if you're going to convert to some standard time (e.g. 13:19:05 UTC if offset is +06:00).
It gets interesting if you need to convert that to your own local time - because it would depend on what DST rules were in place in 2009 at that time of the year - that can cause a real headache!
So, if you're going to DateTime I recommend converting to universal time and then go from there. Add this to the test:
Console.WriteLine(result);
//little bit long winded - but you need the 'Universal' Kind for reliability
Console.WriteLine(
DateTime.SpecifyKind(
new DateTime(result.ToUniversalTime().Ticks),
DateTimeKind.Utc)
);
This outputs:
11/16/2009 19:15:09 +06:00
11/16/2009 13:15:09
Try DateTime.TryParseExact passing a suitable format string.
Because the DateTime.TryParse(String, DateTime) 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.TryParse(String, IFormatProvider, DateTimeStyles, DateTime) method or one of the overloads of the TryParseExact method and provide a format specifier.
One of the TryParse methods accepts an IFormatProvider, which can also come as a DateTimeFormatInfo class. The following link has all the necessary details:
http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx
Yours would be almost like: ddd, MMM dd yyyy HH':'mm':'ss zzz yyyy
The only problem is the timezone offset, zzz includes a colon between the hours and minutes. You might get away with using zz'00' though it is cheating.

Categories