2009-08-18 3 views
10

У меня возникла проблема, которая, вероятно, связана с моим неправильным пониманием того, как работает метод DateTime.ToShortTimeString(). При форматировании строки времени с помощью этой функции, я предполагал, что он будет уважать «Короткое время» настройки в настройках формата Windows 7.Почему DateTime.ToShortTimeString() не учитывает формат Short Time в «Regional and Language Settings»?

Control Panel -> Clock, Language and Region -> Region and Language -> Formats Tab.

Однако .NET, кажется, выбрать короткий формат времени не основываясь на этой установке, но на основе при нынешней культуре:

Region and Language -> Location -> Current Location

Я сделал некоторые испытания на Windows 7 RC:

 
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 // HH:mm (United Kingdom) 
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 // hh:mm (United Kingdom) 
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM // HH:mm (United States) 
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM // hh:mm (United States) 
Culture: el-GR, 6AM: 6:00 πμ, 6PM: 6:00 μμ // HH:mm (Greece) 
Culture: el-GR, 6AM: 6:00 πμ, 6PM: 6:00 μμ // hh:mm (Greece) 

я использовал эль-GR, как это было культура, что пользователь, который ТЕЗИСЫ ДОКЛАДА он также тестировал это на Vista SP2 и Win 7 RC с тем же результатом.

Вопрос в два раза: 1) Каково мое непонимание форматов .NET и Windows? 2) Какое наилучшее решение для создания короткой временной строки (HH: mm или hh: mm tt) на основе операционной системы, в идеале это должно работать в Mono, поэтому я бы предпочел не читать из реестра или P/Invoke.

Метод, используемый для создания вышеуказанного, для последующего использования и тестирования.

[STAThread] 
static void Main(string[] args) 
{ 
    CultureInfo culture = CultureInfo.CurrentCulture; 

    DateTime sixAm = new DateTime(2009, 07, 05, 6, 0, 0); // 6AM 
    DateTime sixPm = new DateTime(2009, 07, 05, 18, 0, 0); // 6PM 

    string sixAmString = sixAm.ToShortTimeString(); 
    string sixPmString = sixPm.ToShortTimeString(); 

    string format = "Culture: {0}, 6AM: {1}, 6PM: {2}"; 

    string output = String.Format(format, culture, sixAmString, sixPmString); 
    Console.WriteLine(output); 
    Clipboard.Clear(); 
    Clipboard.SetText(output); 

    Console.ReadKey(); 
} 

Обновление: Основываясь на комментарии Майка ниже я приспособил выше метод со следующими изменениями:

Следующие две строки

string sixAmString = sixAm.ToShortTimeString(); 
string sixPmString = sixPm.ToShortTimeString(); 

изменено на

string sixAmString = sixAm.ToString("t", culture); 
string sixPmString = sixPm.ToString("t", culture); 

Я имею в виду o изменил переменную культуры для использования CultureInfo.CurrentUICulture.

Это несчастливо не работает так, как я надеялся, выход независимо от конфигурации короткий промежуток времени в Windows 7 вкладке Форматы был:

 
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM 

Кажется CultureInfo.CurrentUICulture всегда ен- НАС.

ответ

1

В ответ на каждый из моих вопросов:

1) Что такое мое непонимание .NET и Windows, форматы?

Короткий ответ: связь между параметром «Короткое время» отсутствует в настройках «Региональный и язык» и свойство ShortTimePattern .NET. Однако свойство LongTimePattern продиктовано настройкой «Длительное время».

Я приспособил вышеупомянутый метод, заменив два форматирование строки:

string sixAmString = sixAm.ToString("T", culture.DateTimeFormat); 
string sixPmString = sixPm.ToString("T", culture.DateTimeFormat); 

Вот выход:

 
Culture: en-GB, 6AM: 06:00:00, 6PM: 18:00:00 // HH:mm:ss 
Culture: en-GB, 6AM: 06:00:00 AM, 6PM: 06:00:00 PM //hh:mm:ss tt 

В нижней части this article объяснена проблема для меня.

2) Какое наилучшее решение для создания короткой временной строки (HH: mm или hh: mm tt) на основе настройки операционной системы?

Я не знаю о лучшем решении, но я создал следующую функцию, которая преобразует LongTimeFormat в ShortTimeFormat, что позволяет приложению следовать за параметром users, если они меняют «Long Time» (хотя он выиграл ' t отслеживать настройку «короткое время»).

static string GetShortTimeString(DateTime ShortTimeString) 
{ 
    DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat; 
    string ShortTimePattern = dateTimeFormat.LongTimePattern.Replace(":ss", String.Empty); 
    ShortTimePattern = ShortTimePattern.Replace(":s", String.Empty); 

    return ShortTimeString.ToString(ShortTimePattern); 
} 

Выход после внесения изменений выше:

 
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 
Culture: en-GB, 6AM: 06:00 AM, 6PM: 06:00 PM 

P/Invoke вариант заключается в использовании GetTimeFormat прохождения TIME_NOSECONDS с использованием DateTime.ToString (Format), как указано выше. Я не тестировал это, так как я бы предпочел не использовать P/Invoke.

5

Ответ на ваш второй вопрос

DateTimeFormat.Format(DateTime.Now, "t", CultureInfo.CurrentUICulture); 

или

DateTime.Now.ToString("t", CultureInfo.CurrentUICulture); 

Это на самом деле всегда лучше использовать явные методы, которые принимают CultureInfo. Нет никакой последовательности, как .Net выбирает, что использовать по умолчанию либо CurrentCulture, либо CurrentUICulture, либо InvarinatCulture.

Чтобы сделать полный ответ. Также я расскажу о различиях между культурами.

So CurrentCulture - это «Панель управления -> Часы, язык и регион -> Регион и язык -> вкладка« Форматы ». Это культура, которую вы ожидаете от своих расчетов.Например, вы можете делать свой учет в США, так что вы должны настроить его в США.

CurrentUICulture - это «Регион и язык -> Язык отображения» означает, что когда вы являетесь эмигрантом из Украины, вы хотите, чтобы ваше приложение было локализовано в UA (но все расчеты все еще находятся в США).

И InvariantCulture - так называемый культурный агностический язык. Вы должны использовать это для хранения информации и так далее. Эффективно это En-US.

Примечание: Я могу ошибаться, когда каждая настройка находится в окнах. Но вы, вероятно, поняли.

+0

Спасибо, я сделаю некоторое тестирование с этим и внедряюсь. На что еще влияет культура, отличная от даты, времени, валюты, десятичной и тысячи разделителей? –

+1

Месяц, названия дней недели. LTR/RTL. Сортировка строк. Операции верхнего и нижнего регистров со строками. Сериализация. –

+0

CultureInfo.CurrentUICulture кажется en-US, где еще это можно настроить? Я попробовал репотировать после проверки, что все было установлено в Соединенном Королевстве. Я также заметил, что иногда после запуска программы он не сразу меняет культуру. Однако запуск его второй раз всегда подбирает его. –

2

Я уверен, что короткая строка формата времени не используется в DateTime.ToShortTimeString() или DateTime.ToString ("t") является ошибкой, поскольку она была исправлена ​​в .NET framework 4.0.

+0

Это должен быть принятый ответ, так как это объясняет, почему ShortTimePattern не использует текущие настройки региона. Быстрая проверка с помощью модульного теста в проекте 3.5 и один в проекте 4.0, и вы увидите, что 3.5 игнорирует все, что задано в диалоге региона и языка – nrjohnstone