【问题标题】:Parsing LocalDate to String in getter and setter methods在 getter 和 setter 方法中将 LocalDate 解析为 String
【发布时间】:2020-02-19 22:39:40
【问题描述】:

我有一个 Java (Spring) 类,其中一个变量是 Date 类型(称为 fnac,它存储生日,所以我不需要小时数!)

这些是他们的 set 和 get 方法:

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,因为每个人似乎都说它更新更好,而且... 我想将 setter 和 getter 添加到 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");

但似乎我需要使用时区,因为...当我在数据库中保存日期时,它将保存前一天(因为它似乎在 00:00 UTC 使用 dd/mm/yyyy 保存+0),所以如果我将生日设置为 2015 年 7 月 10 日,它将保存 2015 年 6 月 10 日。 我什至不明白为什么 LocalDate 甚至可以节省一个小时。我使用 LocalDate 是有原因的,而不是 LocalDateTime。我只想要日期,但时代一直在追赶我!

我是 UTC+2(但我认为存储 UTC+2 没有意义,因为下周我们将是 UTC+1),所以我认为它将是 ZoneId.of("Europe/Madrid ") (我想它会在时区改变时自动改变小时)。

我希望你能帮助我! (对不起我的英语,它并不完美)。谢谢!

【问题讨论】:

  • 你能显示你的示例输入字符串String fnac
  • 而且您的数据库可能位于不同的时区
  • 您是否考虑过将日期作为字符串以您想要的格式存储在数据库中。这样您就不必担心时区。

标签: java spring date java-time localdate


【解决方案1】:

由于您不需要时间,因此您需要使用唯一的 LocalDate

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

无需为此使用 ZonedDateTime。希望这会有所帮助。

【讨论】:

  • Answer by Ole V.V. 已经涵盖了这一点。而且该答案做得更简洁,因为不需要定义格式模式,如您的答案中所示。
【解决方案2】:

我不得不在 application.properties 中更改这一行

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

到这一行:

spring.datasource.url=jdbc:mysql://localhost:3306/............&serverTimezone=欧洲/马德里

我之前尝试过使用 UTC+2,但它不存在

更改该配置和 Ole V.V. 的答案为我工作

谢谢!

【讨论】:

    【解决方案3】:

    LocalDate.parse

    这比你想象的要容易得多。

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

    我正在利用您的字符串采用 ISO 8601 格式的事实,这是 java.time 类的默认格式,现代 Java 日期和时间 API。所以LocalDate 会在没有任何显式格式化程序的情况下解析这种格式,并从其toString 方法中返回它。

    忘记关于旧的DateSimpleDateFormat 类的一切。 java.time 可以为你做这一切。也不必担心时区,因为LocalDate 没有任何时区。如果日期被错误地保存到数据库中,那么软件中的某处存在错误,或者您需要进行配置/设置。

    链接: Wikipedia article: ISO 8601

    【讨论】:

    • 它正在存储前一天。如果我更改数据库字段(DATE 到 DATATIME),它将存储为前一天,00.00 h。我不明白为什么,也找不到错误:S 这就是我一直在寻找使用时区的原因。我对 Date 没有任何问题,但正如每个人都说要使用 LocalDate...我改变了它:/
    • 这很明显是某个地方的时区问题。您无法在您的 Java 类中解决它(或者如果您要解决它,您可以添加 1 天,但这将是您不想要的非常糟糕的 hack,而且很可能会给您带来其他问题)。
    • 现在我已经更改了 spring.datasource.url=.......&serverTimezone=Europe/Madrid application.properties 我试图更改该值设置“UTC+2”,但它无法识别它,我不知道该写什么,lol 在更改之前,它是UTC。我不明白为什么 UTC 会将日期存储为前一天。欧洲/马德里是 UTC+2,现在是下午 15:50。好吧,我有点明白为什么,但似乎太复杂了。谢谢!
    【解决方案4】:

    您当前使用的数据库没有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 中没有存储时间,时区仍存储在日期中。这基本上就是你的转换正在做的事情。

    解决时区问题的最简单方法是将日期存储为所需格式的字符串,然后根据需要进行转换。无论您的服务器位于哪个时区以及您所在的位置,这都是一致的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-14
      • 2017-09-09
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多