Мой компьютер настроен с культурой not en-US
.
При использовании встроенной функции Win32 GetDateFormat
я получаю правильно отформатированные даты:
- 22//11//2011 4:: 42:: 53 P ̰̃ M]
Это правильно; а также то, как Windows это делает:
панель задач
Настройки региона и языка
Проводник Windows
Outlook
Когда я пытаюсь преобразовать дату в строку в .NET, используя мою текущую локаль, например:
DateTime.Now.ToString();
DateTime.Now.ToString(CultureInfo.CurrentCulture);
Я получаю неправильную дату:
- 22////11////2011 4:: 42:: 53 P ̰̃ M]
Эта ошибка в .NET очевидна в Windows, где используется багги Код .NET:
Средство просмотра событий Windows:
Планировщик заданий:
Студия управления SQL Server:
Как сделать .NET не ошибкой?
Как мне преобразовать даты и время в строки с использованием текущей культуры (правильно)?
Примечание. Пользователь имеет право устанавливать свои Windows в соответствии с любыми желаемыми языковыми настройками. Как и сейчас, моя программа не будет обрабатывать правильные настройки. Говорить пользователю, "Не делай этого", довольно злобно.
Аналогичный пример исходит от Delphi, который предполагает, что дата разделитель никогда не может быть более одного символа. Когда Windows настроен с локалью, которая использует несколько символов для даты разделитель, например:
- sk-SK (Словацкая - Словакия):
.
где даты должны быть отформатированы как:
22. 11. 2011
библиотека кода не может принять разделитель даты дольше, чем один символ, и возвращается к:
22/11/2011
В прошлом некоторые могли бы предлагать вам не беспокоиться о таком краю случаи. Такие предложения не имеют никакого веса со мной.
Я не буду вступать в модный матч с тем, кто хочет изменить смысл моего вопроса, изменив название. Но вопрос не ограничивается псевдо-локалями, в частности предназначенные для поиска ошибок в приложениях.
Бонус-чат
Здесь представлен уникальный список форматов дат со всего мира:
- 11.11.25
- 11.25.2011
- 11/25/2011
- 2011.11.25
- 2011.11.25.
- 2011/11/25
- 2011-11-25
-
-
- 2011
-
Особый интерес представляет последний пример, в котором не использует gregorian calendar:
- Арабский (Саудовская Аравия)
ar-SA
: 29/12/32 02:03:07 م - Дивехи (Мальдивы)
dv-MV
: 29/12/32 14:03:07 - Дари/Пашто (Афганистан)
prf-AF / ps-AF
: 29/12/32 2:03:07 غ.و
Хотя это крайние случаи, о которых вам никогда не придется беспокоиться.
Обновление 14//12//2011:
Другая демонстрация ошибки заключается в том, что Datetime.Parse
не может разобрать DateTime.ToString
:
String s = DateTime.Today.ToString("d"); //returns "14////12////2011"
DateTime d = DateTime.Parse(s); //expects "dd//MM//yyyy"
.Parse
выдает исключение.
Обновление 02//8, 2012 09:: 56'12:
Любое использование разделителя дат лишено, кроме того, что оно неверно. Из MSDN:
LOCALE_SDATE
Windows Vista и более поздняя версия:. Эта константа устарела. Вместо этого используйте
LOCALE_SSHORTDATE
. Пользовательский языковой стандарт может не иметь единого символа разделителя. Например, допустим такой формат, как "12/31, 2006".LOCALE_STIME
Windows Vista и более поздняя версия:. Эта константа устарела. Вместо этого используйте
LOCALE_STIMEFORMAT
. Пользовательский языковой стандарт может не иметь единого символа разделителя. Например, допустим такой формат, как "03: 56'23".