Answer by Albe 在我看来是正确的。以下是我的一些进一步的想法。
我希望我的应用程序为 event expired = true 设置一个标志。
正如 Albe 所提到的,没有必要记录这个过期的事实。只需按日期查询即可查找日期之前(过期)或日期之后(未过期)的记录。
如果性能是一个问题,请进行测试以验证。如果有问题,请考虑为日期列编制索引。
如何处理时区?
这就是诀窍。我将在这里简要介绍一下,因为这已经在这里和姊妹网站https://dba.stackexchange.com 上处理了很多次。
首先,弄清楚您的业务需求是否需要日期或时刻的粒度。正如你直觉的那样,日期是不精确的。对于任何给定的时刻,日期在全球范围内因时区而异。法国巴黎午夜过后几分钟是新的一天,而魁北克蒙特利尔仍是“昨天”。
如果您关心时刻,请使用类似于 SQL 标准 TIMESTAMP WITH TIME ZONE 的类型的列。了解 SQL 标准几乎不涉及日期时间处理的主题。因此,不同数据库系统中的行为差异很大。在 Postgres 中,该列中的值始终为 UTC。与输入一起提供的任何时区或与 UTC 的偏移信息都用于调整为 UTC,然后被丢弃。因此,如果您关心原始区域/偏移量,则必须手动将其存储在附加列中。
检索时,该列的值始终采用 UTC。但是,您使用的访问工具可能会注入其关于如何呈现该值的意见。一些工具会动态应用时区。我发现这种行为是一个不幸的设计选择。尽管出于善意,但这种行为会造成该区域是存储数据的一部分的错觉。
在 Java 中,只使用现代的 java.time 类,而不是与最早的 Java 版本捆绑在一起的非常麻烦和有缺陷的旧日期时间类。
从 JDBC 4.2 开始,您可以使用 PreparedStatement::setObject 和 ResultSet::getObject 直接与数据库交换 java.time 对象。
我的服务器位于欧洲
服务器的位置以及服务器操作系统和 JVM 的当前默认时区应该与您的编程和数据库工作无关。永远不要依赖这些默认设置,因为它们超出您的控制范围,并且可以在运行时随时更改。
相反,请始终明确指定您想要/预期的时区。通常,您的大部分工作都应该使用 UTC。仅在业务规则需要或向用户展示时才调整到时区。
LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
通过提取Instant 调整回UTC。 Instant 是您应该与数据库交换的内容。
Instant instant = zdt.toInstant() ;
调整回一个区域。
ZonedDateTime zdtAuckland = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ; // Same moment, same point on the timeline, different wall-clock time.
要查询时刻,请搜索 Stack Overflow 以了解半开放方法,其中定义了一个时间跨度,其中开始包含,而结束不包含时间>。这意味着您不使用 SQL 运算符 BETWEEN。例如,请参阅this。
提示:使用具有site:stackoverflow.com 标准的搜索引擎搜索这些类名称和概念。不幸的是,Stack Overflow 内置的搜索功能偏向于问题,而忽略了答案。例如:https://duckduckgo.com/?q=site%3Astackoverflow.com+%2B%22Half-Open%22+%2Bjava&t=osx&ia=web
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。