Разбор LocalDate в String в методах получения и установки - PullRequest
1 голос
/ 23 октября 2019

У меня был класс на Java (Spring), и одной из переменных был тип Date (называемый fnac, в котором хранится дата рождения, поэтому мне не нужны часы!)

Это были их набор и получениеметоды:

public String getFnac() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        format.setTimeZone(TimeZone.getTimeZone("UTC+2"));
        return format.format(this.fnac);
    }


public void setFnac(String fnac) throws ParseException {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    format.setTimeZone(TimeZone.getTimeZone("UTC+2"));
    this.fnac = format.parse(fnac);
}

Я решил использовать LocalDate, так как все, кажется, говорят, что он новее и лучше, и ... Я хотел бы добавить сеттер и геттер в LocalDate

@Column(name = "FNAC")
    private LocalDate fnac;

Я пытался и искал часы, но я еще не мог добавить его в LocalDate. Вот моя последняя попытка:

    public void setFnac(String fnac) throws ParseException {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZonedDateTime zdt = ZonedDateTime.parse(fnac, formatter.withZone(ZoneId.systemDefault()));
    this.fnac = zdt.toLocalDate();

}



public String getFnac() {
    Instant now = Instant.now();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZonedDateTime zdt = now.atZone(ZoneId.systemDefault());
    return zdt.format(formatter).toString();
}

(у меня может быть что-нибудь прямо в сеттере,но ... извините, вы должны прочитать такой сборщик стихийных бедствий ...)

PD: Да, у меня сохранено LocalDate с этим: https://thoughts -on-java.org /persist-localdate-localdatetime-jpa /

Только с этим кодом он будет хранить даты "успешно":

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

Но, похоже, мне нужно работать с часовыми поясами, потому что... когда я сохраняю дату в базе данных, она сохраняет предыдущий день (потому что кажется, что она сохраняется с помощью dd / mm / yyyy в 00:00 UTC+0), поэтому, если я назначу дату рождения 07.10.2015, она сохранится 10.06.2015. Я даже не понимаю, почему LocalDate даже экономит час. Я использую LocalDate по причине, а не LocalDateTime. Я только хочу Даты, но время преследует меня!

Я UTC + 2 (но я думаю, что не имеет смысла хранить UTC + 2, потому что на следующей неделе мы будем UTC + 1), поэтому я думаю, что это будет ZoneId.of ("Европа / Мадрид ") (я полагаю, что при смене часовых поясов час будет меняться автоматически).

Надеюсь, вы мне поможете! (Извините за мой английский, он не идеален). Спасибо!

Ответы [ 4 ]

3 голосов
/ 23 октября 2019

LocalDate.parse

Это намного проще, чем вы думаете.

public void setFnac(String fnac) {
    this.fnac = LocalDate.parse(fnac);
}

public String getFnac() {
    return fnac.toString();
}

Я использую тот факт, что ваши строки имеют формат ISO 8601, формат по умолчанию дляклассы java.time, современный API даты и времени Java. Поэтому LocalDate анализирует этот формат без какого-либо явного средства форматирования, а также возвращает его из метода toString.

Просто забудьте все о старых классах Date и SimpleDateFormat. java.time может сделать все это для вас. И также не беспокойтесь о часовом поясе, потому что LocalDate не имеет никакого. Если дата неверно сохранена в базе данных, где-то в программном обеспечении или в ее конфигурации / настройке есть ошибка, которую вам необходимо выполнить.

Ссылка: Статья в Википедии:ISO 8601

2 голосов
/ 23 октября 2019

База данных, которую вы используете в настоящее время, не имеет понятия LocalDate, и когда вы конвертируете LocalDate в обычный класс Date, она переносит часы и минуты, установленные на полночь 00:00 Затем, когдабаза данных хранит объект в базе данных, сохраняет дату и добавляет к нему смещение часового пояса сервера.

Вот пример преобразования LocalDate в Date

LocalDate date = LocalDate.now();
System.out.println("From LocalDate: " + date);

Date d = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());

System.out.println("From Date" + d);

Вывод:

From LocalDate: 2019-10-23
Form Date: Wed Oct 23 00:00:00 UTC 2019

Как вы можете видеть, часовой пояс все еще сохраняется в дате, хотя в LocalDate не было времени. По сути, это то, что делает ваше обращение.

Самый простой способ исправить проблему с часовым поясом - это сохранить дату в виде строки в желаемом формате, а затем преобразовать при необходимости. Это будет соответствовать независимо от того, в каком часовом поясе находится ваш сервер и где вы находитесь.

1 голос
/ 24 октября 2019

Мне пришлось изменить эту строку в application.properties

spring.datasource.url = jdbc: mysql: // localhost: 3306 /...........& serverTimezone = UTC

на эту строку:

spring.datasource.url = jdbc: mysql: // localhost: 3306 /...........& serverTimezone = Европа / Мадрид

Я пытался раньше с UTC + 2, но его не было

Изменение этого конфига и ответа Ole VV сработало для меня

Спасибо!

0 голосов
/ 25 октября 2019

Поскольку вам не требуется время, вам нужно использовать только LocalDate .

public void setFnac(String fnac) {
    this.fnac = LocalDate.parse(fnac, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}

Для этого не нужно использовать ZonedDateTime. Надеюсь, что это поможет.

...