Convert java.util.Date to String in yyyy-MM-dd format without creating a lot of objects

China☆狼群 提交于 2019-12-06 17:12:44

问题


I need to convert java.util.Date to String in yyyy-MM-dd format in a big amounts.

I have just moved to java 8 and want to know how to do it properly. My solution with Java 7 was like:

DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern(DATE_FORMAT_PATTERN)

DATE_FORMATTER.print(value.getTime())

It helped me not to create a lots of redundant objects.

So now when I moved to java 8 I want rewrite it properly but:

LocalDate.fromDateFields(value).toString())

creates each time new LocalDate object and this gives a lot of work to GC.

Are there any ways to solve my problem? Performance and thread-safety are very important.

After some testing I have found that even with creating new objects construction with:

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

the fastest all over this topic.


回答1:


The following only has an overhead for the conversion of the old Date to the new LocalDate.

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

It is true however that DateTimeFormatters are thread-safe and hence will have one instantiation more per call.

P.S.

I added .atZone(ZoneOffset.UTC) because of a reported exception, and @Flown's solution: specifying the zone. As Date is not necessarily used for UTC dates, one might use another one.




回答2:


Use SimpleDateFormat to format Date.

watch out, SDF is NOT THREAD-SAFE, it might not be important but keep that in mind.

For Example:

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

LINK with more information.




回答3:


I don't have exact numbers from point of view of the performance but I would use the Java 8 Time API to solve this issue. In your special case I would use the following statement:

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

EDIT: For this solution is a conversion from java.util.Date to java.time.LocalDate required!

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



回答4:


Without creating lots of objects, meaning you want the performance version?

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

This version is thread-safe and avoids most hidden object creations, and unless you have years under 1000 or over 9999, it will print just fine.




回答5:


you can use @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") annotation on your field.



来源:https://stackoverflow.com/questions/52870774/convert-java-util-date-to-string-in-yyyy-mm-dd-format-without-creating-a-lot-of

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!