2016-07-26 7 views
1

Я пришел из другого фона в Java. Этот вопрос может выглядеть глупым, но я не могу его решить своими текущими навыками.JSON UTC date string для локальной строки даты с использованием apache common

Мой сервер возвращает дату UTC как строку json. Я использую Gson с настраиваемым адаптером типа и преобразовываю его в формат требуемой даты (плюс локальный часовой пояс) с помощью SimpleDateFormat. Но поскольку SimpleDateFormat не является потокобезопасным, поэтому я пытаюсь использовать общую библиотеку Apache для получения того же, в котором я терпит неудачу.

//private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    private static final FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("UTC")); 

    @Override 
    public Date deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) throws JsonParseException { 

     try { 
      return DateUtils.parseDate(element.getAsString(), "yyyy-MM-dd HH:mm:ss"); 
     } catch (ParseException e) { 
      return null; 
     } 
     /* 
     sdf.setTimeZone(TimeZone.getTimeZone("UTC")); 

     try { 
      return sdf.parse(element.getAsString()); 
     } catch (ParseException e) { 
      return null; 
     } 
     */ 
    } 

Я ожидал что-то вроде fdf.parse() для преобразования даты UTC строки в локальную дату и не знаю, что я должен использовать.

И в моей модели:

public class UserData { 
    ... 
    private Date dt; 

    private final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy hh:mm a"); 

    public String getTime() { 
     //return dt == null ? "" : sdf.format(dt); 
     return DateFormatUtils.format(dt, "MMM dd, yyyy hh:mm a"); 
    } 
} 

Мое требование заключается в преобразовании UTC строку даты локальной строки даты с помощью Apache (Common Потокобезопасная). Также, если есть оптимизация кода для выполнения того же, это было бы более оценено.

Также мне не нужна дата как тип данных даты, поэтому она может быть преобразована в String/remove адаптера пользовательского типа, если дата может быть отображена в формате желаемого формата («MMM dd, yyyy hh: mm a»).

ответ

1

Использование класса FastDateFormat в библиотеке Apache Commons v3.3.2 работает для меня так:

FastDateFormat parser = 
    FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("UTC")); 
Date d = parser.parse("2015-11-17 19:29:39"); 
System.out.println(d); // in my time zone Europe/Berlin: Tue Nov 17 20:29:39 CET 2015 

FastDateFormat printer = 
    FastDateFormat.getInstance(
     "MMM dd, yyyy hh:mm a", 
     TimeZone.getDefault(), 
     Locale.ENGLISH 
    ); 
System.out.println(printer.format(d)); // Nov 17, 2015 08:29 PM 

Некоторые примечания:

Да, Apache говорит, что это потокобезопасной версия SimpleDateFormat, что означает, что вы можете использовать его как специальную замену (аналогичный API) и сохранить объект формата в статической конечной константе. Поэтому в многопоточной среде можно ожидать более высокой производительности. Но, пожалуйста, не слишком высокие ожидания относительно производительности. Это только быстрее по сравнению с старыми SimpleDateFormat.

В соответствии с моими собственными испытаниями другие более современные библиотеки выглядят быстрее, а также потокобезопасны: JSR-310 (java.time.format-package в Java-8), ThreetenABP (backported to Android), Joda -Time-Android и Time4A (моя собственная библиотека, очевидно, самая быстрая - примерно двойная скорость). Поэтому я думаю, что стоит рассмотреть и другие альтернативы библиотеки, если вы также заботитесь о производительности.

Update:

я сейчас скачал и успешно протестировали версии v3.4, так что я не могу воспроизвести здесь свой комментарий. Я бы также не ожидал, что удаление такого важного метода будет выпущено без существенных изменений. Может быть, вы просто верите, что у вас есть v3.4, но другая более старая версия активна.

Примеры использования других библиотек:

Threeten-ABP (адаптация Backport из JSR-310 для Android)

примерно такой же скорости синтаксического анализа как Apache Commons Lang

static final DateTimeFormatter PARSER = 
    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(
     ZoneOffset.UTC 
    ); 
static final DateTimeFormatter PRINTER = 
    DateTimeFormatter.ofPattern("MMM dd, yyyy hh:mm a", Locale.ENGLISH) 
    .withZone(ZoneId.systemDefault()); 

public static String toLocaleZone(String utc) { 
    ZonedDateTime zdt = ZonedDateTime.parse("2015-11-17 19:29:39", PARSER);  
    return PRINTER.format(zdt); 
} 

Joda-Time-Android (адаптация Joda-Time для Android)

немного быстрее разборе чем ThreetenABP или Apache Commons

static final DateTimeFormatter PARSER = 
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZoneUTC(); 
static final DateTimeFormatter PRINTER = 
    DateTimeFormat.forPattern("MMM dd, yyyy hh:mm a").withLocale(Locale.ENGLISH).withZone(
     DateTimeZone.getDefault() 
    ); 

public static String toLocaleZone(String utc) { 
    DateTime dt = PARSER.parseDateTime("2015-11-17 19:29:39"); 
    return PRINTER.print(dt); 
} 

Time4A (адаптация Time4J для Android)

самый быстрый подход (примерно в два раза скорость парсер)

static final ChronoFormatter<Moment> PARSER = 
    ChronoFormatter.ofMomentPattern(
     "yyyy-MM-dd HH:mm:ss", 
     PatternType.CLDR, 
     Locale.ROOT, 
     ZonalOffset.UTC 
    ); 
static final ChronoFormatter<PlainTimestamp> PRINTER = 
    ChronoFormatter.ofTimestampPattern(
     "MMM dd, yyyy hh:mm a", 
     PatternType.CLDR, 
     Locale.ENGLISH 
    ); 

public static String toLocaleZone(String utc) throws ParseException { 
    Moment m = PARSER.parse(utc); // "2015-11-17 19:29:39" 
    return PRINTER.format(m.toLocalTimestamp()); // Nov 17, 2015 08:29 pm 
} 
+0

Я использую ApacheCommons v3.4 и не существует метода 'parse()', который вызывает у меня проблемы. Если я использую 'parseObject()', то он возвращает объект Date как null из блока catch. –

+0

Я использую Java-7, поэтому не могу использовать JSR-310. Если бы я не смог найти решение, я попробую Джоду. О ThreeTenABP & Time4A Я не мог понять, как использовать их в моем адаптере Model & Date для удовлетворения моих требований. Если бы вы могли дать образец, это помогло бы мне. –

+0

@RajanSharma Официальный API для v3.4 упоминает, что [метод] (https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/apache/commons/lang3/time/FastDateFormat. html # parse (java.lang.String)), проверит его вскоре после его загрузки. –

0
Use the below method for converting UTC date format to Local date Format 
private void converUTCTOLocal(){ 
     String dateInput = "02/04/2016 12:22:11"; 
    //sdfIn is current date format 
     SimpleDateFormat sdfIn = new SimpleDateFormat("dd/mm/yyyy hh:mm:ss"); 
    //sdfOut is required date format 
     SimpleDateFormat sdfOut = new SimpleDateFormat("dd/mm/yyyy hh:mm:ss"); 
     sdfOut.setTimeZone(Calendar.getInstance().getTimeZone()); 
     TimeZone utcZone = TimeZone.getTimeZone("UTC"); 
     sdfIn.setTimeZone(utcZone); 
     try { 
      Date dateIn = sdfIn.parse(dateInput); 
      String dateOut = sdfOut.format(dateIn); 
      Log.i("dateOut",""+dateOut); 


     }catch (ParseException e1){ 
      e1.printStackTrace(); 
     }catch (Exception e){ 
      e.printStackTrace();`enter code here` 
     } 

    } 
+1

Внимательно прочитайте мое требование. Я должен избегать SimpleDateFormat. –