DateTime.ParseExact issue with non-standard timezone string - c#

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.

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"));

String was not recognized as a valid DateTime 01:01:0001 error

I have string as follow:
var StringDate = "Mon Oct 02 2017 16:44:23 GMT 0200 (Central European Summer Time)"
DateTime dt = DateTime.Parse(StringDate);
When I convert this string to date I have error: "String was not recognized as a valid DateTime Exception." and dt = "01:01:0001 00:00:00"
That's not a valid Date/Time format that c# automatically recognizes.
Use this format instead:
var StringDate = "Mon Oct 02 2017 16:44:23 +0200";
DateTime dt = DateTime.Parse(StringDate);
You'll need to modify your incoming string. Use regex for that (take out the parenthesis section, remove the "GMT", and add a plus before the time offset).
The other option is to use DateTime.ParseExact(), however you still need to modify your incoming string:
var input = "Mon Oct 02 2017 16:44:23 GMT +0200 (Central European Summer Time)";
var dateTime = DateTime.ParseExact(
input,
"ddd MMM dd yyyy HH:mm:ss 'GMT' zz'00' '(Central European Summer Time)'",
CultureInfo.InvariantCulture);
C# expects any timezone info to have a - or + before the number, so there is no way to extract the time zone information without adding in that character. Simply "assuming" it is a positive value is not enough.
Also, there is no wildcards for exact format matching, meaning that (Central European Summer Time) will be hard-coded in your match string. You're going to run into a lot of problems if you have multiple different time zones - or even if the name of the time zone changes (such as when Daylight Savings time toggles).

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"

How do I parse an RFC822 date in .NET?

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.

how do I specify the timezone on a DateFormat string?

I'm trying to specify the timezone on a string that I am passing to DateFormat.parse. We're currently using .net framework 2.0. Current code is
DateTimeFormatInfo DATE_FORMAT = CultureInfo.CurrentCulture.DateTimeFormat;
DateTime first = DateTime.Parse("Wed, 31 Oct 2007 8:00:00 -5", DATE_FORMAT);
But then when I do first.ToString("r"), the result is
Wed, 31 Oct 2007 09:00:00 GMT
What am I doing wrong? I also tried using DateTime.SpecifyKind method to set my DateTime object's Kind to Local, but it seems like you would need to specify the kind as local before you parse the string, if the timezone is part of the string.
My local timezone is EDT, that's what I'm ultimately trying to get this date to.
Edit - our solution:
input :
DateTime first = DateTime.SpecifyKind(DateTime.Parse("OCT 31, 2007 8:00 AM", DATE_FORMAT), DateTimeKind.Local);
output :
first.ToLocalTime().ToString("our format")
Still haven't found a way to get time zone abbreviation, like 'EDT'.
Use the ToLocalTime() method before calling ToString().
first.ToLocalTime().ToString();
You can use the "zz" or "zzz" date formats to give you -5 or -5:00.
When you call first.ToString("r"),
Here is what based on MSDN
Represents a custom date and time
format string defined by the
DateTimeFormatInfo..::.RFC1123Pattern
property. The pattern reflects a
defined standard and the property is
read-only. Therefore, it is always the
same, regardless of the culture used
or the format provider supplied. The
custom format string is "ddd, dd MMM
yyyy HH':'mm':'ss 'GMT'".
You can pass the defined format information into ToString, try to call this method
DateTime..::.ToString Method (IFormatProvider)
Instead, and pass your DateTimeFormatInfo object.
Have a look at the DateTimeOffset struct, I think this is what you need.
Try using ParseExact() - you can specify what goes where.
In your case, you can parse it with:
string str = "Wed, 31 Oct 2007 8:00:00 -5";
string fmt = "ddd, dd MMM yyyy H:mm:ss z";
DateTime d = DateTime.ParseExact(str, fmt, null);
Console.WriteLine(d);

Categories