Конвертировать java.util.Date в String в формате гггг-ММ-дд без создания большого количества объектов - PullRequest
0 голосов
/ 18 октября 2018

Мне нужно конвертировать java.util.Date в String в формате yyyy-MM-dd в больших количествах.

Я только что перешел на Java 8 и хочу знать, как это сделать правильно.Мое решение с Java 7 было таким:

DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern(DATE_FORMAT_PATTERN)

DATE_FORMATTER.print(value.getTime())

Это помогло мне не создавать много избыточных объектов.

Так что теперь, когда я перешел на Java 8, я хочу переписать его правильно, но:

LocalDate.fromDateFields(value).toString())

каждый раз создает новый LocalDate объект, и это дает много работы GC.

Есть ли способы решить мою проблему?Производительность и безопасность потоков очень важны.

После некоторого тестирования я обнаружил, что даже при создании новых объектов конструкция с:

new SimpleDateFormat("yyyy-MM-dd")).format(value)) 

самая быстрая во всей этой теме.

Ответы [ 5 ]

0 голосов
/ 19 октября 2018

вы можете использовать аннотацию @JsonFormat (shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") для вашего поля.

0 голосов
/ 18 октября 2018

Без создания большого количества объектов, а это значит, что вам нужна версия производительности?

public static String getIsoDate(java.util.Date time) {
    java.util.Calendar cal = java.util.Calendar.getInstance();
    cal.setTime(time);
    StringBuilder sb = new StringBuilder();
    int year = cal.get(java.util.Calendar.YEAR);
    int month = cal.get(java.util.Calendar.MONTH) + 1;
    int day = cal.get(java.util.Calendar.DAY_OF_MONTH);
    sb.append(year);
    sb.append('-');
    if (month < 10) {
        sb.append('0');
    }
    sb.append(month);
    sb.append('-');
    if (day < 10) {
        sb.append('0');
    }
    sb.append(day);
    return sb.toString();
}

Эта версия является поточно-ориентированной и позволяет избежать создания большинства скрытых объектов, и если у вас нет лет до 1000 или старше 9999, онабудет печатать просто отлично.

0 голосов
/ 18 октября 2018

Используйте SimpleDateFormat для форматирования даты.

обратите внимание, SDF равен НЕ БЕЗОПАСНО ДЛЯ РЕЗЬБЫ , это может быть не важно, но имейте это в виду.

Например:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println((sdf.format(new Date())).toString());

ССЫЛКА с дополнительной информацией.

0 голосов
/ 18 октября 2018

Следующие данные имеют только накладные расходы для преобразования старой даты в новую LocalDate.

    Date date = new Date();
    LocalDate ldate = LocalDate.from(date.toInstant().atZone(ZoneOffset.UTC));
    String s = DateTimeFormatter.ISO_DATE.format(ldate); // uuuu-MM-dd

Правда, DateTimeFormatters являются поточно-ориентированными и, следовательно, будут иметь на один экземпляр больше для каждого вызова.

PS

Я добавил .atZone(ZoneOffset.UTC) из-за сообщенного исключения и решения @ Flown: указание зоны.Поскольку Date не обязательно используется для дат UTC, можно использовать другую.

0 голосов
/ 18 октября 2018

У меня нет точных цифр с точки зрения производительности, но я бы использовал Java 8 Time API для решения этой проблемы.В вашем особом случае я бы использовал следующее утверждение:

LocalDate.now().format(DateTimeFormatter.ISO_DATE);

РЕДАКТИРОВАТЬ: Для этого решения требуется преобразование из java.util.Date в java.time.LocalDate!

new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
...