Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article explique comment les données mises en forme, telles que les données numériques et les données de date et d’heure, sont gérées pour l’affichage et le stockage.
Lorsque vous développez avec .NET, utilisez une mise en forme sensible à la culture pour afficher des données non-chaînes, telles que des nombres et des dates, dans une interface utilisateur. Utilisez le formatage avec la culture invariante pour conserver des données non textuelles sous forme textuelle. N’utilisez pas de mise en forme sensible à la culture pour conserver les données numériques ou de date et heure sous forme de chaîne.
Afficher les données mises en forme
Lorsque vous affichez des données non chaînes telles que des nombres et des dates et des heures pour les utilisateurs, mettez-les en forme à l’aide des paramètres culturels de l’utilisateur. Par défaut, tous les éléments suivants utilisent la culture actuelle dans les opérations de mise en forme :
- Chaînes interpolées prises en charge par les compilateurs C# et Visual Basic .
- Opérations de concaténation de chaîne qui utilisent les opérateurs de concaténation C# ou Visual Basic ou qui appellent directement la String.Concat méthode.
- Méthode String.Format.
- Les méthodes
ToStringdes types numériques et des types de dates et d'heures.
Pour spécifier explicitement qu’une chaîne doit être mise en forme à l’aide des conventions d’une culture désignée ou de la culture invariante, vous pouvez effectuer les opérations suivantes :
Lorsque vous utilisez les méthodes String.Format et
ToString, appelez une surcharge qui a un paramètreprovider, telles que String.Format(IFormatProvider, String, Object[]) ou DateTime.ToString(IFormatProvider), et transmettez-lui la propriété CultureInfo.CurrentCulture, une instance CultureInfo qui représente la culture souhaitée, ou la propriété CultureInfo.InvariantCulture.Pour la concaténation de chaînes, n’autorisez pas le compilateur à effectuer des conversions implicites. Au lieu de cela, effectuez une conversion explicite en appelant une surcharge
ToStringayant un paramètreprovider. Par exemple, le compilateur utilise implicitement la culture actuelle lors de la conversion d’une Double valeur en chaîne dans le code suivant :string concat1 = "The amount is " + 126.03 + "."; Console.WriteLine(concat1);Dim concat1 As String = "The amount is " & 126.03 & "." Console.WriteLine(concat1)Au lieu de cela, vous pouvez spécifier explicitement la culture dont les conventions de mise en forme sont utilisées dans la conversion en appelant la Double.ToString(IFormatProvider) méthode, comme le fait le code suivant :
string concat2 = "The amount is " + 126.03.ToString(CultureInfo.InvariantCulture) + "."; Console.WriteLine(concat2);Dim concat2 As String = "The amount is " & 126.03.ToString(CultureInfo.InvariantCulture) & "." Console.WriteLine(concat2)Pour l’interpolation de chaîne, plutôt que d’affecter une chaîne interpolée à une String instance, affectez-la à un FormattableString. Vous pouvez ensuite appeler sa FormattableString.ToString() méthode pour produire une chaîne de résultat qui reflète les conventions de la culture actuelle, ou vous pouvez appeler la FormattableString.ToString(IFormatProvider) méthode pour produire une chaîne de résultat qui reflète les conventions d’une culture spécifiée.
Vous pouvez également transmettre la chaîne mise en forme à la méthode statique FormattableString.Invariant pour produire une chaîne de résultat qui reflète les conventions de la culture invariante. L’exemple suivant illustre cette approche. (La sortie de l’exemple correspond à la culture actuelle de
en-US.)using System; using System.Globalization; class Program { static void Main() { Decimal value = 126.03m; FormattableString amount = $"The amount is {value:C}"; Console.WriteLine(amount.ToString()); Console.WriteLine(amount.ToString(new CultureInfo("fr-FR"))); Console.WriteLine(FormattableString.Invariant(amount)); } } // The example displays the following output: // The amount is $126.03 // The amount is 126,03 € // The amount is ¤126.03Imports System.Globalization Module Program Sub Main() Dim value As Decimal = 126.03 Dim amount As FormattableString = $"The amount is {value:C}" Console.WriteLine(amount.ToString()) Console.WriteLine(amount.ToString(new CultureInfo("fr-FR"))) Console.WriteLine(FormattableString.Invariant(amount)) End Sub End Module ' The example displays the following output: ' The amount is $126.03 ' The amount is 126,03 € ' The amount is ¤126.03Remarque
Si vous utilisez C# et la mise en forme à l’aide de la culture invariante, il est plus performant d’appeler String.Create(IFormatProvider, DefaultInterpolatedStringHandler) et de passer CultureInfo.InvariantCulture pour le premier paramètre. Pour plus d’informations, consultez Interpolation de chaîne en C# 10 et .NET 6.
Conserver les données mises en forme
Vous pouvez conserver des données non chaînes en tant que données binaires ou en tant que données mises en forme. Si vous choisissez de l’enregistrer en tant que données mises en forme, vous devez appeler une surcharge de méthode de mise en forme qui inclut un provider paramètre et lui passer la propriété CultureInfo.InvariantCulture. La culture invariante fournit un format cohérent pour les données mises en forme indépendantes de la culture et de l’ordinateur. En revanche, la persistance des données mises en forme à l’aide de cultures autres que la culture invariante présente un certain nombre de limitations :
- Les données sont susceptibles d’être inutilisables si elles sont récupérées sur un système qui a une culture différente, ou si l’utilisateur du système actuel modifie la culture actuelle et tente de récupérer les données.
- Les propriétés d’une culture sur un ordinateur spécifique peuvent différer des valeurs standard. À tout moment, un utilisateur peut personnaliser les paramètres d’affichage sensibles à la culture. En raison de cela, les données mises en forme enregistrées sur un système peuvent ne pas être lisibles une fois que l’utilisateur personnalise les paramètres culturels. La portabilité des données mises en forme sur plusieurs ordinateurs est susceptible d’être encore plus limitée.
- Normes internationales, régionales ou nationales qui régissent la mise en forme des nombres ou des dates et des heures changent au fil du temps, et ces modifications sont incorporées dans les mises à jour du système d’exploitation Windows. Lorsque les conventions de mise en forme changent, les données mises en forme à l’aide des conventions précédentes peuvent devenir non lisibles.
L’exemple suivant illustre la portabilité limitée résultant de l’utilisation d’une mise en forme sensible à la culture pour conserver les données. L’exemple enregistre un tableau de valeurs de date et d’heure dans un fichier. Elles sont mises en forme à l’aide des conventions de la culture anglaise (États-Unis). Après que l’application change la culture actuelle en Français (Suisse), elle tente de lire les valeurs enregistrées à l’aide des conventions de mise en forme de la culture actuelle. La tentative de lecture de deux éléments de données déclenche une exception FormatException, et le tableau de dates contient maintenant deux éléments incorrects qui sont égaux à MinValue.
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
public class Example
{
private static string filename = @".\dates.dat";
public static void Main()
{
DateTime[] dates = { new DateTime(1758, 5, 6, 21, 26, 0),
new DateTime(1818, 5, 5, 7, 19, 0),
new DateTime(1870, 4, 22, 23, 54, 0),
new DateTime(1890, 9, 8, 6, 47, 0),
new DateTime(1905, 2, 18, 15, 12, 0) };
// Write the data to a file using the current culture.
WriteData(dates);
// Change the current culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-CH");
// Read the data using the current culture.
DateTime[] newDates = ReadData();
foreach (var newDate in newDates)
Console.WriteLine(newDate.ToString("g"));
}
private static void WriteData(DateTime[] dates)
{
StreamWriter sw = new StreamWriter(filename, false, Encoding.UTF8);
for (int ctr = 0; ctr < dates.Length; ctr++) {
sw.Write("{0}", dates[ctr].ToString("g", CultureInfo.CurrentCulture));
if (ctr < dates.Length - 1) sw.Write("|");
}
sw.Close();
}
private static DateTime[] ReadData()
{
bool exceptionOccurred = false;
// Read file contents as a single string, then split it.
StreamReader sr = new StreamReader(filename, Encoding.UTF8);
string output = sr.ReadToEnd();
sr.Close();
string[] values = output.Split( new char[] { '|' } );
DateTime[] newDates = new DateTime[values.Length];
for (int ctr = 0; ctr < values.Length; ctr++) {
try {
newDates[ctr] = DateTime.Parse(values[ctr], CultureInfo.CurrentCulture);
}
catch (FormatException) {
Console.WriteLine($"Failed to parse {values[ctr]}");
exceptionOccurred = true;
}
}
if (exceptionOccurred) Console.WriteLine();
return newDates;
}
}
// The example displays the following output:
// Failed to parse 4/22/1870 11:54 PM
// Failed to parse 2/18/1905 3:12 PM
//
// 05.06.1758 21:26
// 05.05.1818 07:19
// 01.01.0001 00:00
// 09.08.1890 06:47
// 01.01.0001 00:00
// 01.01.0001 00:00
Imports System.Globalization
Imports System.IO
Imports System.Text
Imports System.Threading
Module Example
Private filename As String = ".\dates.dat"
Public Sub Main()
Dim dates() As Date = {#5/6/1758 9:26PM#, #5/5/1818 7:19AM#, _
#4/22/1870 11:54PM#, #9/8/1890 6:47AM#, _
#2/18/1905 3:12PM#}
' Write the data to a file using the current culture.
WriteData(dates)
' Change the current culture.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-CH")
' Read the data using the current culture.
Dim newDates() As Date = ReadData()
For Each newDate In newDates
Console.WriteLine(newDate.ToString("g"))
Next
End Sub
Private Sub WriteData(dates() As Date)
Dim sw As New StreamWriter(filename, False, Encoding.Utf8)
For ctr As Integer = 0 To dates.Length - 1
sw.Write("{0}", dates(ctr).ToString("g", CultureInfo.CurrentCulture))
If ctr < dates.Length - 1 Then sw.Write("|")
Next
sw.Close()
End Sub
Private Function ReadData() As Date()
Dim exceptionOccurred As Boolean = False
' Read file contents as a single string, then split it.
Dim sr As New StreamReader(filename, Encoding.Utf8)
Dim output As String = sr.ReadToEnd()
sr.Close()
Dim values() As String = output.Split({"|"c})
Dim newDates(values.Length - 1) As Date
For ctr As Integer = 0 To values.Length - 1
Try
newDates(ctr) = DateTime.Parse(values(ctr), CultureInfo.CurrentCulture)
Catch e As FormatException
Console.WriteLine("Failed to parse {0}", values(ctr))
exceptionOccurred = True
End Try
Next
If exceptionOccurred Then Console.WriteLine()
Return newDates
End Function
End Module
' The example displays the following output:
' Failed to parse 4/22/1870 11:54 PM
' Failed to parse 2/18/1905 3:12 PM
'
' 05.06.1758 21:26
' 05.05.1818 07:19
' 01.01.0001 00:00
' 09.08.1890 06:47
' 01.01.0001 00:00
' 01.01.0001 00:00
'
Toutefois, si vous remplacez les CultureInfo.CurrentCulture propriétés par CultureInfo.InvariantCulture dans les appels vers DateTime.ToString(String, IFormatProvider) et DateTime.Parse(String, IFormatProvider), les données de date et d’heure enregistrées sont restaurées, comme le montre la sortie suivante :
06.05.1758 21:26
05.05.1818 07:19
22.04.1870 23:54
08.09.1890 06:47
18.02.1905 15:12