Search code examples
javaspring-bootformatlocaldatetime

Spring Boot Batch Processing LocalDatetime Format yyyy-MM-dd HH:mm:ss to yyyy-MM-dd


I have a problem about formatting localdatetime when I read values from csv file and add them into h2 database.

Here is the example of defining localdatetime in csv file.

2000-08-15 19:07:46

I want to get 2000-08-15 (removing time part). Even if I defined DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); instead of DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); in localDateTimeFormat method , I got an error.

Here is the error shown below.

java.time.format.DateTimeParseException: Text '1999-01-25 13:08:57' could not be parsed, unparsed text found at index 10
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2109) ~[na:na]
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2008) ~[na:na]
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:494) ~[na:na]
    at com.example.batchprocessingcsvtodatabase.config.UserProcessor.localDateTimeFormat(UserProcessor.java:37) ~[classes/:na]
    at com.example.batchprocessingcsvtodatabase.config.UserProcessor.process(UserProcessor.java:26) ~[classes/:na]
    at com.example.batchprocessingcsvtodatabase.config.UserProcessor.process(UserProcessor.java:14) ~[classes/:na]

How can I fix it?

Here is the user class shown below.

public class User extends BaseEntity{

    @Type(type = "org.hibernate.type.UUIDCharType")
    private UUID personId;

    private String firstName;
    private String lastName;
    private String email;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    private String country;

    @JsonFormat(pattern="yyyy-MM-dd")
    private LocalDateTime birthday;

    private int age;
}

Here is the processor class shown below.

public class UserProcessor implements ItemProcessor<UserInput, User> {


    @Override
    public User process(UserInput userInput) throws Exception {

        User user = User.builder()
                .personId(UUID.fromString(userInput.getPersonId()))
                .firstName(userInput.getFirstName())
                .lastName(userInput.getLastName())
                .email(userInput.getEmail())
                .country(userInput.getCountry())
                .birthday(localDateTimeFormat(userInput.getBirthday()))
                .gender(userInput.getGender().equals("Male") ? Gender.MALE : Gender.FEMALE)
                .age(Period.between(localDateTimeFormat(userInput.getBirthday()).toLocalDate(), LocalDate.now()).getYears())
                .build();

        return user;
    }

    private LocalDateTime localDateTimeFormat(String birthday) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime formatDateTime = LocalDateTime.parse(birthday, formatter);

        return formatDateTime;
    }
}

Solution

  • You have used the wrong type for birthday; it should be LocalDate as you want to keep only the date part.

    Change

    @JsonFormat(pattern="yyyy-MM-dd")
    private LocalDateTime birthday;
    

    to

    @JsonFormat(pattern="yyyy-MM-dd")
    private LocalDate birthday;
    

    You will also need to change the function definition to return LocalDate out of the parsed LocalDateTime as shown in the demo below:

    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class Main {
        public static void main(String[] args) {
            System.out.println(getLocalDate("2000-08-15 19:07:46"));
        }
    
        private static LocalDate getLocalDate(String birthday) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return LocalDateTime.parse(birthday, formatter).toLocalDate();
        }
    }
    

    Output:

    2000-08-15