Как решить проблему смещения на один день для даты в Java Spring - PullRequest
0 голосов
/ 17 февраля 2020

Я очень устал. Я не могу решить проблему с одним днем, потерянным в Java Spring. Есть много похожих вопросов в stackoverflow, но ни один из них мне не помог.

Приложение My Spring использует пакет java .time.LocalDate и принимает поле дня рождения с даты в веб-интерфейсе (компонентact-datetime). В формате гггг-мм-дд. Spring использует jdb c для сохранения данных в таблицу в базе данных mysql.

День рождения сохранен в БД как один потерянный день. Например, пользователь ввел - 1998-04-12, затем он будет сохранен как 1998-04-11. Это происходит только в течение нескольких месяцев, месяцы с ноября по март правильно сохранены в БД, но другие месяцы с одним потерянным днем. Это как при создании, так и при редактировании пользователя.

Вот код:

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

Я отладил свой код, серверная часть правильно принимает день рождения пользователя и использует простой jdb c, но где находится крыса, которую я не нашел. Как преодолеть эту проблему?

1 Ответ

2 голосов
/ 17 февраля 2020

Это похоже на проблему с часовым поясом, особенно проблему, касающуюся перехода на летнее время (с последнего воскресенья марта по последнее воскресенье октября в европейских странах). Убедитесь, что настройки часового пояса компьютера, среды Java и сервера базы данных совпадают. Даты, такие как дни рождения, должны быть типа DATE (не TIMESTAMP).

...