2014-10-29 11 views
0

내 안드로이드 애플 리케이션에서 날짜에 ISO8601 형식을 사용하는 ReST API에서 데이터를 가져옵니다. 한 예는 "2014-04-24T21:56:50.443Z"입니다. 때로는 시간대가 Z로 표시되고 때로는 signHH:mm (예 : -08 : 00)으로 표시됩니다.안드로이드에서 ISO8601 날짜 문자열을 길게

날짜가 내 데이터베이스에 삽입되는 동안 api에서받은 날짜가 오래 변환됩니다. 현재 나는 insert 문에서 다음 명령을 사용하여 iso8601String을 율리우스 날짜로 변환합니다.이 날짜는 이후에 획 (epoch) 이후 밀리 초 수를 제공하는 긴 시간 소인으로 변환됩니다 (이것은 내가 줄 수있는 유일한 명령이었습니다. 내 앱 슈퍼 중요하다 나 밀리 초 정밀)

"CAST(((strftime('%J', '" + iso8601String + "') - 2440587.5) * 86400000) AS INTEGER)" 

지금 시나리오는 데이터베이스에 도착도하기 전에 긴 타임 스탬프로 들어오는 iso8601String을 변환하는 저를 요구하는 내놓았다. 이 문자열로 작업하기 위해 Android의 SimpleDateFormat에 제공해야하는 패턴은 yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ이지만 안타깝게도 ZZZZZ은 Android 버전 < 4.3에서 지원되지 않습니다 (그러나 4.0 이상 (API 레벨 14)을 실행하는 모든 장치를 지원해야 함) !!

어쨌든 SimpleDateFormat에 종속되지 않고 타임 스탬프와 iso8601String을 구문 분석/포맷 할 수 있습니까? (나는 그것으로 큰 의존성을 JodaTime를 사용할 수 있으며, 그것은 안드로이드에 자사의 성능을 알 수 없습니다)

변환이 Long

Date의 변환 내 사용자 지정 GSON 시리얼 라이저/디시리얼라이저에서 수행됩니다

답변

2

나는 내 대답을 생각해 냈다 !! 개념은 날짜 문자열을 모든 버전의 SimpleDateFormat (> = API 레벨 14)이 이해할 수있는 형식 (yyyy-MM-dd'T'HH:mm:ss.SSSZ)으로 변환하는 것입니다. 따라서 날짜를 직렬화해야하는 경우 문자열의 역 직렬화를 yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ에서 yyyy-MM-dd'T'HH:mm:ss.SSSZ으로 변환해야하며 반대의 경우도 마찬가지입니다.

public class GsonIso8601Datelizer implements JsonSerializer<Date>, JsonDeserializer<Date> { 

private static final String COMPAT_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; 
private static final char COLON = ':'; 
private static final char ISO8601_TZ_INFO_IS_JUST_Z = 'Z'; 
private static final int ISO8601_COLON_INDEX = 26; 

private final SimpleDateFormat mSimpleDateFormat; 

public GsonIso8601Datelizer() { 
    mSimpleDateFormat = new SimpleDateFormat(COMPAT_FORMAT_STRING); 
} 


@Override 
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) { 
    if (src == null) { 
     return null; 
    } else { 
     StringBuilder stringBuilder; 
     synchronized (this) { 
      stringBuilder = new StringBuilder(mSimpleDateFormat.format(src)); 
     } 

     stringBuilder.insert(ISO8601_COLON_INDEX, COLON); 
     return new JsonPrimitive(stringBuilder.toString()); 
    } 
} 


@Override 
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
    if (json.isJsonNull() || TextUtils.isEmpty(json.getAsString())) { 
     return null; 
    } else { 
     StringBuilder stringBuilder = new StringBuilder(json.getAsString().trim()); 
     if (stringBuilder.charAt(stringBuilder.length() - 1) == ISO8601_TZ_INFO_IS_JUST_Z) { 
      stringBuilder.replace(stringBuilder.length() - 1, stringBuilder.length(), "+0000"); 
     } else { 
      stringBuilder.deleteCharAt(ISO8601_COLON_INDEX); 
     } 

     Date date; 
     synchronized (this) { 
      try { 
       date = mSimpleDateFormat.parse(stringBuilder.toString()); 
      } catch (ParseException e) { 
       throw new IllegalArgumentException("Couldn't parse date string. " + 
         "Original: " + json.getAsString() + "; " + 
         "After custom processing: " + stringBuilder.toString()); 
      } 
     } 
     return date; 
    } 
} 
GSON

에 대한 사용자 지정 직렬/역 직렬화를 사용하여 수행 할 수 있습니다
관련 문제