2013-02-16 14 views
5

Parsuję JSON z serwera w mojej aplikacji Android przy użyciu biblioteki Jackson JSON. Jednak wnioski analizowania zawieść, gdy otrzymam DateTime ponieważ jest w tym formacie:Parsowanie ASP.NET MVC zwrócił datę przy użyciu biblioteki Jackson JSON w Javie

"/Date(1277931782420)/" 

Wiem, że powinienem zrobić coś takiego:

ObjectMapper om = new ObjectMapper(); 
om.setDateFormat(new TicksSinceFormat()); 

Ale nie mam pojęcia, czy mogę użyć SimpleDateFormat w ogóle (i jakiego formatu formatu użyłbym?) lub muszę napisać własny parser DateFormat. Tak więc, na serio będę wdzięczny, jeśli ktoś mógłby pomóc z przykładem kodu.

EDIT: OK, zobacz moją odpowiedź dla kompletnego kodu.

Odpowiedz

5

To okazało się trudniejsze niż się spodziewałem:

public class TicksSinceFormat extends DateFormat { 
    @Override 
    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition field) { 
     long millis = date.getTime(); 

     return new StringBuffer("/Date(" + millis + ")/"); 
    } 

    @Override 
    public Date parse(String string, ParsePosition position) { 
     int start = string.indexOf("(") + 1; 
     int end = string.indexOf(")"); 

     String ms = string.substring(start, end); 
     Date date = new Date(Long.parseLong(ms)); 

     position.setIndex(string.length() - 1); // MUST SET THIS 
     return date; 
    } 

    @Override 
    public Object clone() { 
     return new TicksSinceFormat(); // MUST SET THIS 
    } 
} 

Korzystanie klasa jest wtedy bardzo proste, wystarczy zrobić:

ObjectMapper om = new ObjectMapper(); 
om.setDateFormat(new TicksSinceFormat()) 

Zakładam, że to może być lepiej zakodowane + że będę musiał poradzić sobie z różnicami, jeśli chodzi o .NET Ticks VS Java ticks - ale na razie będzie to o. Jeśli ktoś ma lepsze rozwiązanie lub lepszy wgląd w wymienione problemy, zajmie mi to później - zapraszam do zamieszczania postów i zaznaczę twoją odpowiedź jako poprawną, o ile jest lepsza.

EDYCJA: Jak już wyjaśniłem w tym question & answer przełączyłem się na bibliotekę ServiceStack.Text na serwerze i zwraca ona inny format ISO8601. Dla tego formatu używam nieco innej analizy (ponieważ Jackson ma problem z analizą ISO8601, która zawiera milisekundy). Oczywiście, jak z innym kodem jestem delegowania - daj mi znać, jeśli masz lepszą wersję (tylko proszę pisać kod/edytować ten post, zamiast uciekania się do filozoficznej retoryki, w jaki sposób należy to zrobić):

@SuppressLint("SimpleDateFormat") 
public class JacksonSimpleDateFormat extends SimpleDateFormat { 
    public JacksonSimpleDateFormat() { 
     if (mParser == null) { 
      mParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 
      mParser.setTimeZone(TimeZone.getTimeZone("UTC")); 
     } 
    } 

    @Override 
    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition field) { 
     return mParser.format(date, buffer, field); 
    } 

    private static SimpleDateFormat mParser; 
    @Override 
    public Date parse(String string, ParsePosition position) { 
     String str = string.split("\\.")[0]; 

     Date date = null; 
     try { 
      date = mParser.parse(str); 
     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     position.setIndex(string.length() - 1); 
     return date; 
    } 

    @Override 
    public Object clone() { 
     return new JacksonSimpleDateFormat(); 
    } 
} 
+1

Wygląda na to, że twój kod powinien działać dobrze ... jedyną zmianą, którą zrobiłbym, jest użycie grupy przechwytującej RegEx w swojej metodzie "parsowania" , zamiast string.indexOf/string.substring. To tylko styl ... Zawsze uważałem, że string.indexOf/substring jest nieco kruchy i trudny w obsłudze, jeśli chodzi o indeks/długość. Tylko moja skromna opinia. –

+0

@PhilipTenn Dbaj o dobry kod Regex i kod, który zadziała na pewno? – kape123

3

mogę się mylić w tej sprawie, bo nie dostał bardzo daleko w rozwoju Android, ale format ty przedstawiane:

"/Date(1277931782420)/" 

Pojawia się Unix czas epoka.

Jeśli tak jest, nie trzeba/trzeba używać SimpleDateFormat. Zamiast tego spróbuj utworzyć z niego Long i przekazać do konstruktora Date, określając, czy jest to wartość czasu w sekundach lub milisekundach.

Oto post StackOverflow, który dostarcza kod robi tak: https://stackoverflow.com/a/535017/463196

+0

Dziękuję za link - Pracuję nad tym, ale są pewne nieoczekiwane problemy (patrz edit) – kape123

Powiązane problemy