Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird untersucht, wie formatierte Daten, z. B. numerische Daten und Datums- und Uhrzeitdaten, zur Anzeige und zum Speichern behandelt werden.
Wenn Sie mit .NET entwickeln, verwenden Sie kulturabhängige Formatierungen, um Nicht-Zeichenfolgendaten wie Zahlen und Datumsangaben in einer Benutzeroberfläche anzuzeigen. Verwenden Sie die Formatierung mit der invarianten Kultur , um Nicht-Zeichenfolgendaten in Zeichenfolgenform beizubehalten. Verwenden Sie keine kultursensitive Formatierung, um numerische oder Datums- und Uhrzeitdaten in Zeichenfolgenform beizubehalten.
Formatierte Daten anzeigen
Wenn Sie Nicht-Zeichenfolgendaten wie Zahlen und Datumsangaben und Uhrzeiten für Benutzer anzeigen, formatieren Sie diese mithilfe der Kultureinstellungen des Benutzers. Standardmäßig verwenden alle folgenden die aktuelle Kultur in Formatierungsvorgängen.
- Interpolierte Zeichenfolgen, die von den C# - und Visual Basic-Compilern unterstützt werden.
- Zeichenfolgenverkettungsvorgänge, die die C# - oder Visual Basic-Verkettungsoperatoren verwenden oder die die String.Concat Methode direkt aufrufen.
- Die String.Format-Methode.
- Die
ToString
Methoden der numerischen Typen und der Datums- und Uhrzeittypen.
Wenn Sie explizit angeben möchten, dass eine Zeichenfolge mithilfe der Konventionen einer bestimmten Kultur oder der invarianten Kultur formatiert werden soll, können Sie wie folgt vorgehen:
Rufen Sie bei Verwendung der String.Format- und
ToString
-Methoden eine Überladung auf, die einenprovider
-Parameter aufweist, wie etwa String.Format(IFormatProvider, String, Object[]) oder DateTime.ToString(IFormatProvider), und übergeben Sie die CultureInfo.CurrentCulture-Eigenschaft, eine CultureInfo-Instanz, die die gewünschte Kultur darstellt, oder die CultureInfo.InvariantCulture-Eigenschaft.Bei Zeichenfolgenverkettung dürfen Sie dem Compiler keine impliziten Konvertierungen erlauben. Führen Sie stattdessen eine explizite Konvertierung durch Aufrufen einer
ToString
Überladung mit einemprovider
Parameter aus. Beispielsweise verwendet der Compiler implizit die aktuelle Kultur, wenn ein Double Wert in eine Zeichenfolge im folgenden Code konvertiert wird:string concat1 = "The amount is " + 126.03 + "."; Console.WriteLine(concat1);
Dim concat1 As String = "The amount is " & 126.03 & "." Console.WriteLine(concat1)
Stattdessen können Sie explizit die Kultur angeben, deren Formatierungskonventionen in der Konvertierung verwendet werden, indem Sie die Double.ToString(IFormatProvider) Methode aufrufen, wie der folgende Code ausführt:
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)
Weisen Sie bei der Zeichenfolgeninterpolation die interpolierte Zeichenfolge einer String-Instanz zu und nicht einer FormattableString. Anschließend können Sie die FormattableString.ToString() Methode aufrufen, um eine Ergebniszeichenfolge zu erzeugen, die die Konventionen der aktuellen Kultur widerspiegelt, oder Sie können die FormattableString.ToString(IFormatProvider) Methode aufrufen, um eine Ergebniszeichenfolge zu erzeugen, die die Konventionen einer bestimmten Kultur widerspiegelt.
Sie können auch die formatierbare Zeichenfolge an die statische FormattableString.Invariant Methode übergeben, um eine Ergebniszeichenfolge zu erzeugen, die die Konventionen der invarianten Kultur widerspiegelt. Dieser Ansatz wird anhand des folgenden Beispiels veranschaulicht. (Bei der Ausgabe des Beispiels wird als aktuelle Kultur
en-US
verwendet.)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.03
Imports 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.03
Hinweis
Wenn Sie C# und Formatierung mit der invarianten Kultur verwenden, ist es leistungsfähiger, den ersten Parameter aufzurufen String.Create(IFormatProvider, DefaultInterpolatedStringHandler) und zu übergeben CultureInfo.InvariantCulture . Weitere Informationen finden Sie unter Zeichenfolgeninterpolation in C# 10 und .NET 6.
Formatierte Daten beibehalten
Sie können Nicht-Zeichenfolgendaten entweder als Binärdaten oder als formatierte Daten speichern. Wenn Sie sich dafür entscheiden, sie als formatierte Daten zu speichern, sollten Sie eine Formatierungsmethoden-Überladung aufrufen, die einen provider
Parameter enthält, und die CultureInfo.InvariantCulture Eigenschaft übergeben. Die invariante Kultur bietet ein konsistentes Format für formatierte Daten, die unabhängig von Kultur und Maschine sind. Im Gegensatz dazu bringt das Beibehalten von Daten, die mit anderen Kulturen als der invarianten Kultur formatiert werden, einige Einschränkungen mit sich:
- Die Daten können wahrscheinlich nicht verwendet werden, wenn sie auf einem System mit einer anderen Kultur abgerufen werden, oder wenn der Benutzer des aktuellen Systems die aktuelle Kultur ändert und versucht, die Daten abzurufen.
- Die Eigenschaften einer Kultur auf einem bestimmten Computer können sich von Den Standardwerten unterscheiden. Jederzeit kann ein Benutzer kulturabhängige Anzeigeeinstellungen anpassen. Aus diesem Grund sind formatierte Daten, die auf einem System gespeichert sind, möglicherweise nicht lesbar, nachdem der Benutzer kulturelle Einstellungen angepasst hat. Die Portabilität formatierter Daten über Computer hinweg ist wahrscheinlich noch eingeschränkter.
- Internationale, regionale oder nationale Standards regeln die Formatierung von Zahlen oder Daten und Zeiten, und deren Änderungen werden im Laufe der Zeit in Windows-Betriebssystemupdates integriert. Wenn sich Formatierungskonventionen ändern, können Daten, die mit den vorherigen Konventionen formatiert wurden, unlesbar werden.
Das folgende Beispiel veranschaulicht die eingeschränkte Portabilität, die sich aus der Verwendung von kultursensibler Formatierung zum Speichern von Daten ergibt. Im Beispiel wird ein Array von Datums- und Uhrzeitwerten in einer Datei gespeichert. Diese werden anhand der Konventionen der Kultur Englisch (USA) formatiert. Nachdem die Anwendung die aktuelle Kultur in Französisch (Schweiz) geändert hat, versucht sie, die gespeicherten Werte mithilfe der Formatierungskonventionen der aktuellen Kultur zu lesen. Der Versuch, zwei der Datenelemente zu lesen, löst eine FormatException Ausnahme aus, und das Array von Datumsangaben enthält jetzt zwei falsche Elemente, die gleich MinValuesind.
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
'
Wenn Sie jedoch die CultureInfo.CurrentCulture-Eigenschaft durch CultureInfo.InvariantCulture in den Aufrufen von DateTime.ToString(String, IFormatProvider) und DateTime.Parse(String, IFormatProvider) ersetzen, werden die beibehaltenen Datums- und Uhrzeitdaten erfolgreich wiederhergestellt, wie die folgende Ausgabe zeigt:
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