Home » Java » How to resolve one day offset problem for a date in Java Spring-Exceptionshub

How to resolve one day offset problem for a date in Java Spring-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am very tired. I cannot resolve the problem with one day lost in Java Spring. There are many similar questions in stackoverflow, but none of them helped me.

My Spring App uses java.time.LocalDate package and accepts birthday from date field on frontend (react-datetime component). In yyyy-mm-dd format. Spring uses jdbc to save data to table in mysql database.

The birthday saved into DB as one day lost. For example user entered – 1998-04-12 then it will be saved as 1998-04-11. This happens only for some months, the months from november till march saved correctly to DB, but other months with one day lost. This is both on creating and on editing of the user.

Here is the code:

...
import java.time.LocalDate;

public class UserInfo {
...
public LocalDate birthday;

}

@PreAuthorize("hasAnyAuthority('ADMIN_GROUP_EDIT, SPEC_USERS_EDIT, USERS_EDIT, REGISTRATION_DATA_EDIT')")
@RequestMapping(value = "/update/{id}", method = PUT)
public void update(HttpServletResponse response, HttpServletRequest request, @PathVariable Long id) {
    User curUser = getUser();
    log.info("Got update user request by user " + curUser);
    log.info("For user id " + id);
    String reqBody = Utils.toString(request);
    if (reqBody == null) {
        returnError(response, RestErrorCode.EMPTY_REQUEST);
        return;
    }
    JsonElement body = new JsonParser().parse(reqBody);
    JsonObject jsonObject = body.getAsJsonObject();
    if (jsonObject == null) {
        log.error(BAD_REQUEST_BODY_MESS);
        return;
    }

    UserInfo info = null;

    if (jsonObject.has("info")) {
        String infoStr = jsonObject.get("info").toString();
        info = GsonHelper.fromJson(infoStr, UserInfo.class);
    }

 userService.updateUserInfo(info);

@Transactional
    public int updateUserInfo(UserInfo info) {
        info.editorUserId = AuthProvider.getCurUserId();
        return transactionTemplate.execute(status -> {
            String update = "" +
                "UPDATE USER_INFO " +
                "   SET first_name = COALESCE(:firstName, first_name), " +
                "   middle_name = COALESCE(:middleName, middle_name), " +
                "   last_name = COALESCE(:lastName, last_name), " +
                "   birthday = COALESCE(:birthday, birthday), " +
                "   address = COALESCE(:address, address)," +
                "   email = COALESCE(:email, email)," +
               "WHERE id =:id";
            return npDb.update(update, new FieldSqlParameterSource(info));
        });
    }

I debugged my code, backend correctly accepts user’s birthday and uses simple jdbc but where is the rat I didn’t find. How to overcome this problem?

How to&Answers:

This looks like a timezone issue, specifically the daylight savings time (last sunday in march to last sunday in october in European countries). Check that the timezone settings of the machine, your Java environment and the database server match. Dates like birthdays should be of type DATE (not TIMESTAMP).