2015-02-16 2 views
6

Ich verwende die Retrofit-Bibliothek für meine REST-Aufrufe. Der JSON, der hereinkommt, sieht so aus.GSON-Serialisierung nachrüsten Datum aus JSON-String in long oder java.lang.Long

{ 
    "created_at": "2013-07-16T22:52:36Z", 
} 

Wie kann ich feststellen, Retrofit oder Gson diese lange in zu konvertieren?

+0

Sie einen benutzerdefinierten Typ-Wandler verwenden können (aber ich weiß nicht, wie man eines von diesen auf ein bestimmtes Feld statt auf einen ganzen Typ beschränkt) – njzk2

+0

als Randnotiz, dieses 'Z' sieht st Angebot. Ich würde auf ein Formatierungsproblem auf der Serverseite wetten. – njzk2

+0

das 'Z' bedeutet einfach, es gibt keinen Offset von UTC - mehr Infos von [wikipedia] (http://en.wikipedia.org/wiki/ISO_8601#UTC) –

Antwort

5

es lesen als String in Ihrem POJO in dann Getter verwenden Sie es als eine lange zurück:

String created_at; 

public long getCreatedAt(){ 
    SimpleDateFormat formatter = new 
       SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 
    Date createDate = formatter.parse(created_at); 

    return createDate.getTime(); 
} 

die Simple String here

+0

@ njzk2 gut bearbeiten danke – pula

+0

Dies funktioniert nicht für mich aus irgendeinem Grund ... http://pastebin.com/rizyZJR5 – Lion789

+0

@ Lion789, ohne Ihre Ausgabe zu sehen oder die Unterschiede zwischen 'DateFormat' vs' SimpleDateFormat' bewusst zu sein, würde ich versuchen, mit SimpleDateFormat. – pula

0

referenziert werden können Sie die Parse-Muster in die festlegen GsonBuilder.setDateFormat() und legen Date-Objekt in der POJO und dann rufen Sie einfach Date.getMillis()

setDateFormat()

18

Sie können dies ganz einfach tun, indem Sie einen benutzerdefinierten GsonConverter mit Ihrem eigenen Gson-Objekt auf der Retrofit-Instanz einrichten. In Ihrem POJO können Sie Date created_at; statt einer langen oder einer Zeichenfolge. Vom Datumsobjekt können Sie created_at.getTime() verwenden, um bei Bedarf die Länge zu erhalten.

Gson gson = new GsonBuilder() 
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssz") 
.create(); 

RestAdapter.Builder builder = new RestAdapter.Builder(); 
// Use a custom GSON converter 
builder.setConverter(new GsonConverter(gson)); 
..... create retrofit service. 

Sie auch mehrere Datum String-Formate durch die Registrierung eines benutzerdefinierten JsonDeserializer auf der Gson Instanz verwendet durch Nachrüstung

GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(Date.class, new DateTypeDeserializer()); 

public class DateTypeDeserializer implements JsonDeserializer<Date> { 
    private static final String[] DATE_FORMATS = new String[]{ 
      "yyyy-MM-dd'T'HH:mm:ssZ", 
      "yyyy-MM-dd'T'HH:mm:ss", 
      "yyyy-MM-dd", 
      "EEE MMM dd HH:mm:ss z yyyy", 
      "HH:mm:ss", 
      "MM/dd/yyyy HH:mm:ss aaa", 
      "yyyy-MM-dd'T'HH:mm:ss.SSSSSS", 
      "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS", 
      "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'", 
      "MMM d',' yyyy H:mm:ss a" 
    }; 

    @Override 
    public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationContext context) throws JsonParseException { 
     for (String format : DATE_FORMATS) { 
      try { 
       return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString()); 
      } catch (ParseException e) { 
      } 
     } 
     throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString() 
       + "\". Supported formats: \n" + Arrays.toString(DATE_FORMATS)); 
    } 
} 
2

Nach dem Lesen der Dokumente unterstützen kann, habe ich versucht, dies. Es funktioniert, aber ich weiß nicht, ob es irgendwelche Auswirkungen auf andere Arten haben wird.

Ich brauchte eine lange in meinem POJO, coz ich möchte nicht konvertieren, wenn in DB speichern.

benutzen ich einen benutzerdefinierten Deserializer

JsonDeserializer<Long> deserializer = new JsonDeserializer<Long>() { 
    @Override 
    public Long deserialize(JsonElement json, Type typeOfT, 
     JsonDeserializationContext context) throws JsonParseException { 
     try{ 
      if(json==null){ 
       return new Long(0); 
      } 
      else{ 
       String dateString = json.getAsString(); 
       long dateLong = DateFormatUtil.getLongServerTime(dateString); 
       return new Long(dateLong); 
      } 
     } 
     catch(ParseException e){ 
      return new Long(0); 
     } 
    } 
}; 

und Verwendung soll es

Gson gson = new GsonBuilder() 
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 
    .setDateFormat(patternFromServer) 
    .registerTypeAdapter(Long.class, deserializer) 
    .create(); 
+0

Danke, es funktioniert für mich – schwertfisch

+0

Benötigen Sie angeben .setDateFormat (...)? Meins hat ohne das gearbeitet. – bMcNees

0

Sie einen Typ-Adapter in Ihrem Gson Beispiel durch

new GsonBuilder() 
    .registerTypeAdapter(Date.class, [date deserializer class here]) 
    .create 

verwenden werden, aber kann ich vorschlagen, dass Anstatt einen SimpleDateFormatter zu verwenden, werfen Sie einen Blick auf diese Implementierung m FasterXML/jackson-databind-Implementierungen für die ISO8601-Datumsverarbeitung in this class und this one. Es hängt sehr davon ab, ob Sie viele Daten analysieren oder nicht.

Beachten Sie auch, dass wir Probleme mit der Verwendung von SimpleDateFormatter in einer Android-Anwendung (wir verwenden eine Kombination aus Java und Android-Bibliotheken) gab, wo es verschiedene Ergebnisse zwischen Parsing in Java und Android gab. Die Verwendung der obigen Implementierungen half dabei, dieses Problem zu lösen.

Dies ist Java implementation und dies ist die Android implementation, nicht die Definition für Z und X in der Java-Implementierung und die fehlenden X Implementierung in Android

2

Sie einfach diese setDateFormat() Methode verwenden, um es zu tun

public class RestClient 
{ 
    private static final String BASE_URL = "your base url"; 
    private ApiService apiService; 

    public RestClient() 
    { 
     Gson gson = new GsonBuilder() 
       .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'") 
       .create(); 

     RestAdapter restAdapter = new RestAdapter.Builder() 
       .setLogLevel(RestAdapter.LogLevel.FULL) 
       .setEndpoint(BASE_URL) 
       .setConverter(new GsonConverter(gson)) 
       .build(); 

     apiService = restAdapter.create(ApiService.class); 
    } 

    public ApiService getApiService() 
    { 
     return apiService; 
    } 
} 
0

Unten Code ist getestet und endlich funktioniert nach viel Mühe. vor dem Erstellen von Retrofit-Objekt erstellen Gson Objekt

Gson gson = new GsonBuilder() 
       .registerTypeAdapter(Date.class, new DateDeserializer()) 
       .registerTypeAdapter(Date.class, new DateSerializer()) 
       .create(); 

und jetzt schaffen Retrofit Beispiel

Retrofit retrofit retrofit = new Retrofit.Builder() 
        .baseUrl("URL") 
        .addConverterFactory(GsonConverterFactory.create(gson)) 
        .build(); 

diese beiden Klassen erstellen serialisiert und deserialisiert Datumsformat

static class DateDeserializer implements JsonDeserializer<Date> { 

     private final String TAG = DateDeserializer.class.getSimpleName(); 

     @Override 
     public Date deserialize(JsonElement element, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { 
      String date = element.getAsString(); 

      SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); 
      formatter.setTimeZone(TimeZone.getTimeZone("GMT")); 
      Date returnDate = null; 
      try { 
       returnDate = formatter.parse(date); 
      } catch (ParseException e) { 
       Log.e(TAG, "Date parser exception:", e); 
       returnDate = null; 
      } 
      return returnDate; 
     } 
    } 

    static class DateSerializer implements JsonSerializer<Date> { 

     private final String TAG = DateSerializer.class.getSimpleName(); 

     @Override 
     public JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) { 
      SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); 
      formatter.setTimeZone(TimeZone.getDefault()); 
      String dateFormatAsString = formatter.format(date); 
      return new JsonPrimitive(dateFormatAsString); 
     } 

    } 
Verwandte Themen