2012-06-21 15 views
5

ho un appuntamento serializzato come stringa "2012-06-20T13: 19: 59.1091122Z"DateTimeConverter la conversione da stringa UTC

Utilizzando la DateTimeConverter, questo viene convertito in un oggetto DateTime {22: 49: 59,1,091122 millions} con la proprietà Kind impostata su "Locale".

es. Il seguente test ha esito negativo:

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); 
    } 

Sono un po 'sorpreso da questo ... mi sarei aspettato che l'oggetto DateTime restituito dal convertitore sarebbe in UTC.

I documenti dicono che DateTimeConverter utilizza DateTime.Parse, ma suppongo che non debba utilizzare l'opzione DateTimeStyles.RoundtripKind.

C'è qualche modo per aggirare questo?

risposta

6

Il vero bug qui è che DateTime.Parse() senza alcun DateTimeStyles passato dovrebbe ancora vedere la "Z" e riconoscere che dovrebbe essere analizzato come UTC. Ma buona fortuna per far riconoscere o correggere la SM.

Il particolare problema illustrato dall'esempio di codice è che DateTimeConverter deve sovrascrivere i metodi da TypeConverter e quindi non ha la capacità di passare parametri aggiuntivi come DateTimeStyles. Peccato che non implementi una qualche proprietà statica o filstatica per questo. Sfrutta infatti Culture.CurrentCulture del thread, ma DateTimeStyles è una cosa separata dalla cultura, quindi ahimè: questo è un altro punto morto.

Presumo che sono vincolati a utilizzando un convertitore, piuttosto che semplicemente chiamando direttamente parse? È un requisito difficile? In caso contrario, si potrebbe fare la seguente:

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); 
} 

Un altro approccio sarebbe quello di utilizzare un DateTimeOffsetConverter invece - si capisce il fuso orario Z correttamente. È quindi possibile utilizzare la proprietà .UtcDateTime del risultato per tornare a un DateTime con un tipo UTC.