Parse DateTime with time zone of form PST/CEST/UTC/etc
Solution 1
AFAIK the time zone abbreviations are not recognized. However if you replace the abbreviation with the time zone offset, it will be OK. E.g.:
DateTime dt1 = DateTime.ParseExact("24-okt-08 21:09:06 CEST".Replace("CEST", "+2"), "dd-MMM-yy HH:mm:ss z", culture);
DateTime dt2 = DateTime.ParseExact("24-okt-08 21:09:06 CEST".Replace("CEST", "+02"), "dd-MMM-yy HH:mm:ss zz", culture);
DateTime dt3 = DateTime.ParseExact("24-okt-08 21:09:06 CEST".Replace("CEST", "+02:00"), "dd-MMM-yy HH:mm:ss zzz", culture);
Solution 2
The quick answer is, you can't do it.
Here is why,
There is a definitive database of world timezones, you can get it from the IANA here.
The problem is, the 3 or 4 letter abbreviations have a many-to-one association with the IANA timezones. For instance "AMT"
means different things, depending on your culture, what part of the world you are in and the context of your application.
AMT "Armenia Time" Asia UTC + 4 hours
AMT "Amazon Time" South America UTC - 4 hours
If you really want to tackle this, I suggest using Noda Time to represent your Instance
s. You'll have to write some code to convert the abbreviations to a standard IANA timezone.
We can't do this for you, it depends on the context of your application.
Another good example is "CST"
.
CST "China Standard Time" Asia UTC + 8 hours
CST "Central Standard Time" Central America UTC - 6 hours
CST "Cuba Standard Time" Caribbean UTC - 5 hours
CST "Central Standard Time" North America UTC - 6 hours
Solution 3
Dictionary of abbreviations if you decide to go the search&replace route (I did).
Dictionary<string, string> _timeZones = new Dictionary<string, string>() {
{"ACDT", "+1030"},
{"ACST", "+0930"},
{"ADT", "-0300"},
{"AEDT", "+1100"},
{"AEST", "+1000"},
{"AHDT", "-0900"},
{"AHST", "-1000"},
{"AST", "-0400"},
{"AT", "-0200"},
{"AWDT", "+0900"},
{"AWST", "+0800"},
{"BAT", "+0300"},
{"BDST", "+0200"},
{"BET", "-1100"},
{"BST", "-0300"},
{"BT", "+0300"},
{"BZT2", "-0300"},
{"CADT", "+1030"},
{"CAST", "+0930"},
{"CAT", "-1000"},
{"CCT", "+0800"},
{"CDT", "-0500"},
{"CED", "+0200"},
{"CET", "+0100"},
{"CEST", "+0200"},
{"CST", "-0600"},
{"EAST", "+1000"},
{"EDT", "-0400"},
{"EED", "+0300"},
{"EET", "+0200"},
{"EEST", "+0300"},
{"EST", "-0500"},
{"FST", "+0200"},
{"FWT", "+0100"},
{"GMT", "GMT"},
{"GST", "+1000"},
{"HDT", "-0900"},
{"HST", "-1000"},
{"IDLE", "+1200"},
{"IDLW", "-1200"},
{"IST", "+0530"},
{"IT", "+0330"},
{"JST", "+0900"},
{"JT", "+0700"},
{"MDT", "-0600"},
{"MED", "+0200"},
{"MET", "+0100"},
{"MEST", "+0200"},
{"MEWT", "+0100"},
{"MST", "-0700"},
{"MT", "+0800"},
{"NDT", "-0230"},
{"NFT", "-0330"},
{"NT", "-1100"},
{"NST", "+0630"},
{"NZ", "+1100"},
{"NZST", "+1200"},
{"NZDT", "+1300"},
{"NZT", "+1200"},
{"PDT", "-0700"},
{"PST", "-0800"},
{"ROK", "+0900"},
{"SAD", "+1000"},
{"SAST", "+0900"},
{"SAT", "+0900"},
{"SDT", "+1000"},
{"SST", "+0200"},
{"SWT", "+0100"},
{"USZ3", "+0400"},
{"USZ4", "+0500"},
{"USZ5", "+0600"},
{"USZ6", "+0700"},
{"UT", "-0000"},
{"UTC", "-0000"},
{"UZ10", "+1100"},
{"WAT", "-0100"},
{"WET", "-0000"},
{"WST", "+0800"},
{"YDT", "-0800"},
{"YST", "-0900"},
{"ZP4", "+0400"},
{"ZP5", "+0500"},
{"ZP6", "+0600"}
};
Solution 4
I have two answers because I'm not exactly sure what you are asking.
1) I see you are using CultureInfo, so if you just want to format the date and time to be culture specific, I would separate the date/time and timezone, apply culture method on the date/time and append the timezone. If "CEST" is different for different cultures, you will have to change it by listing all the options (maybe in a case statement).
2) If you want date/time to be converted to another timezone, you can't use CultureInfo,
I suggest reading: http://msdn.microsoft.com/en-us/library/ms973825.aspx
You can also use the .net framework 3.5 class TimeZoneInfo (different from TimeZone) to make your life easier.
http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx
Solution 5
This is how:
- Get the string (precondition: format: ddd, dd MMM yyyy HH:mm:ss zzz)
- Get the last whitespace
- Remove zzz from string, but save value of zzz
- Lookup offset for zzz
- Add offset to string
string dateString = reader.ReadContentAsString(); int timeZonePos = dateString.LastIndexOf(' ') + 1; string tz = dateString.Substring(timeZonePos); dateString = dateString.Substring(0, dateString.Length - tz.Length ); dateString += s_timeZoneOffsets[tz]; // https://msdn.microsoft.com/en-us/library/w2sa9yss(v=vs.110).aspx //string es = reader.ReadElementString("pubDate"); this.m_value = System.DateTime.ParseExact(dateString, "ddd, dd MMM yyyy HH:mm zzz", System.Globalization.CultureInfo.InvariantCulture);
with
private static System.Collections.Generic.Dictionary<string, string> s_timeZoneOffsets =
new System.Collections.Generic.Dictionary<string, string>() {
{"ACDT", "+10:30"},
{"ACST", "+09:30"},
{"ADT", "-03:00"},
{"AEDT", "+11:00"},
{"AEST", "+10:00"},
{"AHDT", "-09:00"},
{"AHST", "-10:00"},
{"AST", "-04:00"},
{"AT", "-02:00"},
{"AWDT", "+09:00"},
{"AWST", "+08:00"},
{"BAT", "+03:00"},
{"BDST", "+02:00"},
{"BET", "-11:00"},
{"BST", "-03:00"},
{"BT", "+03:00"},
{"BZT2", "-03:00"},
{"CADT", "+10:30"},
{"CAST", "+09:30"},
{"CAT", "-10:00"},
{"CCT", "+08:00"},
{"CDT", "-05:00"},
{"CED", "+02:00"},
{"CET", "+01:00"},
{"CEST", "+02:00"},
{"CST", "-06:00"},
{"EAST", "+10:00"},
{"EDT", "-04:00"},
{"EED", "+03:00"},
{"EET", "+02:00"},
{"EEST", "+03:00"},
{"EST", "-05:00"},
{"FST", "+02:00"},
{"FWT", "+01:00"},
{"GMT", "+00:00"},
{"GST", "+10:00"},
{"HDT", "-09:00"},
{"HST", "-10:00"},
{"IDLE", "+12:00"},
{"IDLW", "-12:00"},
{"IST", "+05:30"},
{"IT", "+03:30"},
{"JST", "+09:00"},
{"JT", "+07:00"},
{"MDT", "-06:00"},
{"MED", "+02:00"},
{"MET", "+01:00"},
{"MEST", "+02:00"},
{"MEWT", "+01:00"},
{"MST", "-07:00"},
{"MT", "+08:00"},
{"NDT", "-02:30"},
{"NFT", "-03:30"},
{"NT", "-11:00"},
{"NST", "+06:30"},
{"NZ", "+11:00"},
{"NZST", "+12:00"},
{"NZDT", "+13:00"},
{"NZT", "+12:00"},
{"PDT", "-07:00"},
{"PST", "-08:00"},
{"ROK", "+09:00"},
{"SAD", "+10:00"},
{"SAST", "+09:00"},
{"SAT", "+09:00"},
{"SDT", "+10:00"},
{"SST", "+02:00"},
{"SWT", "+01:00"},
{"USZ3", "+04:00"},
{"USZ4", "+05:00"},
{"USZ5", "+06:00"},
{"USZ6", "+07:00"},
{"UT", "-00:00"},
{"UTC", "-00:00"},
{"UZ10", "+11:00"},
{"WAT", "-01:00"},
{"WET", "-00:00"},
{"WST", "+08:00"},
{"YDT", "-08:00"},
{"YST", "-09:00"},
{"ZP4", "+04:00"},
{"ZP5", "+05:00"},
{"ZP6", "+06:00"}
};
thelsdj
C# business logic programmer by day, electronic music and science fiction fan by night
Updated on July 08, 2022Comments
-
thelsdj almost 2 years
I'm trying to parse an international datetime string similar to:
24-okt-08 21:09:06 CEST
So far I've got something like:
CultureInfo culture = CultureInfo.CreateSpecificCulture("nl-BE"); DateTime dt = DateTime.ParseExact("24-okt-08 21:09:06 CEST", "dd-MMM-yy HH:mm:ss ...", culture);
The problem is what should I use for the '...' in the format string? Looking at the Custom Date and Time Format String MSDN page doesn't seem to list a format string for parsing timezones in PST/CEST/GMT/UTC form.
-
Vitaliy Ulantikov about 11 yearsWill this handle Daylight Time?
-
Matt Johnson-Pint over 8 yearsSorry, but this approach is unreliable. Any hardcoded list of abbreviation to offset is opinionated with regard to ambiguities, and is just a snapshot in time.
-
Jussi Palo over 8 yearsOf course it is. It is equally (un)reliable as using these non-standardized time zones in the first place. My answer is just backing up the accepted answer. Remember to down-vote that as well.
-
Vincent Vancalbergh over 8 yearsSome people (I'd go even further and say most) actually only receive data pertinent to a single culture. This approach, while inperfect, will suffice.
-
gzak over 8 yearsNo, it will not, since the offset is being specified manually here.
-
gzak over 8 yearsTechnically this is still doable, since you can pass a
CultureInfo
object to the parser to disambiguate your context. -
Jodrell about 8 years@gzak, yes, if you wanted the abbreviations localised to a passed culture you could work out the mappings.
-
Panagiotis Kanavos about 7 yearsThis is unreliable, even for a single culture. Russia changed DST rules many times in the past 4 years. Mapping the abbreviation to an IANA or Windows tz name and looking up the current rules is far more reliable
-
Matt Johnson-Pint over 6 yearsNo you couldn't. Culture info will tell you things about the user's language and cultural preferences. It will tell you nothing about a user's time zone. My culture might be
en-US
even if I'm visiting Japan. -
Jodrell over 6 years@MattJohnson but if your culture is
en-US
we could infer thatCST
meant"Central Standard Time" North America UTC -6
to you regardless of your timezone, even if it wereUTC-5
. Of course, what is appropriate for one application may be inappropriate for another. In abstract, you can't tell, as my answer states. With enough context, part of which would be he culture, we could tell. -
Matt Johnson-Pint over 6 years"en-US" is intended to mean "English as spoken in the United States". In other words, US is referring to dialect, not location. Why would it be correct to infer Central Standard Time from CST just because I speak English in the way that Americans do? Sure, Americans say "CST", but we might also say that referring to China - especially if we happen to be in China. :)
-
Jodrell over 6 years@MattJohnson, as we are agreeing, additional context is necessary.
-
JohnB about 6 yearsThank you. Yes there were lots of bad answers.
-
Ryan Bemrose almost 6 yearsThis is still a bad answer for reasons discussed elsewhere on this page. You are hardcoding assumptions about what abbreviations like "AMT" or "CST" mean. The problem is this question has no good answer; the codes are ambiguous, and no lookup table can be definitive. These assumptions may have sufficed to solve OP's problem, but they were not stated in the question.
-
thelem almost 6 yearsIt will, provided you have a Replace call for all the timezones you might receive and the source date uses the correct timezone (e.g. doesn't use EST when they mean EDT)
-
MIKE over 5 yearsso wait.. does it handle daylight time or not?
-
jpmc26 over 5 yearsDo not put "Necromancing" declarations in your posts. These are clutter; SO has no policy about activity on old questions. If anything, it is somewhat encouraged since new answers arise as technology changes.
-
jpmc26 over 5 years@MattJohnson Because as an United States English speaker in Japan using your device configured to your normal culture, you would probably not type CST in an application to mean something other than U.S. Central. Admittedly, it's not definitive, but it's okay as a heuristic.
-
Stefan Steiger over 5 years@MIKE: Considering CEST (central european summer time) and CET (central european [winter] time) are not the same, then yes. However, a call to replace is risky, as you don't know if CEST/CET occurs in the date string for culture X.
-
boatcoder over 2 yearsIf given a choice between right some of the time and right none of the time, I'll take "some" of the time for the project I'm currently working on. Right now I'd have to punt without using a crutch like this which might get it wrong.....
-
Stefan Steiger over 2 years@jpmc26: I put those declaration in my posts when I answer an old question. The idea is, that people see that low-vote-count compared to other answers is due to that the answer is new, and not that the answer is bad. Though, it is true that one could already see this when looking at the answer-date - so consequently, that declaration is always redundant.
-
Stefan Steiger over 2 years@Ryan Bemrose: Actually, I'm assuming they are windows-timezones, so the abbrevations are unambiguous. It's true however, that IANA time-zones would be ambiguous, thus there would be no solution. Assuming the input values are from windows-machines, which would be true in 95% of cases of desktop machines, this works best. If you'd be running the code on a Linux-machine however, you'd first have to map the posix-timezones generated from C# to windows-timezones for lookup-purposes. I have the code for this somewhere, but if it's unambiguous, is a good question.
-
Stefan Steiger over 2 yearsAnybody, you might be interested in github.com/ststeiger/ews-managed-api/blob/master/…