在Java中操作日期和时间戳的最佳方法是什么?

时间:2008-09-17 21:07:45

标签: java datetime

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

  • 0个月。我意识到最佳做法是使用Calendar.SEPTEMBER而不是8,但令人讨厌的是8代表9月而不是8月。

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

  • 我知道我过去还有其他问题,但不记得了。您可以随意在回复中添加更多内容。

所以,我的问题是......你使用什么第三方API来简化Java对日期和时间操作的使用,如果有的话?有关使用Joda的任何想法?有人仔细观察JSR-310 Date and Time API吗?

10 个答案:

答案 0 :(得分:10)

This post对比较Java Date / Time API和JODA进行了很好的讨论。

我个人只需要在Java中操作日期/时间时使用Gregorian CalendarSimpleDateFormat。我从来没有在使用Java API时遇到任何问题,并且发现它很容易使用,所以没有真正研究过任何替代方案。

答案 1 :(得分:5)

java.time

Java 8及更高版本现在包含java.time框架。灵感来自Joda-Time,由JSR 310定义,由ThreeTen-Extra项目扩展。请参阅the Tutorial

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

核心课程是:

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

基于0的月份

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

更好的是,EnumMonth)为一年中的每个月提供一个对象实例。因此,您无需依赖代码中的“魔术”数字,例如910

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

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

如果还不熟悉Java枚举,请阅读Tutorial并进行学习。它们非常方便和强大。

没有时间的日期

LocalDate类代表一个仅限日期的值,没有时间,没有时区。

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

请注意,确定日期需要时区。新的一天在巴黎早些时候比蒙特利尔还要早,那里仍然是“昨天”。 ZoneId类代表时区。

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

同样地,有一个LocalTime课程,其中一个时间段尚未与日期或时区相关联。

关于java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:3)

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

我经常使用DateUtils.truncate(),这将为你“归零”Date的部分(如果你想让你的Date对象代表一个日期并且不包含任何时间信息,则会很有帮助)。每种方法也适用于DateCalendar个对象。

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

答案 3 :(得分:2)

我已经独自使用Joda三年了,肯定会推荐它 - 它的整个区域都覆盖了一个“做它所说的”界面。

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

在javascript中也一样。当他们认为让2008年意味着2008年,31意味着本月的第31天,并且 - 这是最好的部分 - 11意味着第12个月时,某人肯定已经吸烟了。

另一方面,他们在三分之二中得到了正确的答案。

答案 6 :(得分:1)

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

过去的项目经常包含Java日期时间对象,这本身就是一个非常重要的任务。然后使用包装器进行日期操作。

答案 7 :(得分:0)

日期API很难设计,特别是如果他们必须处理本地化。尝试自己动手看看,至少值得做一次。 Joda能够做得这么好的事实对其开发者来说是一个真正的功劳。为了回答你的问题,我没有听到关于那个图书馆的好消息,尽管我自己从来没有玩过它。

答案 8 :(得分:0)

许多程序员首先使用Date,它有许多已弃用的重载构造函数(使其难以使用),但是一旦你弄清楚GregorianCalendar它就会变得更容易管理。这里的例子非常有用:

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

答案 9 :(得分:0)

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

  1. 日期(即年 - 月 - 日)
  2. 即时(即currentTimeMillis)
  3. 当您理解这一点时,它将彻底改变您在代码中处理类似日期的概念的方式。事情会更简单,更清晰,更好。无论如何!

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

    自己动手;这很简单。只需填写以下类:MyDate(包装年 - 月 - 日),月(枚举),TimeOfDay(小时 - 分 - 秒 - 毫秒),DayOfWeek(枚举),Instant(包装长)。在Instants和Dates之间转换时始终考虑时区。

    如果这看起来令人生畏,您可以使用Calendar和SimpleDateFormat。你会在一天内完成这件事而不会后悔。