Преобразование формата даты "EEE MMM dd HH: mm: ss zzzz yyyy" в "yyyy-MM-dd'T'HH: mm: ss" в Java

У меня проблема с оптимизацией кода. В настоящее время я конвертирую эти два формата с помощью java LocalDateTime. Но это занимает от 80 до 110 мс. Это также увеличивает мое время ответа. Есть ли альтернативный и более быстрый способ сделать это?

вот мой код:

value= Tue Jan 01 00:19:32 CET 1901

begindate = 1901-01-01T00:19:32

private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern
("EEE MMM dd HH:mm:ss zzz yyyy",Locale.ENGLISH);

LocalDateTime beginDate = LocalDateTime.parse(value, formatter);

String Isoformat = beginDate.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)


1 ответ

Решение

Изменить: комментарии Джона Скита и, наконец, сами дают ответ: при первом анализе строки необходимо загрузить базу данных часовых поясов и данные локали, включенные в JVM, для анализа CET(или другое сокращение часового пояса в строке). На это нужно время. В следующий раз эти данные уже будут загружены, поэтому парсинг будет быстрым.

Вы можете улучшить время анализа первой строки, если при запуске программы у вас есть время выполнить некоторую операцию с часовым поясом, чтобы данные были загружены. Вы можете попробовать ZoneId.systemDefault() или же ZoneId.systemDefault().getDisplayName(TextStyle.SHORT, Locale.ENGLISH) или просто разобрать (жестко запрограммированную) строку, как в базе данных.

Исходный ответ: измените схему базы данных, чтобы сохранить дату и время как timestamp with time zone или же datetime. Это избавит вас от разбора. (Если данные в вашей таблице уже есть, преобразование, конечно, займет время, но это только один раз и не происходит, пока пользователь ожидает ответа.)

Если вы не можете изменить схему базы данных, вот более прямой ответ на ваш вопрос. Это уродливый код, потому что он написан для оптимизации, поэтому используйте его только в крайнем случае.

private static DateTimeFormatter monthFormatter
        = DateTimeFormatter.ofPattern("MMM", Locale.ROOT);

    int m = Month.from(monthFormatter.parse(value.subSequence(4, 7))).getValue();
    if (m < 10) {
        return value.substring(value.length() - 4) + "-0" + m + '-' + value.substring(8, 10) + 'T' + value.substring(11, 19); 
    } else {
        return value.substring(value.length() - 4) + '-' + m + '-' + value.substring(8, 10) + 'T' + value.substring(11, 19); 
    }

На моем 10-летнем компьютере это сократило время с 1,78 миллисекунды до 0,73 мс на преобразование, измеренное с помощью System.nanoTime()на 100 преобразований. Снижение на 59 % по сравнению с вашим кодом.

Вы можете получить дополнительную скидку, если сделаете свой собственный HashMap поиск аббревиатуры месяца вместо использования DateTimeFormatter.

Другие вопросы по тегам