4

I have a bunch of strings that are DateTime values dumped from some database... Probably MySql. I have no control on the structure.

The strings look like this:

2011-05-17 00:00:00 Etc/GMT

I've found solutions that involve replacing "Etc/GMT" prior to the parse. This smells bad.

Is there a one step solution to turning this string to a DateTime without stripping out the timezone info?

Haedrian
  • 4,240
  • 2
  • 32
  • 53
spender
  • 117,338
  • 33
  • 229
  • 351
  • 1
    Convert it to UTC then DateTime.Parse it. – FlemGrem Sep 18 '13 at 20:16
  • >"I could mention the fruit-based supplier, in which case I might be contractually bound to do time in prison or kill myself or something." Sorry, I know English too bad to understand this. What means "fruit-based supplier"? – Display Name Sep 18 '13 at 20:17
  • It comes from a DB dump, so the string is fixed. – spender Sep 18 '13 at 20:17
  • @SargeBorsch: I've said too much already! Think of a fruit. You probably guessed it. – spender Sep 18 '13 at 20:18
  • @spender I think it's not too much, but too little, because it's hard to understand. But it sounds interesting. – Display Name Sep 18 '13 at 20:19
  • @SargeBorsch: he's essentially saying he's under an NDA and can't say who he's working for, but gives a very big hint. – PiousVenom Sep 18 '13 at 20:19
  • 1
    @AaronH: How do you convert a string to UTC without parsing it? – spender Sep 18 '13 at 20:21
  • @MyCodeSucks but what is the purpose of that phrase? I didn't get it completely. And what is the hint? He works for Apple, maybe? Why this may be important in the question? – Display Name Sep 18 '13 at 20:22
  • It's not a big deal. The strings come from Apple. I can't change them. – spender Sep 18 '13 at 20:23
  • `Etc/GMT` looks like some very custom time zone format. I doubt you can get Framework solution to deal with it... – Alexei Levenkov Sep 18 '13 at 20:24
  • Are you beholden to only MS code, or would a [noda-time](http://nodatime.org/) solution be Ok? [(also for folks wondering Where in the World Etc/GMT is)](http://stackoverflow.com/questions/7303580/understanding-etc-gmt-timezone) – user7116 Sep 18 '13 at 20:27
  • @AzZa, I don't know of any years that have 17 months, so the answer should be self-evident. I chose this particular string to eliminate that ambiguity. – spender Sep 18 '13 at 20:29
  • @user7116: There's a thought. I'm open to any solution that actually understands the timezone rather that stripping it out. Can nodatime handle it? – spender Sep 18 '13 at 20:31
  • I don't think `DateTime` can store the so-called `TimeZone`. – King King Sep 18 '13 at 20:33
  • @KingKing: I don't need to store a TimeZone. I need to read it though in order to get a fixed point in time. I store all times as UTC. I don't know if I can trust my datasource to do the same. – spender Sep 18 '13 at 20:34

3 Answers3

6

DateTime.ParseExact

Converts the specified string representation of a date and time to its DateTime equivalent using the specified format and culture-specific format information. The format of the string representation must match the specified format exactly.

For funky formats you can use ParseExact. And you also probably want to use DateTimeStyles.AssumeUniversal:

String original = "2011-05-17 00:00:00 Etc/GMT";
DateTime result = DateTime.ParseExact(
    original,
    "yyyy-MM-dd HH:mm:ss 'Etc/GMT'",
    System.Globalization.CultureInfo.InvariantCulture,
    System.Globalization.DateTimeStyles.AssumeUniversal);
Console.WriteLine(result.ToString()); // given my timezone: 5/16/2011 8:00:00 PM
Console.WriteLine(result.ToUniversalTime().ToString()); // 5/17/2011 12:00:00 AM
Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • 2
    I don't have the opportunity to manipulate this string. It's in a (really really) huge DB dump over which I have zero control of the format. I know of ParseExact. I don't know how to get it to parse the timezone info in this format. – spender Sep 18 '13 at 20:19
  • You can parse it per normal, then play with `DateTimeOffset`. The difference (as I understand it) is the timezone offsets go between positive and negative. – Brad Christie Sep 18 '13 at 20:25
  • @spender: Assuming all read as "Etc/GMT" that should be the equiv to UTC. So just read it in as `InvariantCulture` and all should be fine. You could always specify a `DateTimeStyle` as the fourth parameter in `ParseExact` if you're _that_ worried. – Brad Christie Sep 18 '13 at 20:41
  • 2
    If taking this approach, you should probably never let it use your local time zone. You can pass `DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal`, or you can let it parse as "unspecified" and afterwards apply `DateTime.SpecifyKind(dt, DateTimeKind.Utc)`. – Matt Johnson-Pint Sep 18 '13 at 23:25
4

It appears that Noda Time contains Etc/GMT in its time zone database based on a quick look at the source.

The means by which you parse dates and times is a bit different in Noda Time than in the .Net Framework (I'm by no means an expert in Noda Time):

var pattern = ZonedDateTimePattern.CreateWithInvariantCulture(
    @"yyyy'-'MM'-'dd HH':'mm':'ss z",
    DateTimeZoneProviders.Tzdb);

var result = pattern.Parse(@"2011-05-17 00:00:00 Etc/GMT");
if (result.Success)
{
    Console.WriteLine("{0}", result.Value);
}
user7116
  • 63,008
  • 17
  • 141
  • 172
3

"Etc/GMT" is a tz aka Olson time zone specifier. These are used pretty much everywhere but Windows, as Microsoft has their own.

So, there's nothing in .NET that will help you. You'll have to go elsewhere. As user7116 mentions, Noda Time supports tz time zones and Microsoft time zones. It's an excellent library.

Annoyingly, .NET actually does not have a DateTime type with a time zone attached. It can attach an offset, which is not quite the same (a time zone can have multiple offsets depending on DST). Noda Time does support this and will be able to preserve the statement exactly.

Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
  • And even with the link you reference it's the equiv of Utc (`+00:00`) (which `DateTime.ParseExact` can handle fine when specifying `DateTimeStyles.AssumeUniversal`) – Brad Christie Sep 18 '13 at 20:52
  • UTC and GMT are *not* equivalent. UTC is an atomic time, it has no offset, and GMT is a solar time. They slowly drift apart -- this is why leap seconds exist. Leap seconds are added to UTC to ensure GMT and UTC are always less than 1 second apart. This may of course be "good enough" and probably is -- no arguments there -- but still I'd never call it equivalent. – Cory Nelson Sep 18 '13 at 20:59
  • We're talking 0.9/sec accuracy delta--I _doubt_ OP needs something _that_ finite. I'm not going to argue semantics, but for most intents and purposes they're equivalent. – Brad Christie Sep 18 '13 at 21:11
  • 1
    @CoryNelson - You are confusing GMT with UT1 and TAI. GMT actually is defined in modern parlance as identical to UTC. Besides, Windows doesn't ever track leap seconds anyway. – Matt Johnson-Pint Sep 18 '13 at 23:15
  • I should add, the reason GMT and UTC are not perfectly identical is that GMT *used* to have it's own legal definition. Saying "UTC" removes any question about it. We still say "GMT" in many places though, especially when referring to `Europe/London` when it's *not* on summer time. – Matt Johnson-Pint Sep 18 '13 at 23:30