2011-04-15 14 views
72

Después de 4 horas sin parar tratando de resolver el problema, he decidido preguntar aquí si alguien me puede ayudar."Fecha indescifrable: 1302828677828" tratando de deserializar con Gson una fecha del formato de milisegundos recibida del servidor

El problema es que mi cliente Android cuando intenta deserializar los datos recibidos de un servidor arroja la excepción "Unparseable: 1302828677828".

Me gustaría saber si es posible deserializar una fecha de formato milisegundo utilizando Gson.

+0

Qué fecha/hora se supone que esto represente? – Squonk

+0

¿No puedes simplemente analizarlo como 'largo', y luego convertir programáticamente' long' en 'Date' en tu código? – aroth

+11

Finalmente obtuve la solución: \t // Crea el objeto json que administrará la información recibida \t GsonBuilder builder = new GsonBuilder(); \t // Se registra un adaptador para gestionar los tipos de fecha como valores largos builder.registerTypeAdapter (Date.class, nuevo JsonDeserializer () { pública Fecha deserializar (JsonElement JSON, Tipo typeOfT, el contexto JsonDeserializationContext) lanza JsonParseException { \t return new Date (json.getAsJsonPrimitive(). GetAsLong()); } }); Gson gson = builder.create(); – Alfonso

Respuesta

129

comentario de Alfonso:

finalmente conseguí la solución:

// Creates the json object which will manage the information received 
GsonBuilder builder = new GsonBuilder(); 

// Register an adapter to manage the date types as long values 
builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
     return new Date(json.getAsJsonPrimitive().getAsLong()); 
    } 
}); 

Gson gson = builder.create(); 
+2

Esto no funciona cuando las fechas están en ambos formatos. –

+0

¡¡¡Muchas gracias, me salvaste el tiempo !! –

+0

gracias, es una gran respuesta –

0

tengo el mismo problema cuando traté de deserializar campo DateTime con Rest client de Android annotations biblioteca. Como solución que he creado a medida GsonHttpMessageConverter

public class CustomGsonHttpMessageConverter extends GsonHttpMessageConverter { 

    public CustomGsonHttpMessageConverter() { 
     // Creates the json object which will manage the information received 
     GsonBuilder builder = new GsonBuilder(); 

     // Register an adapter to manage the date types as long values 
     builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
      public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
       return new Date(json.getAsJsonPrimitive().getAsLong()); 
      } 
     }); 

     setGson(builder.create()); 
    } 
} 

y definirlo en el cliente resto

@Rest(rootUrl = "http://192.168.1.1:8080", converters = {CustomGsonHttpMessageConverter.class}) 
public interface RestClient extends RestClientErrorHandling { 
... 

espero que será útil

0

escribí un ImprovedDateTypeAdapter basado en GSON DateTypeAdapter por defecto que admite el formato de fechas predeterminadas y el formato de marca de tiempo (largo).

import com.google.gson.Gson; 
import com.google.gson.JsonSyntaxException; 
import com.google.gson.TypeAdapter; 
import com.google.gson.TypeAdapterFactory; 
import com.google.gson.reflect.TypeToken; 
import com.google.gson.stream.JsonReader; 
import com.google.gson.stream.JsonToken; 
import com.google.gson.stream.JsonWriter; 

import java.io.IOException; 
import java.text.DateFormat; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Locale; 
import java.util.TimeZone; 

public final class ImprovedDateTypeAdapter extends TypeAdapter<Date> { 

    public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { 

     public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { 

      @SuppressWarnings("unchecked") 
      TypeAdapter<T> typeAdapter = (TypeAdapter<T>) ((typeToken.getRawType() == Date.class) ? new ImprovedDateTypeAdapter() 
        : null); 
      return typeAdapter; 
     } 
    }; 
    private final DateFormat enUsFormat; 
    private final DateFormat localFormat; 
    private final DateFormat iso8601Format; 

    public ImprovedDateTypeAdapter() { 
     this.enUsFormat = DateFormat.getDateTimeInstance(2, 2, Locale.US); 

     this.localFormat = DateFormat.getDateTimeInstance(2, 2); 

     this.iso8601Format = buildIso8601Format(); 
    } 

    private static DateFormat buildIso8601Format() { 
     DateFormat iso8601Format = new SimpleDateFormat(
       "yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); 
     iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC")); 
     return iso8601Format; 
    } 

    public Date read(JsonReader in) throws IOException { 
     if (in.peek() == JsonToken.NULL) { 
      in.nextNull(); 
      return null; 
     } 
     return deserializeToDate(in.nextString()); 
    } 

    private synchronized Date deserializeToDate(String json) { 
     try { 

      return new Date(Long.parseLong(json)); 
     } catch (Exception e) { 

      try { 

       return this.localFormat.parse(json); 
      } catch (ParseException e1) { 

       try { 

        return this.enUsFormat.parse(json); 
       } catch (ParseException e2) { 

        try { 

         return this.iso8601Format.parse(json); 
        } catch (ParseException e3) { 

         throw new JsonSyntaxException(json, e3); 
        } 
       } 
      } 
     } 
    } 

    public synchronized void write(JsonWriter out, Date value) 
      throws IOException { 
     if (value == null) { 
      out.nullValue(); 
      return; 
     } 
     String dateFormatAsString = this.enUsFormat.format(value); 
     out.value(dateFormatAsString); 
    } 
} 

Para usarlo:

// Creates the json object which will manage the information received 
GsonBuilder builder = new GsonBuilder(); 

// Register an adapter to manage the date types as long values 
builder.registerTypeAdapter(Date.class, new ImprovedDateTypeAdapter()); 

Gson gson = builder.create(); 
Cuestiones relacionadas