为什么我不应该使用 date4j 而不是 joda java.util.Calendar 或 jsr 310?

发布于 2024-12-01 07:50:09 字数 1631 浏览 1 评论 0原文

我最近遇到了 date4j,一个非常简单的库(本质上是一个类),用于使用Java 中的日期。从概念上讲,我真的很喜欢 date4j 的“想法”。事实上,在阅读了整个主站点和 javadoc 中的文档之后,我非常同意所述的所有内容。

现在,可能有几个原因导致我不应该使用 date4j - bug、性能、缺乏用户等等。我不是在问这些事情。我问的是,从概念上讲,date4j 的想法(对于大多数应用程序来说)有什么问题?当然,可能有一些应用程序需要像 joda 或 Threeten 这样的东西 - 但我相信这些应用程序只是少数。

人们给处理日期/时间的用户(几乎每个编写 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);

这表示时间的“即时”,而与时区无关。这次您应该能够在数据库中持久保存数据,而不必担心发生任何类型的“转换”。如果数据库位于上海时区而网络服务器位于洛杉矶时区,则无关紧要 - 无论如何,时间都是相同的。

一个问题是某些数据库尝试为您管理时区(我正在看着您,Postgres!grr!),并且使情况变得更糟 JDBC 驱动程序级别的行为是特定于供应商的 - 即PreparedStatement.setDate/getDate。

date4j 使用的心理模型似乎摆脱了所有的混乱。例如,在调用 now() 时显式强制使用提供时区。网站上有一些关于使用该库的非常好的建议(这些事情我之前已经在自己的应用程序中做过),例如:

  • 不要使用尝试管理时区的数据库类型,
  • 将时区存储为单独的列(如果需要)

为什么没有更多的人采用像 date4j 这样的库?

I recently came across date4j, an extremely simple library (essentially a single class) for working with dates in Java. Conceptually, I really like the "idea" of date4j. In fact, after reading both the entire main site and the documentation in the javadoc, I pretty much agree with everything stated.

Now, there may be several reasons why I shouldn't use date4j - bugs, performance, lack of users, etc. I'm not asking about those things. I'm asking, conceptually, what's wrong with the idea of date4j (for the majority of the applications out there)? Surely, there may be some applications which need something like joda or threeten - but I believe those to be in the minority.

The normal advice people give to users dealing with dates/times (pretty much everyone writing an java app) is something along the lines of:

  • Use joda-time instead of java.util.Calendar
  • Set your web server to UTC
  • Set your database server to UTC
  • Store your date-time's in UTC

In fact, the last three bullet points illustrate the problems with the current mental model people have when working with dates. People try to manage timezones at both the application and database level (not to mention ORM frameworks add another layer of abstraction which complicates things further).

You should not have to do those things. If you're using java.util.Calendar, for instance, and you are manipulating a time in some user defined timezone:

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);

This represents an "instant" in time regardless of timezone. You should be able to persist this time to and from the database without worrying about any sort of "conversions" happening. It shouldn't matter if the database is in Shanghai timezone and the webserver is in Los Angeles time zone - the instant in time is the same regardless.

One problem is some databases attempt to manage timezones for you (I'm looking at you, Postgres! grr!) and to make it worse the behavior at the JDBC driver level is vendor specific - i.e. PreparedStatement.setDate/getDate.

The mental model that date4j uses seems to get rid of all the confusion. For example, explicitly forcing uses to provide a timezone when calling now(). There's some very good recommendations on the site for using the library (these things I was already doing in my own app previously) such as:

  • don't use a database type which attempts to manage timezones
  • store timezone as a separate column (if required)

Why aren't more people adopting a library like date4j?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玉环 2024-12-08 07:50:09

直到现在我才看过 date4j,但我通读了文档,我有一个具体的问题,以及关于它有什么问题的一种看法。

第一,具体问题。它不在内部维护时区。因此,夏令时存在模糊性。考虑星期日的过渡,即上午 1:59:59(美国东部夏令时间)变为凌晨 1:00:00(美国东部时间)。显然,在那天,说 1:30am 是有歧义的。这种情况发生了两次。所以下面的说法是有歧义的

new DateTime("2011-11-06 01:30:00")

第二,我的看法。 Date 的问题是它没有维护时区。当日历出现时,损害已经造成。此外,日历本身的可变性并没有给自己带来任何好处。但从本质上讲,解决方案必须不仅包括时刻,还包括感知它的地方——时区、文化、地点之类的东西。然后,这些需要在持久化到数据库、序列化、通信等时进行维护。同样的个人原则让我谦虚地建议,即使 xsd:dateTime 也不够,因为它只是允许相对于 UTC 表达日期+时间,但它没有提供是否遵守夏令时等规定。

I've never looked at date4j until now, but I read through the documentation, and I have one concrete problem, and one opinion about what is wrong with it.

First, the concrete problem. It does not maintain Timezone internally. So there is ambiguity about daylight saving. Consider the transition Sunday when 1:59:59am (EDT) becomes 1:00:00am (EST). Clearly, in that day, saying 1:30am is ambiguous. That time happens twice. So the following is ambiguous

new DateTime("2011-11-06 01:30:00")

Second, my opinion. The problem with Date was that it didn't maintain Timezone. By the time Calendar came along, the damage was done. Furthermore, Calendar itself didn't do itself any favors by being mutable. But at the heart, the solution has to include not just moment, but where it was perceived -- timezone, culture, locale sort of stuff. These then need to be maintained alongside the moment when persisted to database, serialized, communicated, whatever. This same personal principle makes me humbly suggest that even xsd:dateTime falls short because it simply allows a date+time to be expressed relative to UTC, it has no provisions to supply whether, for example, daylight saving was being observed.

凉城已无爱 2024-12-08 07:50:09

四年后,我又遇到了这个问题。对我来说,date4j 的第一个问题是 bug。我知道你没有特别问过这些,但这是一个大问题。

更具体地说,错误本身并不是问题,而是完全缺乏某种错误报告系统,这让我对 date4j 感到困扰。据我所知,甚至没有邮件列表,什么也没有。我知道这对于讨论日期/时间 API 应该是什么样子来说可能不是很有趣,但是基础设施仍然很重要。

缺乏一个库很可能是库没有被广泛采用的一个原因。

It's four years later and I've come across this question. For me, the problem #1 with date4j is bugs. I know you specifically didn't ask about those, but it is a major problem.

More specifically, the bugs themselves aren't a problem on their own, it's the complete absence of some kind of bug reporting system that bothers me about date4j. There's not even a mailing list, as far as I know, there isn't anything at all. I know this probably isn't very interesting for a discussion about what date/time API should be like, but still, infrastructure is important.

Lacking one may very well be a reason why a library is not adopted widely.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文