使用带有 UTC 的 localDate

问题描述 投票:0回答:2

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

发生的情况是,我们在 UTC 午夜计费(在进行诸如 billingDate 之类的比较时 <= LocalDate.now()). We actually mean to bill sometime after midnight PST.

我真的觉得在这里使用 LocalDate 是合适的,因为我们只想在当天的某个时间点计费。 然而,直接在代码中或在数据库中进行比较时似乎并不实用(billing_date <= CURRENT_DATE()). Did I make a mistake, should this be a ZonedDateTime in PST? Or should we be converting to ZonedDateTime for comparisons? It feels error prone, we need to remember to convert any time we do a comparision, but perhaps this is the correct solution?

有人有过这种情况的经验并找到了很好的解决方案吗?

我已经看过这个问题,但它没有回答我的问题:Spring REST LocalDate UTC 相差一天

java timezone utc java-time localdate
2个回答
4
投票

指定时区

我建议这只是将所需时区传递给

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
    包含时区,因此它也可以为您提供该指定时区的当前日期和/或时间。
  3. 不接受任何参数并使用 JVM 当前的默认时区。我建议您永远不要使用它。很高兴让读者知道您已经考虑了时区并选择了您想要的时区。并且默认时区可以被同一 JVM 中运行的任何程序随时更改,因此不够稳定,无法依赖于实际工作。

3
投票

我觉得你应该使用

Instant
s。

我真的觉得在这里使用 LocalDate 是合适的,因为我们只想在当天的某个时间点计费。

嗯,不。您确实关心您计费的时间,因为您的数据库关心时间。它将计费时间存储为 00:00 UTC。因为那是一个瞬间,我认为

Instant
将是这里最合适的选择。您也可以使用
ZonedDateTime
,但考虑到您可能从数据库中获取
java.sql.Date
,数据库已经有
toInstant
方法,使用
Instant
s 更方便。

您可以像这样获得年、月、日的瞬间:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.