每次我需要在 Java 中使用日期和/或时间戳时,我总是觉得自己做错了什么,并花费无数时间试图找到更好的方法来使用 API,而无需编写自己的日期和时间实用程序类。这是我刚刚遇到的一些恼人的事情:

  • 从 0 开始的月份。我意识到最佳实践是使用 Calendar.SEPTEMBER 而不是 8,但令人烦恼的是 8 代表 9 月而不是 8 月。

  • 获取没有时间戳的日期。我总是需要将日期的时间戳部分清零的实用程序。

  • 我知道过去还遇到过其他问题,但记不起来了。请随意在您的回复中添加更多内容。

所以,我的问题是...您使用哪些第三方 API 来简化 Java 对日期和时间操作的使用(如果有)?关于使用的任何想法 乔达?有人仔细研究过 JSR-310 日期和时间 API 吗?

有帮助吗?

解决方案

这个帖子 关于 Java 日期/时间 API 与 JODA 的比较进行了很好的讨论。

我个人只是使​​用 公历简单日期格式 任何时候我需要在 Java 中操作日期/时间。我在使用 Java API 时从未遇到过任何问题,并且发现它非常易于使用,因此没有真正研究过任何替代方案。

其他提示

java.time

Java 8 及更高版本现在包括 java.time 框架。灵感来自 乔达时间, , 被定义为 JSR 310, ,扩展为 三十额外 项目。看 教程.

该框架取代了旧的 java.util.Date/.Calendar 类。转换方法允许您来回转换以使用尚未更新的 java.time 类型的旧代码。

核心类是:

该框架解决了您列出的几个问题。

从 0 开始的月份

java.time 中的月份数字为 1-12。

更好的是,一个 Enum (Month) 提供一年中每个月的对象实例。所以你不需要依赖代码中的“神奇”数字,比如 9 或者 10.

if ( theMonth.equals ( Month.OCTOBER ) ) {  …

此外,该枚举还包括一些方便的实用方法,例如获取月份的本地化名称。

如果还不熟悉 Java 枚举,请阅读 教程 并学习。它们非常方便且功能强大。

没有时间的约会

LocalDate 类表示仅日期值,没有时间,没有时区。

LocalDate localDate = LocalDate.parse( "2015-01-02" );

请注意,确定日期需要时区。巴黎的新一天比蒙特利尔的黎明更早,而蒙特利尔的天气仍然是“昨天”。这 ZoneId 类代表一个时区。

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );

同样,有一个 LocalTime 尚未与日期或时区绑定的时间类。


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些课程取代了麻烦的旧课程 遗产 日期时间类,例如 java.util.Date, Calendar, & SimpleDateFormat.

乔达时间 项目,现在在 维护模式, ,建议迁移到 java.time 类。

要了解更多信息,请参阅 甲骨文教程. 。并在 Stack Overflow 上搜索许多示例和解释。规格为 JSR 310.

从哪里获取 java.time 类?

三十额外 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 Interval, YearWeek, YearQuarter, , 和 更多的.

Apache Commons Lang 项目有一个 DateUtils 执行有用的日期操作的类。

我用 DateUtils.truncate() 很多,这将为您将日期的部分“清零”(如果您希望日期对象代表日期而不包含任何时间信息,这会很有帮助)。每种方法都适用 DateCalendar 对象也。

http://commons.apache.org/lang/

我已经专门使用 Joda 三年了,并且肯定会推荐它 - 它的整个区域都覆盖了一个“按其说明操作”的界面。

当你开始时,Joda 可能看起来很复杂,因为它有周期、持续时间和间隔的概念,看起来有点相似,但你可以简单地通过替换来开始 org.joda.time.DateTime (或者 org.joda.time.DateMidnight) 为了 java.util.Date 在您的代码中,并在了解其他领域之前坚持使用这些类包含的许多有用的方法。

我随时随地都在使用 GregorianCalendar。简单的 java.util.Date 太复杂了,是的。

所以,我的建议是 - 使用 GC,它很简单

在 JavaScript 中也是一样的。当某人认为让 2008 表示 2008 年、31 表示该月的第 31 天、以及 - 这是最好的部分 - 11 表示第 12 个月是个好主意时,他们一定是在吸烟。

另一方面,他们三分之二都答对了。

Java 总是让我着迷的是日期时间库。我从未使用过 Joda,只是简单地看了一下,看起来它是一个非常好的实现,如果我正确理解 JSR-130,它会从 Joda 获取知识并最终将其包含在 JavaSE 中。

在过去的项目中,我经常包装 Java 日期时间对象,这本身就是一项艰巨的任务。然后使用包装器进行日期操作。

日期 API 的设计非常困难,特别是如果它们必须处理本地化的话。尝试自己动手,看看,至少值得做一次。Joda 能够做得这么好,这对它的开发者来说是真正的荣誉。为了回答你的问题,我只听说过关于这个库的好消息,尽管我自己从未使用过它。

许多程序员开始使用 Date,它有许多已弃用的重载构造函数(使其难以使用),但是一旦您了解了 GregorianCalendar,它就会变得更容易管理。这里的例子非常有帮助:

http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html

编写自己的日期 API 非常简单,它位于原始 Java 类、日期和日历之上。基本上,日期和日历都受到这样一个事实的困扰:它们试图将两个概念塞进一个类中:

  1. 日期(即年月日)
  2. 即时(即当前时间(毫秒)

当您理解这一点时,它将彻底改变您在代码中处理类似日期的概念的方式。事情会变得更简单、更清晰、更好。从各个意义上来说!

对我来说,Joda 过于复杂,至少对于绝大多数目的来说是这样,而且我特别不喜欢它们违背标准 Java 表单这一事实,一个例子是它们如何解析和格式化日期。Stephen Colebourne,JODA 背后的人,是 JSR-310 的规范负责人,恕我直言,它也遇到了同样的问题(我在过去几年中一直关注并为讨论做出了贡献)。

自己做;这很容易。只需填写以下类别:MyDate(包装年-月-日)、Month(枚举)、TimeOfDay(小时-分钟-秒-毫秒)、DayOfWeek(枚举)、Instant(包装长整型)。在即时和日期之间转换时始终考虑时区。

如果这看起来令人畏惧,您可以在幕后使用 Calendar 和 SimpleDateFormat。您将在一天内完成此操作并且永远不会后悔。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top