2014-05-06 15 views
7

Ho un oggetto DateTimeOffset di "05/06/2014 05:54:00 PM -04: 00".È possibile serializzare DateTimeOffset sulla stringa di tempo zulu con Json.NET?

Durante la serializzazione utilizzando l'impostazione Json.NET e ISO, viene visualizzato "2014-05-06T17: 54: 00-04: 00".

Quello che mi piacerebbe avere è la versione UTC/Zulu di quella stringa "2014-05-06T21: 54: 00Z".

Tuttavia, non sono riuscito a trovare alcuna impostazione del serializzatore per ottenere ciò. So per la serializzazione DateTime, posso impostare DateTimeZoneHandling = DateTimeZoneHandling.Utc per avere il formato Zulu. Tuttavia, non esiste un'opzione di impostazione per DateTimeOffset. Mi sto perdendo qualcosa? O devo creare un override personalizzato per questo?

risposta

15

Provare a utilizzare il IsoDateTimeConverter che viene fornito con Json.Net :

var date = new DateTime(2014, 5, 6, 17, 24, 55, DateTimeKind.Local); 
var obj = new { date = new DateTimeOffset(date) }; 

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.Converters.Add(new IsoDateTimeConverter 
{ 
    DateTimeFormat = "yyyy-MM-ddTHH:mm:ssZ", 
    DateTimeStyles = DateTimeStyles.AdjustToUniversal 
}); 

string json = JsonConvert.SerializeObject(obj, settings); 
Console.WriteLine(json); 

Uscita:

{"date":"2014-05-06T22:24:55Z"} 
+0

Ho il sospetto che ci debba essere un modo integrato per farlo, ma non l'ho trovato ... +1 –

+0

@ThomasLevesque Non sono sicuro del motivo per cui Json.Net non applica questo convertitore automaticamente per 'DateTimeOffset' come sembra per 'DateTime', ma applicarlo manualmente sembra funzionare. In caso contrario, quindi sì, vorrei scrivere un convertitore personalizzato per fare il lavoro come hai mostrato nella tua risposta. –

+0

hai solo bisogno di DateTimeStyles = DateTimeStyles.AdjustToUniversal, ha funzionato per me in questo modo, senza DateTimeFormat –

7

È possibile scrivere un convertitore personalizzato come questo:

class UtcDateTimeOffsetConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     if (value is DateTimeOffset) 
     { 
      var date = (DateTimeOffset)value; 
      value = date.UtcDateTime; 
     } 
     base.WriteJson(writer, value, serializer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     object value = base.ReadJson(reader, objectType, existingValue, serializer); 
     if (value is DateTimeOffset) 
     { 
      var date = (DateTimeOffset)value; 
      value = date.ToLocalTime(); 
     } 
     return value; 
    } 
} 

e applicarlo sulla proprietà che si desidera utilizzare l'attributo JsonConverter:

[JsonConverter(typeof(UtcDateTimeOffsetConverter))] 
public DateTimeOffset Date { get; set; } 
+0

Grazie per la risposta molto dettagliata. Penso di poter applicare questo convertitore globalmente usando JsonConvert.DefaultSettings. Dovrò provarlo più tardi. – Zoomzoom

+0

@Zoomzoom, controlla anche la risposta di Brian, è più semplice –

+0

Grazie a tutti e due. – Zoomzoom