1

I have this string "Sun Aug 02 2015 00:15:47 GMT+0000 (UTC)"

I created this much of the datetime format "ddd MMM dd yyyy HH:mm:ss"

Now im not sure what to do with the ending part of that datetime string. Im not sure if the string I have is a standard format for UTC that can be easily converted or if its a custom format.

Nonetheless, I want to turn that string datetime into a datetime object.

imGreg
  • 900
  • 9
  • 24
  • Take a look at this answer and the use of ParseExact. http://stackoverflow.com/questions/919244/converting-a-string-to-datetime – cost Aug 02 '15 at 20:27
  • Is it just this single string, or is this an example? If it varies, is the string *always* in this format, and always ending in `"GMT+0000 (UTC)"` or does that part vary? It would help to know where the string originates from. – Matt Johnson-Pint Aug 02 '15 at 20:29
  • @MattJohnson I'm using an 3rd party api and its returning that datetime string in that format exactly every time. – imGreg Aug 03 '15 at 03:58

2 Answers2

3
string str = "Sun Aug 02 2015 00:15:47 GMT+0000 (UTC)";
var dt = DateTime.ParseExact(str, "ddd MMM dd yyyy HH:mm:ss \"GMT\"zzzz \"(UTC)\"", CultureInfo.InvariantCulture);
EZI
  • 15,209
  • 2
  • 27
  • 33
  • "zzzz" is not a valid format specifier. Additionally, with this approach the result will have `DateTimeKind.Local` instead of `DateTimeKind.Utc`. – Matt Johnson-Pint Aug 02 '15 at 21:07
  • @MattJohnson `"zzzz" is not a valid format specifier` Do you think I posted this answer before testing it? For the other part, I am not good in DateTime things. Maybe adding a `.ToUniversalTime();` can solve it. – EZI Aug 02 '15 at 21:09
  • [The list of valid format specifiers can be found here](https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx). – Matt Johnson-Pint Aug 02 '15 at 21:14
  • @MattJohnson Good, now how about testing the code above? Maybe I discovered something undocumented :) – EZI Aug 02 '15 at 21:19
  • 1
    Anything more than three `z`'s are ignored, and treated as `zzz`. Still the above code only works if you don't consider `DateTimeKind`. If you check the kind here, it will be `DateTimeKind.Local` - which is probably not desired. – Matt Johnson-Pint Aug 02 '15 at 21:26
  • @MattJohnson If you're assumption about number of z's were correct ParseExact wouldn't return a date 5 min different than the original one for this `"Sun Aug 02 2015 00:15:47 GMT+0005 (UTC)";` – EZI Aug 02 '15 at 21:32
  • With the `DateTime` type, all assumptions are off. You have to read the docs - and then some. In this case, the number of `z` characters does not necessarily match up to the number of digits in the offset. Specifically [the docs for `zzz`](https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx#zzzSpecifier) show that it is for output formatting in `+hh:mm` format. What's not super clear in the docs is that *any* of `zz`, `zzz`, or `K` have the same effect with regard to *parsing*. – Matt Johnson-Pint Aug 02 '15 at 21:36
  • @MattJohnson I meant this: `Anything more than three z's are ignored` It works correctly even for `GMT:+1235` so all 4 `z`s are used somehow by ParseExact. – EZI Aug 02 '15 at 21:40
  • 1
    Yes, but it also works correctly when you specify `zz`, or `zzz` - even when you have four significant digits in the offset. Still - either way, the result is incorrect because it's `.Kind` property is off. See my answer. – Matt Johnson-Pint Aug 02 '15 at 21:58
2

I would consider one of these two approaches:

string str = "Sun Aug 02 2015 00:15:47 GMT+00:00 (UTC)";
str = str.Substring(0, str.IndexOf('(') - 1);
DateTime dt = DateTime.ParseExact(str, "ddd MMM dd yyyy HH:mm:ss 'GMT'K",
    CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);

or

string str = "Sun Aug 02 2015 00:15:47 GMT+00:00 (UTC)";
str = str.Substring(0, str.IndexOf('(') - 1);
DateTimeOffset dto = DateTimeOffset.ParseExact(str, "ddd MMM dd yyyy HH:mm:ss 'GMT'K",
    CultureInfo.InvariantCulture);

In either example, we assume that the part in parenthesis is irrelevant. This may be important if your input can vary with different time zones.

In the first example, we assume that you want the output to always be a UTC based DateTime. The input offset could vary, but the output will always be adjusted to Coordinated Universal Time, and will have DateTimKind.Utc.

In the second example, we assume that you want the output to match exactly what was provided in the input. To do this, the output needs to be a DateTimeOffset type. Otherwise, you wouldn't be able to track offsets that didn't exactly match UTC or your own local time zone.

I prefer the second option. If you need a DateTime, you can always get one by calling the .DateTime, .UtcDateTime, or .LocalDateTime properties of the resulting DateTimeOffset.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • `+1`. This is definitely a better approach. Even MSDN mentioned that `z..` formats are not recommended using with `DateTime` since it doesn't _even_ store any offset value (or timezone information). And also `DateTimKind` issue. `Local` can be ambiguous when you do something with that `DateTime` such as saving in a database etc.. – Soner Gönül Aug 03 '15 at 13:51