2014-06-11 5 views
1

J'utilise Newtonsoft JSON Serializer et c'est super et super rapide mais j'aimerais en faire un peu plus avec. Je ne suis pas sûr que ce soit possible car toutes les recherches que j'ai faites ne sont d'aucune utilité. Ce que je voudrais, c'est pouvoir tronquer le temps vide, donc quand c'est 2014-01-01 00:00:00.000 d'affichage je veux juste 2014-01-01 à la fin, donc fondamentalement couper tout le temps quand ils sont tous des zéros. Pour l'instant j'utilise ce morceau de code:Newtonsoft JSON comment changer dynamiquement le format de la date?

DataTable dt = loadData(); 

// encode the string with Newton JSON.Net 
string output = JsonConvert.SerializeObject(dt, 
    new JsonSerializerSettings 
    { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore, 
     Formatting = Newtonsoft.Json.Formatting.None, 
     DateFormatString = "yyyy-MM-dd HH:mm:ss" 
    }); 

Est-il possible de formater ces dates sans le temps (seulement quand ils sont tous les zéros) sans affecter les performances?

Répondre

1

Vous pouvez le faire avec un JsonConverter personnalisé:

class CustomDateConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(DateTime)); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     DateTime date = (DateTime)value; 
     string format = "yyyy-MM-dd HH:mm:ss"; 
     if (date.Hour == 0 && 
      date.Minute == 0 && 
      date.Second == 0 && 
      date.Millisecond == 0) 
     { 
      format = "yyyy-MM-dd"; 
     } 
     writer.WriteValue(date.ToString(format)); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

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

Démo:

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<DateTime> dates = new List<DateTime> 
     { 
      DateTime.Now, 
      DateTime.Today 
     }; 

     JsonSerializerSettings settings = new JsonSerializerSettings 
     { 
      ReferenceLoopHandling = ReferenceLoopHandling.Ignore, 
      Formatting = Newtonsoft.Json.Formatting.None, 
      Converters = new List<JsonConverter> { new CustomDateConverter() } 
     }; 

     string json = JsonConvert.SerializeObject(dates, settings); 

     Console.WriteLine(json); 
    } 
} 

Sortie:

["2014-06-11 11:56:28","2014-06-11"] 
+0

sonne bien, je vais essayer ... ne serait pas il vaut mieux vérifier l'heure avec quelque chose comme ceci: 'if (date.ToString (" HH: mm: ss.fff ") ==" 00: 00: 00.000 ") {..}', je ne veux pas être frappé par la performance sage comme m JSON peut facilement avoir quelques milliers de lignes – ghiscoding

+0

Non. Du point de vue de la vitesse pure, quatre comparaisons d'entiers seront certainement plus rapides que l'analyse d'une chaîne de format, formatant la date en chaîne puis comparant la date formatée à une chaîne de zéros. D'un point de vue pratique, il ne va pas faire la différence sur quelques milliers de lignes. Utilisez de quelque manière que ce soit plus lisible/maintenable à vous. Si vous êtes vraiment préoccupé par la vitesse, vous devriez utiliser des outils de profilage et de mesure pour trouver vos goulets d'étranglement au lieu de faire des optimisations prématurées. –

+0

Donc vous pensez que 4 contrôles d'entiers seraient toujours plus rapides qu'une conversion toString() + check? En fait, vous avez probablement raison, cela peut être un peu plus lent avec la conversion ToString() 'et la comparaison de chaînes, au lieu de simplement vérifier les entiers. J'imagine que j'utiliserai un entier comme vous l'avez écrit alors ... Mon résultat pourrait varier et augmenter jusqu'à 50k ou plus donc j'étais juste un peu concerné par les performances. – ghiscoding