2009-08-18 9 views
10

Wpadłem na problem, który prawdopodobnie wynika z mojego błędnego zrozumienia sposobu działania metody DateTime.ToShortTimeString(). Podczas formatowania ciągów czasowych z tej funkcji, byłem przy założeniu, że będzie respektować „Short Time” ustawienie w ustawieniach formatu Windows 7 zaDlaczego DateTime.ToShortTimeString() nie uwzględnia formatu Short Time w "Ustawienia regionalne i językowe"?

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

Jednak NET wydaje się wybrać krótki format czasu nie w oparciu o to ustawienie, ale w oparciu przy obecnej kulturze:

Region and Language -> Location -> Current Location

zrobiłem kilka testów na 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) 

użyłem el-GR jako że była kultura, że ​​użytkownik, który repor Z tym problemem testował to również w Vista SP2 i Win 7 RC z tym samym wynikiem.

Pytanie jest naprawdę dwojakie: 1) Jakie są moje nieporozumienia dotyczące formatów .NET i Windows? 2) Jakie jest najlepsze rozwiązanie do utworzenia krótkiego łańcucha czasu formatowania (HH: mm lub gg: mm tt) w oparciu o system operacyjny, najlepiej powinien działać w Mono, więc wolałbym uniknąć czytania z rejestru lub P/Odwołać się.

Metoda użyta do wygenerowania powyższego, do wykorzystania w przyszłości i do testowania.

[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(); 
} 

Aktualizacja: Na podstawie uwag Mike'a poniżej I dostosowany powyższy sposób, z następującymi zmianami:

następujące dwa wiersze

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

zmieniona na

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

I als o zmieniono zmienną hodowlaną, aby używać CultureInfo.CurrentUICulture.

To niestety nie działa tak jak miałem nadzieję, wyjście niezależnie od konfiguracji krótki czas w zakładce Windows 7 za formatów było:

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

Wydaje się CultureInfo.CurrentUICulture jest zawsze en- NAS.

Odpowiedz

1

W odpowiedzi na każde z moich pytań:

1) Co to jest nieporozumienie z .NET i Windows formatów?

Krótka odpowiedź brzmi, że nie ma powiązania między ustawieniem "Krótki czas" w ustawieniach "Regionalny i język" i właściwości .NET ShortTimePattern. Jednak właściwość LongTimePattern jest podyktowana ustawieniem "Long Time".

I dostosowany powyższą metodę zastępując dwie linie formatowanie:

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

Oto wynik:

 
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 

Dno this article wyjaśnił mi ten problem.

2) Jakie jest najlepsze rozwiązanie do utworzenia krótkiego łańcucha czasu formatowania (HH: mm lub gg: mm tt) w zależności od ustawień systemu operacyjnego?

Nie wiem o najlepszym rozwiązaniu, ale stworzyłem następującą funkcję, która konwertuje LongTimeFormat na ShortTimeFormat, umożliwiając aplikacji śledzenie opcji użytkowników, jeśli zmieniają "Long Time" (choć wygrał) t śledzić ustawienie "Krótki czas").

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); 
} 

Wyjście po przeprowadzeniu powyższych zmian:

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

P/Wywołanie rozwiązaniem jest użycie GetTimeFormat przepuszczanie TIME_NOSECONDS pomocą DateTime.ToString (Format), jak powyżej. Nie testowałem tego, ponieważ wolałbym uniknąć używania P/Invoke.

5

Odpowiedź na drugie pytanie jest

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

lub

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

To rzeczywiście zawsze lepiej używać jednoznacznych metod, które akceptują CultureInfo. Nie ma spójności, w jaki sposób .Net wybiera, co używać domyślnie CurrentCulture lub CurrentUICulture lub InvarinatCulture.

Aby odpowiedź była pełna. Omówię także różnice między kulturami.

Więc CurrentCulture to "Panel sterowania -> Zegar, język i region -> Region i język -> zakładka Formaty." To jest kultura, której oczekujesz od swoich obliczeń.Na przykład możesz prowadzić księgowość w USA, więc musisz to skonfigurować w USA.

CurrentUICulture to "Region i język -> Język wyświetlania" oznacza, że ​​kiedy jesteś emigrantem z Ukrainy, chcesz, aby aplikacja była zlokalizowana w UA (ale wszystkie obliczenia są nadal w USA).

I InvariantCulture to tak zwana lokalna kultura agnostyczna. Powinieneś użyć tego do przechowywania informacji i tak dalej. Skutecznie to En-US.

Uwaga: Mogę się mylić, gdy każde ustawienie znajduje się w oknach. Ale prawdopodobnie masz pomysł.

+0

Dzięki, przeprowadzę z tym testowanie i wdrożę. Na co jeszcze wpływa kultura inna niż Data, Czas, Waluta, Dziesiętny i Tysiąc separatorów? –

+1

Miesiąc, nazwy w dni powszednie. Kierunki LTR/RTL. Sortowanie ciągów. Operacje typu upper/lower z ciągami. Serializacja. –

+0

CultureInfo.CurrentUICulture wydaje się być en-US, gdzie jeszcze można to skonfigurować? Próbowałem rebotowania po sprawdzeniu, że wszystko było ustawione na Wielką Brytanię. Zauważyłem też, że czasami po uruchomieniu programu nie pobieram natychmiast zmiany kultury. Jednak uruchomienie go po raz drugi zawsze podnosi. –

2

Jestem całkiem pewien, że krótki łańcuch formatu czasu nie jest używany w DateTime.ToShortTimeString() lub DateTime.ToString ("t") jest błędem, ponieważ został naprawiony w .NET framework 4.0.

+0

powinno to być zaakceptowaną odpowiedzią, ponieważ wyjaśnia, dlaczego ShortTimePattern nie używa bieżących ustawień regionu. Szybka weryfikacja za pomocą testu jednostkowego w projekcie 3.5 i projekcie w wersji 4.0, a zobaczysz, że 3.5 ignoruje wszystko, co jest ustawione w oknie dialogowym regionu i języka – nrjohnstone

Powiązane problemy