为什么我不应该使用date4j而不是joda java.util.Calendar或jsr 310?
我最近遇到了date4j,一个非常简单的库(本质上是一个单一的类),用于在Java中处理日期。从概念上讲,我真的很喜欢date4j的“想法”。事实上,在阅读了整个主站点和javadoc中的文档之后,我非常同意所说的一切。
现在,我不应该使用date4j的原因可能有几个 - 错误,性能,缺乏用户等。我不是在问这些事情。我在问,从概念上讲,date4j的想法有什么问题(对于大多数应用程序来说)?当然,可能有一些应用程序需要像joda或threleten这样的东西 - 但我相信这些是少数。
人们给处理日期/时间的用户(几乎每个人都在编写java应用程序)的正常建议是这样的:
- 使用 joda-time 而不是 java.util.Calendar
- 将 Web 服务器设置为 UTC
- 将数据库服务器设置为 UTC
- 以 UTC 格式存储您的日期时间
事实上,最后三个要点说明了人们在处理约会时遇到的当前心理模型的问题。人们试图在应用程序和数据库级别管理时区(更不用说ORM框架增加了另一个抽象层,这会使事情进一步复杂化)。
你不应该做这些事情。例如,如果您使用的是java.util.Calendar,并且您正在某个用户定义的时区中操作时间:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
c.set(Calendar.YEAR, 2011);
c.set(Calendar.MONTH, 0);
c.set(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY, 3);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
这表示时间上的“瞬间”,无论时区如何。您应该能够将这段时间保留在数据库之间,而不必担心发生任何类型的“转换”。数据库是否在上海时区,而Web服务器在洛杉矶时区并不重要 - 无论如何,时间的瞬间都是一样的。
一个问题是一些数据库试图为你管理时区(我正在看着你,Postgres!grr!),更糟糕的是,JDBC驱动程序级别的行为是特定于供应商的 - 即ReaddStatement.setDate/getDate。
date4j使用的心智模型似乎摆脱了所有的困惑。例如,显式强制使用在调用 now() 时提供时区。网站上有一些关于使用库的非常好的建议(我以前已经在自己的应用程序中做过这些事情),例如:
- 不要使用尝试管理时区的数据库类型
- 将时区存储为单独的列(如果需要)
为什么没有更多的人采用像date4j这样的库?