2012-06-21 9 views
5

tengo una fecha serializado como una cadena "2012-06-20T13: 19: 59.1091122Z"DateTimeConverter la conversión de cadena UTC

Utilizando el DateTimeConverter, esto se convierte en un objeto DateTime {22: 49: 59.1091122} con la propiedad Kind establecida en "Local".

por ejemplo. La siguiente prueba falla:

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

Estoy un poco sorprendido por esto ... lo que habría esperado que el objeto DateTime devuelto por el convertidor sería en UTC.

Los documentos dicen que DateTimeConverter usa DateTime.Parse, pero supongo que no debe usar la opción DateTimeStyles.RoundtripKind.

¿Hay alguna forma de evitar esto?

Respuesta

6

El error real aquí es que DateTime.Parse() sin ningún DateTimeStyles pasado todavía debería ver la "Z" y reconocer que debe analizarse como UTC. Pero buena suerte para que MS lo reconozca o lo solucione.

El problema particular ilustrado por el ejemplo del código es que DateTimeConverter tiene que sobrescribir los métodos de TypeConverter y, por lo tanto, no tiene la capacidad de pasar parámetros adicionales como DateTimeStyles. Es una lástima que no implemente algún tipo de propiedad estática o threadstatic para esto. De hecho, aprovecha el Culture.CurrentCulture del hilo, pero los DateTimeStyles son algo separado de la cultura, por lo que es otro callejón sin salida.

Supongo que está bloqueado en el uso de un convertidor, en lugar de simplemente llamar parse directamente? ¿Es este un requisito difícil? Si no, usted podría hacer lo siguiente:

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

Otro enfoque sería utilizar un DateTimeOffsetConverter lugar - se entiende la Z zona horaria correctamente. A continuación, puede usar la propiedad .UtcDateTime del resultado para volver a DateTime con un tipo UTC.

Cuestiones relacionadas