2009-03-21 16 views
33

He serializado un objeto utilizando serializador JSON de Newtonsoft y el DateTime ha llegado a través como:análisis de JSON DateTime a partir de Newtonsoft JSON Serializador

/Date(1237588418563+0000)/ 

Cuando $ .evalJSON() en eso, es un objeto pero no puedo encontrar ningún método de fecha normal como toUTCString en él.

¿Alguna idea de qué puedo hacer con esto?

+0

hace este trabajo para usted ?: http://www.tek-tips.com/viewthread.cfm?qid=1526126&page=8 – bernie

Respuesta

77

Utilice uno de los JsonConverters que vienen con Json.NET para trabajar con las fechas y obtener un mejor formato. JavaScriptDateTimeConverter le dará automáticamente una fecha de JavaScript.

public class LogEntry  
{  
    public string Details { get; set; }  
    public DateTime LogDate { get; set; } 
} 

[Test] 
public void WriteJsonDates() 
{  
    LogEntry entry = new LogEntry  
    {  
    LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),  
    Details = "Application started."  
    };  


    string defaultJson = JsonConvert.SerializeObject(entry);  
    // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}  

    string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());  
    // {"Details":"Application started.","LogDate":new Date(1234656000000)} 

    string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());  
    // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}  
} 

Documentación: Serializing Dates in JSON with Json.NET

+4

Como referencia, el espacio de nombres en IsoDateTimeConverter es Newtonsoft. Json.Converters y en JsonConvert.SerializeObject es Newtonsoft.Json –

2

se encontró con el mismo problema, y ​​halló una solución basada en el enlace de Adán:

new Date(yourDate.substr(yourDate.indexOf("(") + 1, 13) - 0)); 

Se ve como una marca de tiempo Unix, que Javascript es fácilmente capaz para convertir en un objeto de fecha. El - 0 es simplemente para hacer javascript tratar la salida substr como un entero ... Creo que se puede Number() es así, si no te gusta el aspecto de - 0

1

el objeto JSON que contiene algo como esto:

var data = {"CreatedDate":"/Date(1327572000000-1000)/"}); 

/// 
var oddDateTimeZone = data.CreatedDate; 
var utcDateTime = oddDateTimeZone.substr(oddDateTimeZone.indexOf("(")+1, 13); 
var utcZone = oddDateTimeZone.substr(oddDateTimeZone.indexOf("-")+1, 4); 
var utcDateTimeZone = new Date(Number(utcDateTime)-(Number(utcZone))); 

pero, aún así sería mejor arreglar el objeto JSON para que la función de fecha se active sin usar algo como eval() o ventana []. Tal vez en jQuery. No es seguro.

¡No olvide que el desplazamiento podría ser + y no solo - para el desplazamiento!

+0

también utiliza una expresión regular y luego evalúa el texto de esta manera: 'eval (" new "+ data.CreateDate.replace (/ \ // ig," ")) ' parece funcionar bien –

15

A partir de la versión 4.5r5 de Newtonsoft Json.Net, utiliza la clase JsonPropertyAttribute Class y establece su propiedad Property de ItemConverterType. Uso:

// class to be serialized 
public class MyClass 
{ 
    [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] 
    public DateTime? DateTime1; 
    public DateTime? DateTime2; 
} 

Como he observado que esto se transformará la DateTimeConverter para todas las propiedades de esta clase no sólo el anterior que se declara.

+0

Esta respuesta es la más reciente –

+1

No creo que entiendo lo que se supone que debe hacer, o cómo se supone que funciona. En mi clase, tengo esto: [JsonProperty (ItemConverterType = typeof (IsoDateTimeConverter))] public System.DateTime RecordInsertedDate {get; conjunto; } Pero mis fechas siguen apareciendo como predeterminado/Fecha (132456560000000)/formato –

+0

NVM, estaba usando ServiceStack que estaba anulando esto. Debe usar ServiceStack's JsConfig.DateHandler = DateHandler.ISO8601; configuración de configuración en su código para obtener ISO8601 –

14

Se me ocurrió un enfoque diferente que podría ser útil para algunos. Básicamente creo mi propio CustomDateConverter al que llamo cuando lo necesito. El convertidor toma 2 parámetros, un formato de fecha, p. yyyy-MM-dd HH:mm:ss y una TimeZoneInfo, lo que me permite convertir la fecha de UTC a la zona horaria del usuario:

public class JSONCustomDateConverter : DateTimeConverterBase 
{ 
    private TimeZoneInfo _timeZoneInfo; 
    private string _dateFormat; 

    public JSONCustomDateConverter(string dateFormat, TimeZoneInfo timeZoneInfo) 
    { 
     _dateFormat = dateFormat; 
     _timeZoneInfo = timeZoneInfo; 
    } 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(DateTime); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     writer.WriteValue(TimeZoneInfo.ConvertTimeFromUtc(Convert.ToDateTime(value), _timeZoneInfo).ToString(_dateFormat)); 
     writer.Flush(); 
    } 

Usted puede utilizar de esta manera:

var jsonString = JsonConvert.SerializeObject(myObject, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = new List<JsonConverter>() { new JSONCustomDateConverter("yyyy-MM-dd HH:mm:ss", loggedUser.Timezone) } }); 

Obviamente usted podría quitar todo lo relacionado con la zona horaria si solo quieres formatear la fecha personalizada. ¡Déjame saber que ayudó!

+2

Finalmente encontré una muestra de anulación normal :) muchas gracias – povilasp

+0

Si alguien está buscando extenderlo mediante el registro global en Asp.Net MVC'services.AddMvc() .AddJsonOptions (jsonOption => { jsonOption.SerializerSettings.Converters.Add ( nueva JSONCustomDateConverter ("dd/mm/yyy", TimeZoneInfo.FindSystemTimeZoneById ("Hora estándar de India"))); }); ' –

0

Lo siento simplificar un poco @ James Newton-Rey

string date = Newtonsoft.Json.JsonConvert.SerializeObject(DateTime.Now);  
0

ObjectMapper asignador = new ObjectMapper();

mapper.registerModule (nuevo JavaTimeModule());

mapper.configure (SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

Esto funciona para mí