Как удалить зависимость DateTime.Parse от System.Threading.Thread.CurrentThread.CurrentCulture - PullRequest
2 голосов
/ 28 июля 2010

Рассмотрим следующий код:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("fo-FO");
            var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
            var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
            Console.WriteLine("Was able to parse with fo-FO");
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: {0}", e);
        }

        try
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
            var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
            Console.WriteLine("Was able to parse with en-US");
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: {0}", e);
        }
    }
}

Вывод:

Exception: System.FormatException: String was not recognized as a valid DateTime.
   at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
   at System.DateTime.Parse(String s, IFormatProvider provider)
   at DateTimeTest2.Program.Main(String[] args) in C:\Projects\DateTimeTest2\DateTimeTest2\Program.cs:line 17
Was able to parse with en-US

Этот фрагмент кода доказывает, что DateTime.Parse использует Thread.CurrentThread.CurrentCulture независимо от того, что передается «InvariantCulture». Я считаю это настолько не интуитивным, что считаю это «ошибкой».

Почему мы должны передавать CultureInfo, если в любом случае он фактически игнорируется DateTime.Parse? Есть ли способ вызова DateTime.Parse способом, который не зависит от CurrentCulture?

Ответы [ 5 ]

9 голосов
/ 28 июля 2010

Этот фрагмент кода доказывает, что DateTime.Parse использует Thread.CurrentThread.CurrentCulture независимо от того, передается ли «InvariantCulture» в

Я не уверен, как этот примердоказывает это.Строки, переданные в DateTime.Parse, отличаются, поэтому неудивительно, что получаются разные результаты.

Первая строка имеет время, отформатированное как 23.59.59, которое (очевидно) InvariantCulture не может проанализировать;вторая строка имеет время, отформатированное как 23:59:59, которое InvariantCulture может разобрать.В чем проблема?

изменить , чтобы добавить, так как, по-видимому, это имеет значение, я работаю с .NET 2.0 и строки, производимые fo-FO и en-US соответственно

9999-12-31T23.59.59Z

и

9999-12-31T23:59:59Z
1 голос
/ 06 мая 2015

Если вы не хотите соблюдать часовой пояс при разборе, вы можете использовать

var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);

или

var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
1 голос
/ 28 июля 2010

из MSDN:

Инвариантная культура нечувствительна к культуре.Ваше приложение указывает инвариантную культуру по имени, используя пустую строку ("") или по идентификатору языка.InvariantCulture извлекает экземпляр инвариантной культуры.Он связан с английским языком, но не с какой-либо страной / регионом.

Я не смог найти никаких ссылок на использование культуры текущего потока, поскольку это было бы нелогично, как вы сказали.

Вы можете (в качестве обходного пути) кэшировать культуру текущего потока, установить для нее известную хорошую культуру (en-US), выполнить анализ, а затем установить культуру потока на старое значение.

CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
System.Threading.Thread.CurrentThread.CurrentCulture = ci;

Это будет гарантировать, что вы знаете, какая культура используется для анализа строки DateTime, и не повлияет на внешний код вызова, поскольку культура никогда не изменяется с внешней стороны.

0 голосов
/ 28 июля 2010

В дополнение к тому, что написал AakashM:

Я попытался запустить его в .NET 3.5 SP1. Во втором случае я получаю исключение System.FormatException, в котором указано, что значение DateTime выходит за пределы диапазона.

0 голосов
/ 28 июля 2010

В обоих синтаксических анализах используется InvariantCulture, что на самом деле является жестко заданной ссылкой на культуру «en-US» (могут быть случаи, когда InvariantCulture не «en-US», но я не пришел через них).

Замените ваше использование InvariantCulture на new CultureInfo("en-US"), и станет понятно, почему первый анализ не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...