4

Possible Duplicate:
Parse DateTime with timezone of form PST/CEST/UTC/etc

I have a date string in the following format

Fri, 14 Dec 2012 6:52 am PST

I want to convert it to date time. I am using DateTime.TryParseExact to achieve it, but I am not able to read the time zone. If I change the string (without the time zone) to

Fri, 14 Dec 2012 6:52 am

and use

DateTime.TryParseExact(DateString, "ddd, dd MMM yyyy h:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None,out dt)

it works. How can I read the time zone.

Edit - I am getting the data from the Yahoo weather API (e.g. http://weather.yahooapis.com/forecastrss?w=2420380).

Thanks.

Community
  • 1
  • 1
arunlalam
  • 1,838
  • 2
  • 15
  • 23

4 Answers4

9

I don't believe there's a custom date and time format specifier which handles time zones (as opposed to current UTC offsets). Even if there were, time zone abbreviations are potentially ambiguous, so they're generally poor as a way of communicating time zone information. Unfortunately they're widely used, of course...

I suspect you'll be best off creating a map from abbreviation to "best guess time zone", then stripping whatever's after the last space from your input string, and using that to get the zone.

Just in case anyone was wondering, Noda Time doesn't handle this yet either - but I'm hoping to make progress on it at some point :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • This is probably the best option, but it's still not great. Particularly since some abbreviations are used in multiple places (eg, CST is used by Australia, North America and China, with very different offsets). Also remember that people frequently misuse daylight/standard abbreviations (eg, say CDT when they're actually on Standard time, or vice versa). You'd want to look at the date to see if it's actually during standard vs daylight time. http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations – Brian Reischl Dec 14 '12 at 15:56
  • @BrianReischl: Absolutely - that's why I specifically pointed out the ambiguity. But unfortunately it's the best we've got at the moment :( – Jon Skeet Dec 14 '12 at 15:58
  • Ah, right. I read that as referring to the ambiguity during the Daylight/Standard switchover, but I see you probably meant both. – Brian Reischl Dec 14 '12 at 16:00
6

Yeah ok it is not possible, but its not a Solution for the Problem. So what I do is trying to find a solution for arunlalam :)

Here it is (UPDATED: Corrected timezones -/+):

    public static string[][] TimeZones = new string[][] {
        new string[] {"ACDT", "+1030", "Australian Central Daylight"},
        new string[] {"ACST", "+0930", "Australian Central Standard"},
        new string[] {"ADT", "-0300", "(US) Atlantic Daylight"},
        new string[] {"AEDT", "+1100", "Australian East Daylight"},
        new string[] {"AEST", "+1000", "Australian East Standard"},
        new string[] {"AHDT", "-0900", ""},
        new string[] {"AHST", "-1000", ""},
        new string[] {"AST", "-0400", "(US) Atlantic Standard"},
        new string[] {"AT", "-0200", "Azores"},
        new string[] {"AWDT", "+0900", "Australian West Daylight"},
        new string[] {"AWST", "+0800", "Australian West Standard"},
        new string[] {"BAT", "+0300", "Bhagdad"},
        new string[] {"BDST", "+0200", "British Double Summer"},
        new string[] {"BET", "-1100", "Bering Standard"},
        new string[] {"BST", "-0300", "Brazil Standard"},
        new string[] {"BT", "+0300", "Baghdad"},
        new string[] {"BZT2", "-0300", "Brazil Zone 2"},
        new string[] {"CADT", "+1030", "Central Australian Daylight"},
        new string[] {"CAST", "+0930", "Central Australian Standard"},
        new string[] {"CAT", "-1000", "Central Alaska"},
        new string[] {"CCT", "+0800", "China Coast"},
        new string[] {"CDT", "-0500", "(US) Central Daylight"},
        new string[] {"CED", "+0200", "Central European Daylight"},
        new string[] {"CET", "+0100", "Central European"},
        new string[] {"CST", "-0600", "(US) Central Standard"},
        new string[] {"EAST", "+1000", "Eastern Australian Standard"},
        new string[] {"EDT", "-0400", "(US) Eastern Daylight"},
        new string[] {"EED", "+0300", "Eastern European Daylight"},
        new string[] {"EET", "+0200", "Eastern Europe"},
        new string[] {"EEST", "+0300", "Eastern Europe Summer"},
        new string[] {"EST", "-0500", "(US) Eastern Standard"},
        new string[] {"FST", "+0200", "French Summer"},
        new string[] {"FWT", "+0100", "French Winter"},
        new string[] {"GMT", "-0000", "Greenwich Mean"},
        new string[] {"GST", "+1000", "Guam Standard"},
        new string[] {"HDT", "-0900", "Hawaii Daylight"},
        new string[] {"HST", "-1000", "Hawaii Standard"},
        new string[] {"IDLE", "+1200", "Internation Date Line East"},
        new string[] {"IDLW", "-1200", "Internation Date Line West"},
        new string[] {"IST", "+0530", "Indian Standard"},
        new string[] {"IT", "+0330", "Iran"},
        new string[] {"JST", "+0900", "Japan Standard"},
        new string[] {"JT", "+0700", "Java"},
        new string[] {"MDT", "-0600", "(US) Mountain Daylight"},
        new string[] {"MED", "+0200", "Middle European Daylight"},
        new string[] {"MET", "+0100", "Middle European"},
        new string[] {"MEST", "+0200", "Middle European Summer"},
        new string[] {"MEWT", "+0100", "Middle European Winter"},
        new string[] {"MST", "-0700", "(US) Mountain Standard"},
        new string[] {"MT", "+0800", "Moluccas"},
        new string[] {"NDT", "-0230", "Newfoundland Daylight"},
        new string[] {"NFT", "-0330", "Newfoundland"},
        new string[] {"NT", "-1100", "Nome"},
        new string[] {"NST", "+0630", "North Sumatra"},
        new string[] {"NZ", "+1100", "New Zealand "},
        new string[] {"NZST", "+1200", "New Zealand Standard"},
        new string[] {"NZDT", "+1300", "New Zealand Daylight"},
        new string[] {"NZT", "+1200", "New Zealand"},
        new string[] {"PDT", "-0700", "(US) Pacific Daylight"},
        new string[] {"PST", "-0800", "(US) Pacific Standard"},
        new string[] {"ROK", "+0900", "Republic of Korea"},
        new string[] {"SAD", "+1000", "South Australia Daylight"},
        new string[] {"SAST", "+0900", "South Australia Standard"},
        new string[] {"SAT", "+0900", "South Australia Standard"},
        new string[] {"SDT", "+1000", "South Australia Daylight"},
        new string[] {"SST", "+0200", "Swedish Summer"},
        new string[] {"SWT", "+0100", "Swedish Winter"},
        new string[] {"USZ3", "+0400", "USSR Zone 3"},
        new string[] {"USZ4", "+0500", "USSR Zone 4"},
        new string[] {"USZ5", "+0600", "USSR Zone 5"},
        new string[] {"USZ6", "+0700", "USSR Zone 6"},
        new string[] {"UT", "-0000", "Universal Coordinated"},
        new string[] {"UTC", "-0000", "Universal Coordinated"},
        new string[] {"UZ10", "+1100", "USSR Zone 10"},
        new string[] {"WAT", "-0100", "West Africa"},
        new string[] {"WET", "-0000", "West European"},
        new string[] {"WST", "+0800", "West Australian Standard"},
        new string[] {"YDT", "-0800", "Yukon Daylight"},
        new string[] {"YST", "-0900", "Yukon Standard"},
        new string[] {"ZP4", "+0400", "USSR Zone 3"},
        new string[] {"ZP5", "+0500", "USSR Zone 4"},
        new string[] {"ZP6", "+0600", "USSR Zone 5"}
        };

And the function which returns the parsable offset:

public static string TimeZoneToOffset(string tz)
    {
        tz = tz.ToUpper().Trim();
        for (int i = 0 ; i < TimeZones.Length ; i++)
        {
            if (((string)((string[])TimeZones.GetValue(i)).GetValue(0)) == tz)
            {
                return ((string)((string[])TimeZones.GetValue(i)).GetValue(1));
            }
        }
        return System.TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).ToString()
        .Replace(":", "").Substring(0, 5);
    }

Found here: http://bytes.com/topic/c-sharp/answers/214648-how-do-i-parse-date-w-time-zone

Hope it works :) Have a nice day

rboy
  • 2,018
  • 1
  • 23
  • 35
Johannes Wanzek
  • 2,825
  • 2
  • 29
  • 47
  • 1
    You might want to check those values. AEST is +10/11 not -10/11 (i live here after all) and its common to use AEST weather we are currently in DST or not as some states don't observe it and are in the same timezone (QLD doesn't and NSW does for example and they are in the same timezone). So the above will be an hour off in those circumstances as well. – White Dragon Sep 26 '13 at 04:51
3

PST is not a parseable timezone for the .NET framework - the timezone format specifiers expect a numeric offset such as -0800.

One way to deal with this is to convert every timezone to its numeric representation before attempting to parse.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • Interesting. I was looking at the link http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx and i was not able to find anything that i could match it with. Thanks for the info. – arunlalam Dec 14 '12 at 15:46
  • @arunlalam - Yes, the `k` and `z`, `zz`, `zzz` format specifiers only work with numeric timezone offsets, not named ones. There is no format specifier for named timezones. – Oded Dec 14 '12 at 15:48
2

You could replace the timezone part with the offset:

string DateString = "Fri, 14 Dec 2012 6:52 am PST";
DateTime dt;
bool parsable = DateTime.TryParseExact(
    DateString.Replace("PST", "+2")
    , "ddd, dd MMM yyyy h:mm tt z"
    , CultureInfo.InvariantCulture
    , DateTimeStyles.None
    , out dt);

Demo

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939