每当我需要使用Java中的日期和/或时间戳时,我总是觉得我做错了什么并花费无数个小时试图找到一种更好的API工作方式,而无需编写我自己的日期和时间实用程序类。这是我刚遇到的一些烦人的事情:
0个月。我意识到最佳做法是使用Calendar.SEPTEMBER而不是8,但令人讨厌的是8代表9月而不是8月。
获取没有时间戳的日期。我总是需要将该日期的时间戳部分归零的实用程序。
我知道我过去还有其他问题,但不记得了。您可以随意在回复中添加更多内容。
所以,我的问题是......你使用什么第三方API来简化Java对日期和时间操作的使用,如果有的话?有关使用Joda的任何想法?有人仔细观察JSR-310 Date and Time API吗?
答案 0 :(得分:10)
This post对比较Java Date / Time API和JODA进行了很好的讨论。
我个人只需要在Java中操作日期/时间时使用Gregorian Calendar和SimpleDateFormat。我从来没有在使用Java API时遇到任何问题,并且发现它很容易使用,所以没有真正研究过任何替代方案。
答案 1 :(得分:5)
Java 8及更高版本现在包含java.time框架。灵感来自Joda-Time,由JSR 310定义,由ThreeTen-Extra项目扩展。请参阅the Tutorial。
此框架取代了旧的java.util.Date/.Calendar类。转换方法允许您来回转换以使用尚未针对java.time类型更新的旧代码。
核心课程是:
Instant
ZoneId
ZoneOffset
包括a constant for UTC。ZonedDateTime
= Instant
+ ZoneId
此框架解决了您列出的几个问题。
基于0的月份java.time中的月份数为1-12。
更好的是,Enum
(Month
)为一年中的每个月提供一个对象实例。因此,您无需依赖代码中的“魔术”数字,例如9
或10
。
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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:3)
Apache Commons Lang项目有一个DateUtils
类,可以执行有用的日期操作。
我经常使用DateUtils.truncate()
,这将为你“归零”Date的部分(如果你想让你的Date对象代表一个日期并且不包含任何时间信息,则会很有帮助)。每种方法也适用于Date
和Calendar
个对象。
答案 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类,日期和日历之上。基本上日期和日历都受到这样一个事实的影响:他们试图将两个概念塞进一个类中:
当您理解这一点时,它将彻底改变您在代码中处理类似日期的概念的方式。事情会更简单,更清晰,更好。无论如何!
对我而言,Joda过于复杂,至少在绝大多数目的中都是如此,我特别不喜欢他们违反标准Java表单的事实,例如他们如何解析和格式化日期。 JODA背后的人物Stephen Colebourne是JSR-310的规范负责人,这也是同样的问题(我跟随并为过去几年的讨论做出了贡献)。
自己动手;这很简单。只需填写以下类:MyDate(包装年 - 月 - 日),月(枚举),TimeOfDay(小时 - 分 - 秒 - 毫秒),DayOfWeek(枚举),Instant(包装长)。在Instants和Dates之间转换时始终考虑时区。
如果这看起来令人生畏,您可以使用Calendar和SimpleDateFormat。你会在一天内完成这件事而不会后悔。