2012-06-21 8 views
5

ich ein Datum serialisiert als String haben "2012-06-20T13: 19: 59.1091122Z"Datetimeconverter von UTC String Umwandlung

die DateTimeConverter benutzen, wird dies zu einem Datetime-Objekt umgewandelt {22: 49: 59,1091122} mit der Kind Eigenschaft auf "Local" festgelegt.

z. Der folgende Test fehlschlägt:

private static readonly DateTime UtcDate = new DateTime(634757951991091122, DateTimeKind.Utc); 
    private const string UtcSerialisedDate = "2012-06-20T13:19:59.1091122Z"; 

    [Test] 
    public void DateTimeConverter_Convert_From_Utc_String() 
    { 
     // Arrange 
     var converter = TypeDescriptor.GetConverter(typeof(DateTime)); 

     // Act 
     var result = converter.ConvertFrom(UtcSerialisedDate); 

     // Assert 
     Assert.AreEqual(UtcDate, result); 
     Assert.AreEqual(DateTimeKind.Utc, ((DateTime)result).Kind); 
    } 

ich ein bisschen davon überrascht bin ... ich erwartet hätte, dass das Objekt Datetime durch den Wandler zurück in UTC wäre.

Die Dokumente sagen, dass DateTimeConverter DateTime.Parse verwendet, aber ich vermute, es darf die Option DateTimeStyles.RoundtripKind nicht verwenden.

Gibt es einen Weg um dies zu umgehen?

Antwort

6

Der eigentliche Fehler hier ist, dass DateTime.Parse() ohne DateTimeStyles sollte immer noch die "Z" sehen und erkennen, dass es als UTC analysiert werden sollte. Aber viel Glück, dass MS das bestätigt oder repariert. Das besondere Problem, das in Ihrem Codebeispiel dargestellt wird, besteht darin, dass der DateTimeConverter Methoden von TypeConverter überschreiben muss und daher keine zusätzlichen Parameter wie DateTimeStyles übergeben kann.

Es ist schade, dass es keine statische oder threadstatische Eigenschaft dafür implementiert. Es nutzt tatsächlich die Culture.CurrentCulture des Threads, aber DateTimeStyles sind eine separate Sache von der Kultur, also leider - das ist eine andere Sackgasse.

Ich nehme an, Sie sind in die Verwendung eines Konverters gesperrt, anstatt nur parse direkt aufrufen? Ist das eine harte Anforderung? Wenn nicht, könnten Sie wie folgt vorgehen:

public static object ConvertFrom<T>(string value) 
{ 
    if (typeof(T) == typeof(DateTime)) 
    return DateTime.Parse(value, null, DateTimeStyles.RoundtripKind); 

    var converter = TypeDescriptor.GetConverter(typeof(T)); 
    return converter.ConvertFrom(value); 
} 

Ein anderer Ansatz wäre, eine DateTimeOffsetConverter stattdessen verwenden - es versteht richtig die Z Zeitzone. Sie könnten dann die Eigenschaft .UtcDateTime des Ergebnisses verwenden, um zu einer DateTime mit einer UTC-Art zurückzukehren.