2017-11-06 5 views
2

Ist es möglich, dass .NET die folgende Ausgabe erstellt?Wie erstellt man .NET CultureInfo mit Dateformat ISO 8601?

DateTime.UtcNow.ToString() --> "2017-11-07T00:40:00.123456Z" 

Natürlich gibt es immer die Möglichkeit, ToString ("s") oder ToString ("yyyy-MM-TTThh: mm: ss.fffffffK") zu verwenden. Aber gibt es eine Möglichkeit, das Standardverhalten für die parameterlose ToString-Methode an die gewünschte Ausgabe anzupassen?

Ich habe versucht, die CurrentCulture zu ändern. Aber das Beste, was ich bekam, war "2017-11-07 00: 40: 00.123456Z". Ich habe keine Möglichkeit gefunden, das Trennzeichen zwischen dem Datum und der Zeit von einem Leerzeichen zu "T" zu ändern.

Antwort

4

Es ist möglich, aber nur durch den Zugriff auf ein internes Feld über Reflexion, die nicht garantiert in allen Fällen funktioniert.

var culture = (CultureInfo) CultureInfo.InvariantCulture.Clone(); 
var field = typeof(DateTimeFormatInfo).GetField("generalLongTimePattern", 
              BindingFlags.NonPublic | BindingFlags.Instance); 
if (field != null) 
{ 
    // we found the internal field, set it 
    field.SetValue(culture.DateTimeFormat, "yyyy-MM-dd'T'HH:mm:ss.FFFFFFFK"); 
} 
else 
{ 
    // fallback to setting the separate date and time patterns 
    culture.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd"; 
    culture.DateTimeFormat.LongTimePattern = "HH:mm:ss.FFFFFFFK"; 
} 
CultureInfo.CurrentCulture = culture; 

Console.WriteLine(DateTime.UtcNow); // "2017-11-07T00:53:36.6922843Z" 

Beachten Sie, dass die ISO-8601-Spezifikation ist einen Raum ermöglichen, anstelle eines T verwendet werden. Es ist nur vorzuziehen die T zu verwenden.

+0

Vielen Dank! Ich werde das sowieso nicht machen, da ich mich nicht wohl dabei fühle. Nur wenn jemand interessiert ist: Das obige Feld ist ein interner "Cache" für das Datetime-Format, das niemals verändert wird. https://referencesource.microsoft.com/#mscorlib/system/globalization/datetimeformatinfo.cs,a1da93c5a4a8c4e3 – Andreas

+0

Ja, ich würde empfehlen, dies nie wirklich zu tun. Verwenden Sie einfach 'ToString' mit einer korrekten Formatspezifikation. Es so zu verstecken ist wahrscheinlich nicht die beste Idee. Vielleicht gut für eine hacky Workaround, aber versuchen Sie es zu vermeiden. :) –

0

Scott Hanselmann hat darüber gebloggt here.

ein wenig Reflectoring zeigt uns, dass die Standardformatzeichenfolge für System.DateTime "G" wie in System.DateTime.ToString ("G") ist, wobei G eine der Voreinstellungen ist.

[...]

und erhält den Ausgang er erwartet, was darauf hinweist, dass "G" die Kombination ist eines shortdate und ein Longtime.

So sollten Sie außer Kraft setzen ShortDatePattern und LongTimePattern:

ich den Code in C# konvertiert und ja, es funktioniert:

var customCulture = new CultureInfo("en-US") 
{ 
    DateTimeFormat = 
    { 
     ShortDatePattern = "yyyy-MM-dd", 
     LongTimePattern = "HH:mm:ss.FFFFFFFK" 
    } 
}; 

Console.WriteLine(DateTime.Now); 

System.Threading.Thread.CurrentThread.CurrentCulture = customCulture; 
System.Threading.Thread.CurrentThread.CurrentUICulture = customCulture; 
Console.WriteLine(DateTime.Now); 

Console.ReadLine(); 

Allerdings hat Scott betitelte seinen Posten Böse Enabling für Grund. Denke zweimal darüber nach, bevor du das tust! Die T wird nicht benötigt, kann aber auch nicht bereitgestellt werden. Wenn Sie es noch benötigen, müssen Sie Reflection als Matt answered verwenden.