Warm tip: This article is reproduced from serverfault.com, please click

Convert date fomat "EEE MMM dd HH:mm:ss zzzz yyyy" to "yyyy-MM-dd'T'HH:mm:ss" in Java

发布于 2020-11-28 06:37:59

I have the code optimisation issue. Currently I am converting these two formats using java LocalDateTime. But it takes around 80 ms - 110 ms. This is increasing my response time as well. Is there an alternative and faster way to do this ??

here is my code :

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)


Questioner
Srishti
Viewed
0
Ole V.V. 2020-11-28 23:02:27

Edit: The comments by Jon Skeet and finally yourself give the answer: The first time you parse a string, the time zone database and the locale data included with the JVM need to be loaded in order to parse CET (or other time zone abbreviation in the string). This takes time. The next times theses data are already loaded, so parsing is fast.

You can improve the parsing time of the first string if on program startup you have time to do some time zone operation so the data are loaded. You may try ZoneId.systemDefault() or ZoneId.systemDefault().getDisplayName(TextStyle.SHORT, Locale.ENGLISH) or simply parsing a (hardcoded) string like the ones in the database.

Original answer: Change the database schema to store the date and time as timestamp with time zone or datetime. This will save you from parsing. (If there’s data in your table already, converting it will take time, of course, but that’s only once and doesn’t happen while the user is waiting for a response.)

If you can’t change the database schema, here’s a more direct answer to your question. It’s ugly code because it’s written for optimization, so only use it as a last resort.

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); 
    }

On my 10 years old computer this reduced the time from 1.78 milliseconds to 0.73 ms per conversion, measured with System.nanoTime() on 100 conversions. A 59 % reduction compared to your code.

You may be able to get a further reduction if you make your own HashMap lookup of the month abbreviation instead of using a DateTimeFormatter.