1

I'm trying to parse this date to DateTime but I got this error

Wed Jan 15 2020 00:00:00 GMT-0400 ' was not recognized as a valid DateTime

// dateRange = ""Mon Oct 07 2019 00:00:00 GMT-0400 (Eastern Daylight Time)Sat Nov 23 2019 00:00:00 GMT-0500 (Eastern Standard Time)";

string start = dateRange.Substring(0, 34);//"Mon Oct 07 2019 00:00:00 GMT-0400"


DateTime startDateTime = DateTime.ParseExact(start, "ddd MMM dd yyyy HH:mm:ss 'GMT'K", System.Globalization.CultureInfo.InvariantCulture);
rezion
  • 7
  • 1
  • 4
  • @RonBeyer Actually, [according to the documentation](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) single quotes around a string should make it a literal string... – Heretic Monkey Jan 23 '20 at 20:33
  • Unfortunately, there's no anchor, but in the table of format specifiers, descriptions, and examples, towards the bottom, it has `"string"` and `'string'` in the format specifiers column and `2009-06-15T13:45:30 ('arr:' h:m t) -> arr: 1:45 P` in the examples column. – Heretic Monkey Jan 23 '20 at 20:38
  • 1
    So `dateRange` is `"Wed Jan 08 2020 00:00:00 GMT-0500 (Eastern Standard Time)Sat Jan 25 2020 00:00:00 GMT-0500 (Eastern Standard Time)"` and then you take the first 34 characters, which gives you `"Mon Oct 07 2019 00:00:00 GMT-0400"` despite that being nowhere in `dateRange`, and the error message is about `"Wed Jan 15 2020 00:00:00 GMT-0400"`, which is also not part of `dateRange`. Please just show a `ParseExact()` call with a string literal passed as the first parameter. @RonBeyer Under "Character literals" at the bottom it says "By enclosing the entire literal string in ... apostrophes." – Lance U. Matthews Jan 23 '20 at 20:39
  • I concede, but I've never used it that way for anything other than a single character. – Ron Beyer Jan 23 '20 at 20:50
  • sorry i have edited the code, i was using two examples at the begenning. – rezion Jan 23 '20 at 20:57
  • Your example is still wrong. Try actually reading the value of `start`, and you'll finding the trailing space. Alternatively, try evaluating `"Mon Oct 07 2019 00:00:00 GMT-0400".Length`,and you'll find it's 33. – Douglas Jan 23 '20 at 21:43

3 Answers3

2

There's a subtle bug in your logic. The substring should take 33 characters, not 34, as the 34th character is the succeeding space:

// string start = dateRange.Substring(0, 34);  // "Wed Jan 08 2020 00:00:00 GMT-0500 "
   string start = dateRange.Substring(0, 33);  // "Wed Jan 08 2020 00:00:00 GMT-0500"
Douglas
  • 53,759
  • 13
  • 140
  • 188
1

Since your string contains an offset, you're much better off parsing it to a DateTimeOffset with the zzz specifier than to a DateTime with the K specifier.

The problem with K is that if any numeric offset is present, the kind will be treated as DateTimeKind.Local, and the date and time part of the value will be adjusted from the provided offset to the local time zone. You likely don't want that behavior.

string dateRange = "Mon Oct 07 2019 00:00:00 GMT-0400 (Eastern Daylight Time)Sat Nov 23 2019 00:00:00 GMT-0500 (Eastern Standard Time)";

string[] parts = dateRange.Split('(',')');

string format = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzz";

DateTimeOffset start = DateTimeOffset.ParseExact(parts[0].Trim(), format, CultureInfo.InvariantCulture);
DateTimeOffset end = DateTimeOffset.ParseExact(parts[2].Trim(), format, CultureInfo.InvariantCulture);

Console.WriteLine(start.ToString("o"));  // 2019-10-07T00:00:00.0000000-04:00
Console.WriteLine(end.ToString("o"));    // 2019-11-23T00:00:00.0000000-05:00

Working example here

Also, if I were to guess I'd say this format were created by concatenating the output of two JavaScript Date objects in a browser (either via toString explicitly, or just implicitly). Is that correct? If so, you should probably not send this format to your back-end, but rather call .toISOString() to get a UTC-based ISO 8601 formatted string, or use a function such as this one to get an ISO 8601 formatted string that is based on the local time of the user. Either output are much better choices to parse in your .Net code than the human-readable strings you are currently using.

One really good reason to do this is that "Mon" and "Oct" are valid abbreviations in English. You may encounter difficulties with users of other languages.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Thank you so much, yes indeed i'm cnocatenating tow strings, but the problem i have with this solution is that the output dates are compatible with my dataBase wich is expecting a dateTime – rezion Jan 23 '20 at 23:45
  • You should still *parse* with `DateTimeOffset`. From there, you can call any of `.DateTime`, `.UtcDateTime`, `.LocalDateTime` properties depending on what you're intending to represent in your database. – Matt Johnson-Pint Jan 24 '20 at 00:49
0

Welcome to StackOverflow.

I'm going to suggest a little different approach, using .NET regular expressions. (regular expression syntax reference here)

You can craft a regular expression that will extract both the start and end date from your string and ignore the rest:

string strRegex = @"(?<startDate>(.*\s*).*)\((?<startZone>.*)\)(?<endDate>(.*\s*).*)\((?<endZone>.*)\)";
Regex myRegex = new Regex(strRegex, RegexOptions.Multiline | RegexOptions.Singleline);
string dateRange = @"Wed Jan 08 2020 00:00:00 GMT-0500 (Eastern Standard Time)Sat Jan 25 2020 00:00:00 GMT-0500 (Eastern Standard Time)";

Match myMatch = myRegex.Match(dateRange);

string startDate = myMatch.Groups["startDate"].Value;
string endDate = myMatch.Groups["endDate"].Value;
Console.WriteLine(startDate);
Console.WriteLine(endDate); 

Here is the output:

Wed Jan 08 2020 00:00:00 GMT-0500 
Sat Jan 25 2020 00:00:00 GMT-0500
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Mike Marshall
  • 7,788
  • 4
  • 39
  • 63