4

特定のカルチャで、現在のスレッドのカルチャをそのカルチャに設定し、RFC1123形式のDateTimeに基づいて文字列を出力し、それをDateTimeに変換しようとすると、製品にバグが発生しました。失敗します。最も頭を悩ませる失敗は、イタリア語のmartediのように、それをmarで始まる単語に翻訳する曜日がある多くの文化からのものです。構文解析ルーチンは「mar」を参照し、英語で3月を意味し、すべてが失敗すると思いますが、それは単なる推測です。私が話していることを正確に説明するために私が知っている最良の方法は、コードを提供することです。

using System;
using System.Globalization;
using System.Threading;

namespace RFC1123Test
{
    class Program
    {
    static void Main(string[] args)
    {
        //list taken from http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo(v=vs.71).aspx
        var culturesToTest = new string[] { String.Empty /*invariant culture*/, "af", "af-ZA", 
        "sq", "sq-AL", "ar", "ar-DZ", "ar-BH", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", 
        "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", 
        "ar-AE", "ar-YE", "hy", "hy-AM", "az", "az-AZ-Cyrl", "az-AZ-Latn", "eu", "eu-ES", 
        "be", "be-BY", "bg", "bg-BG", "ca", "ca-ES", "zh-HK", "zh-MO", "zh-CN", "zh-CHS", 
        "zh-SG", "zh-TW", "zh-CHT", "hr", "hr-HR", "cs", "cs-CZ", "da", "da-DK", "div", 
        "div-MV", "nl", "nl-BE", "nl-NL", "en", "en-AU", "en-BZ", "en-CA", "en-CB", 
        "en-IE", "en-JM", "en-NZ", "en-PH", "en-ZA", "en-TT", "en-GB", "en-US", "en-ZW", 
        "et", "et-EE", "fo", "fo-FO", "fa", "fa-IR", "fi", "fi-FI", "fr", "fr-BE", "fr-CA",
        "fr-FR", "fr-LU", "fr-MC", "fr-CH", "gl", "gl-ES", "ka", "ka-GE", "de", "de-AT", 
        "de-DE", "de-LI", "de-LU", "de-CH", "el", "el-GR", "gu", "gu-IN", "he", "he-IL", 
        "hi", "hi-IN", "hu", "hu-HU", "is", "is-IS", "id", "id-ID", "it", "it-IT", 
        "it-CH", "ja", "ja-JP", "kn", "kn-IN", "kk", "kk-KZ", "kok", "kok-IN", "ko",
        "ko-KR", "ky", "ky-KZ", "lv", "lv-LV", "lt", "lt-LT", "mk", "mk-MK", "ms", 
        "ms-BN", "ms-MY", "mr", "mr-IN", "mn", "mn-MN", "no", "nb-NO", "nn-NO", "pl",
        "pl-PL", "pt", "pt-BR", "pt-PT", "pa", "pa-IN", "ro", "ro-RO", "ru", "ru-RU", 
        "sa", "sa-IN", "sr-SP-Cyrl", "sr-SP-Latn", "sk", "sk-SK", "sl", "sl-SI", "es",
        "es-AR", "es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-SV", "es-GT",
        "es-HN", "es-MX", "es-NI", "es-PA", "es-PY", "es-PE", "es-PR", "es-ES", "es-UY",
        "es-VE", "sw", "sw-KE", "sv", "sv-FI", "sv-SE", "syr", "syr-SY", "ta", "ta-IN", 
        "tt", "tt-RU", "te", "te-IN", "th", "th-TH", "tr", "tr-TR", "uk", "uk-UA", "ur", 
        "ur-PK", "uz", "uz-UZ-Cyrl", "uz-UZ-Latn", "vi", "vi-VN" };

        //2:30 PM local time
        var timeOfDayForTest = TimeSpan.FromHours(14).Add(TimeSpan.FromMinutes(30));

        CultureInfo cultureForTest = null;
        foreach (var culture in culturesToTest)
        {
        bool suitableForTest = true;
        try
        {
            cultureForTest = new CultureInfo(culture);
            Thread.CurrentThread.CurrentCulture = cultureForTest;
            Thread.CurrentThread.CurrentUICulture = cultureForTest;
        }
        catch
        {
            suitableForTest = false;
        }
        if (suitableForTest)
        {
            //be sure to do a date for every day of the week
            for (int i = 0; i < 7; i++)
            {
            runTest(cultureForTest, DateTime.Now.Date.Add(timeOfDayForTest).AddDays(i));
            }
        }
        }
    }

    private static void runTest(CultureInfo culture, DateTime dt)
    {
        //string representation of RFC1123 pattern
        string rfc1123Date = dt.ToUniversalTime().ToString(CultureInfo.CurrentCulture.DateTimeFormat.RFC1123Pattern);

        bool parseFails = false;
        DateTime parsedDt = DateTime.MinValue;
        try
        {
        parsedDt = Convert.ToDateTime(rfc1123Date);
        }
        catch
        {
        parseFails = true;
        }
        if (parseFails)
        {
        Console.WriteLine(String.Format("ERROR: {0} [{1}] parse failed for [{2}].",
            culture.Name, culture.NativeName, rfc1123Date));
        }
        else
        {
        if (parsedDt.Ticks == dt.Ticks)
        {
            //success!
            //Console.WriteLine(String.Format("SUCCESS: {0} [{1}] worked just fine for {2}.",
            //culture.Name, culture.NativeName, rfc1123Date));
        }
        else
        {
            Console.WriteLine(String.Format("ERROR: {0} [{1}] parsed successfully for {2} but parsed date does not match.",
            culture.Name, culture.NativeName, rfc1123Date));
        }
        }
    }
    }
}

出力は次のとおりです。

ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Dins, 12 Jul 2011 18:30:00 GMT].
ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Woen, 13 Jul 2011 18:30:00 GMT].
ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Dond, 14 Jul 2011 18:30:00 GMT].
ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Vry, 15 Jul 2011 18:30:00 GMT].
ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Sat, 16 Jul 2011 18:30:00 GMT].
ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Son, 17 Jul 2011 18:30:00 GMT].
ERROR: af-ZA [Afrikaans (Suid Afrika)] parse failed for [Maan, 18 Jul 2011 18:30:00 GMT].
ERROR: sq-AL [shqipe (Shqip‰ria)] parse failed for [Mar, 12 Kor 2011 18:30:00 GMT].
ERROR: sq-AL [shqipe (Shqip‰ria)] parse failed for [Sht, 16 Kor 2011 18:30:00 GMT].
ERROR: gl-ES [galego (galego)] parse failed for [mar, 12 xull 2011 18:30:00 GMT].
ERROR: it-IT [italiano (Italia)] parse failed for [mar, 12 lug 2011 18:30:00 GMT].
ERROR: it-CH [italiano (Svizzera)] parse failed for [mar, 12 lug 2011 18:30:00 GMT].
ERROR: it-CH [italiano (Svizzera)] parse failed for [gio, 14 lug 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 12 7 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 13 7 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 14 7 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 15 7 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 16 7 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 17 7 2011 18:30:00 GMT].
ERROR: ja-JP [??? (??)] parse failed for [?, 18 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 12 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 13 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 14 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 15 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 16 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 17 7 2011 18:30:00 GMT].
ERROR: ko-KR [??? (????)] parse failed for [?, 18 7 2011 18:30:00 GMT].
ERROR: es-AR [Espa¤ol (Argentina)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-BO [Espa¤ol (Bolivia)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-CL [Espa¤ol (Chile)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-CO [Espa¤ol (Colombia)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-CR [Espa¤ol (Costa Rica)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-DO [Espa¤ol (Rep£blica Dominicana)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-EC [Espa¤ol (Ecuador)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-SV [Espa¤ol (El Salvador)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-GT [Espa¤ol (Guatemala)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-HN [Espa¤ol (Honduras)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-MX [Espa¤ol (M‚xico)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-NI [Espa¤ol (Nicaragua)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-PA [Espa¤ol (Panam )] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-PY [Espa¤ol (Paraguay)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-PE [Espa¤ol (Per£)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-PR [Espa¤ol (Puerto Rico)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-ES [espa¤ol (Espa¤a)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-UY [Espa¤ol (Uruguay)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].
ERROR: es-VE [Espa¤ol (Republica Bolivariana de Venezuela)] parse failed for [mar, 12 jul 2011 18:30:00 GMT].

だから私の質問は、なぜこのコードが機能しないのですか?

4

2 に答える 2

6

RFC1123Patternに関する注意事項は、不変カルチャを使用して解析されることです。以下が機能するはずです。

string rfc1123Date = dt.ToUniversalTime().ToString("R");

...

parsedDt = Convert.ToDateTime(rfc1123Date);

出力のテール:

成功:vi-VN [Tiê'ngVi?t(Vi?t Nam)]は、2011年7月13日18:30:00GMTの水曜日に問題なく機能しました。成功:vi-VN [Tiê'ngVi?t(Vi?t Nam)]は、2011年7月14日18:30:00GMT(グリニッジ標準時)の木曜日に問題なく機能しました。成功:vi-VN [Tiê'ngVi?t(Vi?t Nam)]は、2011年7月15日18:30:00GMTの金曜日に問題なく機能しました。成功:vi-VN [Tiê'ngVi?t(Vi?t Nam)]は、2011年7月16日18:30:00GMTの土曜日に問題なく機能しました。成功:vi-VN [Tiê'ngVi?t(Vi?t Nam)]は、2011年7月17日18:30:00GMTの日曜日に問題なく機能しました。成功:vi-VN [Tiê'ngVi?t(Vi?t Nam)]は、2011年7月18日18:30:00GMTの月曜日に問題なく機能しました。

于 2011-07-12T18:02:07.420 に答える
6

DateTime.ParseExactテキストの日付を生成するために使用したのと同じフォーマットプロバイダーで使用してみてください。

DateTime.ParseExact(rfc1123Date, CultureInfo.CurrentCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.CurrentCulture).ToLocalTime()

于 2011-07-12T18:07:03.540 に答える