将 localDate 与 UTC 一起使用

Using localDate with UTC

我在使用 UTC 中的 LocalDate 时遇到问题。我的服务器使用 UTC,我的数据库使用 UTC。我使用 LocalDate 为基于订阅的应用程序存储 billingDate。

发生的情况是我们在午夜 UTC 计费(当进行像 billingDate <= LocalDate.now() 这样的比较时)。我们实际上是想在太平洋标准时间午夜后的某个时间结算。

我真的觉得在这里使用 LocalDate 是合适的,因为我们只想在当天的某个时间点计费。但是,直接在代码或数据库中进行比较时似乎并不实用 (billing_date <= CURRENT_DATE())。我弄错了吗,这应该是 PST 中的 ZonedDateTime 吗?或者我们应该转换为 ZonedDateTime 进行比较?感觉容易出错,我们需要记住每次进行比较时都要转换,但也许这是正确的解决方案?

有没有人遇到过这种情况并找到了好的解决方案?

我看过这个问题,但它没有回答我的问题:Spring REST LocalDate UTC differs of one day

我觉得你应该使用 Instants。

I really felt like using LocalDate was appropriate here, because we just want to bill at some point during that day.

嗯,不。您确实关心您的计费时间,因为您的数据库关心时间。它将计费时间存储为 00:00 UTC。因为那是一个瞬间,所以我认为Instant在这里是最合适的选择。您也可以使用 ZonedDateTime,但考虑到您可能从数据库中获取 java.sql.Date,它已经有 toInstant 方法,使用 Instants 更方便.

您可以像这样从年月日中获取瞬间:

LocalDate ld = LocalDate.of(2019, 7, 8);
Instant i = ld.atStartOfDay(ZoneId.of("America/Los_Angeles")).toInstant();

America/Los_Angeles 是太平洋标准时间。

我建议这只是将所需时区传递给 LocalDate.now(ZoneId) 的问题。

  • 菲律宾标准时间使用LocalDate.now(ZoneId.of("Asia/Manila"))。目前它产生 2019-07-09.
  • 皮特凯恩标准时间使用 LocalDate.now(ZoneId.of("Pacific/Pitcairn"))。刚刚给了2019-07-08.

我假设您指的不是太平洋标准时间,因为在我们说话时没有时区使用太平洋标准时间(那些在冬天使用的时区现在是太平洋夏令时)。无论如何,请注意三个字母的时区缩写通常是模棱两可的。

具有now方法的java.time类通常具有三个重载变体:

  1. 采用我推荐的 ZoneId 个参数供一般使用。
  2. 一个采用 Clock 参数的方法非常适合可测试性。 Clock 包括一个时区,所以这个也能为您提供指定时区的当前日期 and/or 时间。
  3. 一个不接受任何参数并使用 JVM 的默认时区。我建议您永远不要使用它。很高兴 reader 知道您已经考虑了时区并选择了您想要的时区。并且默认时区可以由同一 JVM 中的任何程序随时更改 运行,因此不够稳定以依赖于实际工作。