web-dev-qa-db-ja.com

PST / CEST / UTC / etcの形式のタイムゾーンでDateTimeを解析します

私は次のような国際日時文字列を解析しようとしています:

24-okt-08 21:09:06 CEST

これまでのところ、私は次のようなものを持っています:

CultureInfo culture = CultureInfo.CreateSpecificCulture("nl-BE");
DateTime dt = DateTime.ParseExact("24-okt-08 21:09:06 CEST",
    "dd-MMM-yy HH:mm:ss ...", culture);

問題は、フォーマット文字列の「...」に何を使うべきですか? Custom Date and Time Format String を見ると、MSDNページはPST/CEST/GMT/UTC形式のタイムゾーンを解析するための形式文字列をリストしていないようです。

43
thelsdj

私の知る限り、タイムゾーンの略語は認識されません。ただし、略語をタイムゾーンオフセットに置き換えても問題ありません。例えば。:

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);
32
Panos

簡単な答えは、それはできないということです。


その理由は次のとおりです。

世界のタイムゾーンの決定的なデータベースがあります。これは IANA here から取得できます。

問題は、3文字または4文字の略語がIANAタイムゾーンと多対1の関連付けを持っていることです。例えば ​​ - "AMT" は、文化、世界のどの部分、アプリケーションのコンテキストに応じて、さまざまなことを意味します。

AMT "Armenia Time" Asia          UTC + 4 hours 
AMT "Amazon Time"  South America UTC - 4 hours 

本当にこれに取り組む場合は、 Noda Time を使用してInstancesを表すことをお勧めします。略語を標準のIANAタイムゾーンに変換するコードを記述する必要があります。

あなたのためにこれを行うことはできません、それはあなたのアプリケーションのコンテキストに依存します。


別の良い例は "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 
22
Jodrell

Search&replaceルートに行くことにした場合の略語の辞書(私がやった)。

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"}
        };
9
Jussi Palo

あなたが何を求めているのか正確にはわからないので、2つの答えがあります。

1)CultureInfoを使用していることがわかります。したがって、文化固有の日付と時刻をformatだけにしたい場合は、日付/時刻を分離しますタイムゾーン、日付/時刻にカルチャメソッドを適用し、タイムゾーンを追加します。 「CEST」が文化によって異なる場合は、すべてのオプションをリストすることで変更する必要があります(おそらくcaseステートメントで)。

2)日付/時刻を別のタイムゾーンに変換する場合、CultureInfoを使用できません。

読むことをお勧めします: http://msdn.Microsoft.com/en-us/library/ms973825.aspx

また、.net framework 3.5クラスTimeZoneInfo(TimeZoneとは異なる)を使用して、生活を楽にすることもできます。

http://msdn.Microsoft.com/en-us/library/system.timezoneinfo.aspx

3
hmak

こうやって:

  1. 文字列を取得します(前提条件:形式:ddd、dd MMM yyyy HH:mm:ss zzz)
  2. 最後の空白を取得する
  3. 文字列からzzzを削除しますが、zzzの値は保存します
  4. Zzzのルックアップオフセット
  5. 文字列にオフセットを追加
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);

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"}
};
0
Stefan Steiger