Pourquoi ne pas DateTime.ToShortTimeString () respecter le format court temps dans « Paramètres régionaux et linguistiques »?
-
18-09-2019 - |
Question
J'ai couru dans une question qui est probablement dû à ma mauvaise compréhension de la façon dont fonctionne la méthode DateTime.ToShortTimeString (). Lors du formatage des chaînes de temps avec cette fonction, je suppose qu'il respecterait le paramètre « Short Time » dans les paramètres de format Windows 7
Control Panel -> Clock, Language and Region -> Region and Language -> Formats Tab.
Cependant .NET semble sélectionner un format de temps ne repose pas sur ce paramètre, mais en fonction de la culture actuelle:
Region and Language -> Location -> Current Location
Je l'ai fait des tests sur 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)
je el-GR comme ce fut la culture que l'utilisateur qui a signalé le problème avec, il a également testé ceci sur Vista SP2 et Windows 7 RC avec le même résultat.
La question est deux fois vraiment: 1) Quel est mon incompréhension de formats .NET et Windows? 2) Quelle est la meilleure solution pour créer une chaîne de temps de format court (HH: mm ou hh: mm tt) en fonction du système d'exploitation, idéalement cela devrait fonctionner en Mono, donc je préférerais éviter la lecture du registre ou P / Invoke .
Méthode utilisée pour produire ce qui précède, pour référence future et les tests.
[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();
}
Mise à jour: Sur la base des commentaires de Mike ci-dessous la méthode I adapté ci-dessus avec les modifications suivantes:
Les deux lignes suivantes
string sixAmString = sixAm.ToShortTimeString();
string sixPmString = sixPm.ToShortTimeString();
Changement à
string sixAmString = sixAm.ToString("t", culture);
string sixPmString = sixPm.ToString("t", culture);
J'ai aussi changé la variable de la culture à utiliser CultureInfo.CurrentUICulture.
Ce ne unfortunatly fonctionne pas aussi bien que je l'avais espéré, la sortie quelle que soit la configuration du temps dans l'onglet Formats de Windows 7 était:
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM
Il semble que le CultureInfo.CurrentUICulture est toujours en États-Unis.
La solution 3
En réponse à chacune de mes questions:
1) Quel est mon incompréhension de formats .NET et Windows?
La réponse courte est, il n'y a pas de lien entre le paramètre « bref délai » dans les paramètres « régionaux et linguistiques » et la propriété ShortTimePattern de .NET. Cependant, la propriété LongTimePattern est dictée par le réglage « Long Time ».
I adapté le procédé ci-dessus en remplacement des deux lignes de mise en forme à:
string sixAmString = sixAm.ToString("T", culture.DateTimeFormat);
string sixPmString = sixPm.ToString("T", culture.DateTimeFormat);
Voici la sortie:
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
Le fond de cet article m'a expliqué le problème.
2) Quelle est la meilleure solution pour créer une chaîne de temps de format court (HH: mm ou hh: mm tt) en fonction du réglage du système d'exploitation
Je ne sais pas la meilleure solution, mais j'ai créé la fonction suivante qui convertit le LongTimeFormat à un ShortTimeFormat permettant ainsi une application à suivre l'option des utilisateurs si elles changent le « Long Time » (mais il ne sera pas suivi le réglage "Short Time").
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);
}
La sortie après les modifications ci-dessus:
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 Culture: en-GB, 6AM: 06:00 AM, 6PM: 06:00 PM
L'option P / Invoke consiste à utiliser GetTimeFormat passer les TIME_NOSECONDS en utilisant DateTime.ToString (Format) comme ci-dessus. Je ne l'ai pas testé ce que je préférerais éviter d'utiliser P / Invoke.
Autres conseils
Réponse à la deuxième question est
DateTimeFormat.Format(DateTime.Now, "t", CultureInfo.CurrentUICulture);
ou
DateTime.Now.ToString("t", CultureInfo.CurrentUICulture);
Il est en fait toujours préférable d'utiliser des méthodes explicites qui acceptent CultureInfo. Il n'y a pas de cohérence comment .Net choisit ce à utiliser par défaut soit CurrentCulture ou CurrentUICulture ou InvarinatCulture.
Pour présenter une réponse complète. Aussi je vais décrire les différences entre les cultures.
CurrentCulture est "Panneau de configuration -> Horloge, Langue et Région -> Région et langue -> Formats Tab." Ceci est la culture que vous attendez de vos calculs à. Par exemple, vous pouvez faire votre comptabilité aux États-Unis, de sorte que vous avez ce à configurer aux États-Unis.
CurrentUICulture est « Région et langue -> Langue d'affichage », signifie que lorsque vous êtes émigrant de l'Ukraine, vous voulez que votre demande soit localisée en UA (mais tous les calculs est encore aux Etats-Unis)
.InvariantCulture est appelé ainsi locale agnostique de la culture. Vous devez utiliser pour stocker des informations et ainsi de suite. Efficacement En États-Unis.
Note: Je peux me tromper où chaque paramètre est situé dans les fenêtres. Mais vous avez probablement eu une idée.
Je suis tout à fait sûr le fait que la chaîne de format de temps n'est pas utilisé dans DateTime.ToShortTimeString () ou DateTime.ToString ( « t ») est un bug, car il a été corrigé dans .NET Framework 4.0.