在 Java 中操作日期和时间戳的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/87676/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the best way to manipulate Dates and Timestamps in Java?
提问by Joe Dean
Every time I need to work with date and/or timstamps in Java I always feel like I'm doing something wrong and spend endless hours trying to find a better way of working with the APIs without having to code my own Date and Time utility classes. Here's a couple of annoying things I just ran into:
每次我需要在 Java 中使用日期和/或时间戳时,我总是觉得我做错了什么,并花费无数时间试图找到一种更好的 API 工作方式,而无需编写我自己的日期和时间实用程序类. 这是我刚刚遇到的一些烦人的事情:
0-based months. I realize that best practice is to use Calendar.SEPTEMBER instead of 8, but it's annoying that 8 represents September and not August.
Getting a date without a timestamp. I always need the utility that Zeros out the timestamp portion of the date.
I know there's other issues I've had in the past, but can't recall. Feel free to add more in your responses.
基于 0 的月份。我意识到最佳实践是使用 Calendar.SEPTEMBER 而不是 8,但令人讨厌的是 8 代表九月而不是八月。
获取没有时间戳的日期。我总是需要将日期的时间戳部分归零的实用程序。
我知道我过去遇到过其他问题,但想不起来了。请随意在您的回复中添加更多内容。
So, my question is ... What third party APIs do you use to simplify Java's usage of Date and Time manipulation, if any? Any thoughts on using Joda? Anyone looked closer at JSR-310 Date and Time API?
所以,我的问题是……如果有的话,您使用哪些第三方 API 来简化 Java 对日期和时间操作的使用?关于使用Joda 的任何想法?有人仔细研究过 JSR-310 日期和时间 API 吗?
采纳答案by Rich Adams
This posthas a good discussion on comparing the Java Date/Time API vs JODA.
这篇文章很好地讨论了 Java 日期/时间 API 与 JODA 的比较。
I personally just use Gregorian Calendarand SimpleDateFormatany time I need to manipulate dates/times in Java. I've never really had any problems in using the Java API and find it quite easy to use, so have not really looked into any alternatives.
我个人只是在需要在 Java 中操作日期/时间时使用公历和SimpleDateFormat。我在使用 Java API 时从来没有真正遇到过任何问题,并且发现它很容易使用,所以还没有真正研究过任何替代方案。
回答by Basil Bourque
java.time
时间
Java 8 and later now includes the java.timeframework. Inspired by Joda-Time, defined by JSR 310, extended by the ThreeTen-Extraproject. See the Tutorial.
Java 8 及更高版本现在包含java.time框架。受Joda-Time 的启发,由JSR 310定义,由ThreeTen-Extra项目扩展。请参阅教程。
This framework supplants the old java.util.Date/.Calendar classes. Conversion methods let you convert back and forth to work with old code not yet updated for the java.time types.
这个框架取代了旧的 java.util.Date/.Calendar 类。转换方法允许您来回转换以使用尚未针对 java.time 类型更新的旧代码。
The core classes are:
核心类是:
Instant
A moment on the timeline, always in UTC.ZoneId
A time zone. The subclassZoneOffsetincludes a constant for UTC.ZonedDateTime=Instant+ZoneId
Represents a moment on the timeline adjusted into a specific time zone.
Instant
时间线上的一个时刻,总是在UTC。ZoneId
一个时区。该子类ZoneOffset包括一个 UTC 常量。ZonedDateTime=Instant+ZoneId
表示时间轴上调整到特定时区的时刻。
This framework solves the couple of problems you listed.
该框架解决了您列出的几个问题。
0-based months
从 0 开始的月份
Month numbers are 1-12 in java.time.
java.time 中的月份数字是 1-12。
Even better, an Enum(Month) provides an object instance for each month of the year. So you need not depend on "magic" numbers in your code like 9or 10.
更好的是,一个Enum( Month) 为一年中的每个月提供了一个对象实例。因此,您无需依赖代码中的“神奇”数字,例如9或10。
if ( theMonth.equals ( Month.OCTOBER ) ) { …
Furthermore, that enum includes some handy utility methods such as getting a month's localized name.
此外,该枚举包括一些方便的实用方法,例如获取月份的本地化名称。
If not yet familiar with Java enums, read the Tutorialand study up. They are surprisingly handy and powerful.
如果还不熟悉 Java 枚举,请阅读教程并学习。它们非常方便和强大。
A date without a time
没有时间的约会
The LocalDateclass represents a date-only value, without time-of-day, without time zone.
该LocalDate级表示日期,只值,没有时间的天,没有时区。
LocalDate localDate = LocalDate.parse( "2015-01-02" );
Note that determining a date requires a time zone. A new day dawns earlier in Paris than in Montréal where it is still ‘yesterday'. The ZoneIdclass represents a time zone.
请注意,确定日期需要时区。新的一天在巴黎比在蒙特利尔更早开始,那里仍然是“昨天”。本ZoneId类代表一个时区。
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
Similarly, there is a LocalTimeclass for a time-of-day not yet tied to a date or time zone.
类似地,有一个LocalTime尚未与日期或时区相关联的时间类。
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use ThreeTenABP….
- Java SE 8、Java SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。
回答by Michael
The Apache Commons Lang project has a DateUtilsclass that performs helpful Date operations.
Apache Commons Lang 项目有一个DateUtils执行有用的日期操作的类。
I use DateUtils.truncate()a lot, which will "zero out" parts of the Date for you (helpful if you want your Date object to, say, represent a date and not include any time information). Each method works for both Dateand Calendarobjects too.
我使用DateUtils.truncate()了很多,它将为您“清零”日期的部分(如果您希望 Date 对象表示日期而不包含任何时间信息,则很有帮助)。每种方法也适用于Date和Calendar对象。
回答by Patrick Wilkes
I've been using Joda exclusively for three years now and would definitely recommend it - it has the whole area covered with an interface that 'does what it says'.
我已经专门使用 Joda 三年了,我肯定会推荐它——它的整个区域都覆盖了一个界面,“按照它说的做”。
Joda can look complex when you start, as eg it has concepts of periods, duration and intervals which look sort of similar, but you can start off simply by substituting org.joda.time.DateTime(or org.joda.time.DateMidnight) for java.util.Datein your code, and sticking with the many useful methods that those classes contain, before understanding the other areas.
Joda 在您开始时可能看起来很复杂,因为例如它具有看起来有点相似的周期、持续时间和间隔的概念,但是您可以通过在代码中简单地替换org.joda.time.DateTime(或org.joda.time.DateMidnight)来开始java.util.Date,并坚持使用许多有用的方法类包含,在了解其他领域之前。
回答by Thomas Eyde
It's the same in javascript. Someone must have been smoking something when they think it's a good idea to let 2008 mean the year 2008, 31 to mean the 31st day in the month, and - this is the best part - 11 to mean the 12th month.
在 javascript 中也是如此。当有人认为让 2008 表示 2008 年、让 31 表示该月的第 31 天是一个好主意时,他们一定是在抽烟,并且 - 这是最好的部分 - 11 表示第 12 个月。
On the other hand, they got it right on two out of three.
另一方面,他们在三分之二的情况下做对了。
回答by LizB
The thing that always gets me with Java is the date time library. I've never used Joda, just briefly look at it, looks like its a pretty good implementation, and if I understand JSR-130 correctly its taking knowledge from Joda and eventually having it included in JavaSE.
总是让我使用 Java 的是日期时间库。我从未使用过 Joda,只是简单地看了一下,它看起来是一个非常好的实现,如果我正确理解 JSR-130,它会从 Joda 获取知识并最终将其包含在 JavaSE 中。
Quite often for past projects I've wrapped the Java date time objects, which in itself was quite a task. Then used the wrappers for date manipulation.
对于过去的项目,我经常包装 Java 日期时间对象,这本身就是一项艰巨的任务。然后使用包装器进行日期操作。
回答by Vugluskr
Im using GregorianCalendar - always and everywhere. Simple java.util.Date is too complex, yeah.
我使用 GregorianCalendar - 随时随地。简单的 java.util.Date 太复杂了,是的。
So, my advice is - use GC, its simple
所以,我的建议是 - 使用 GC,它很简单
回答by Vugluskr
A lot of programmers begin by using Date, which has numerous deprecated overloaded constructors (making it difficult to use), but once you figure out GregorianCalendar it becomes a little bit easier to manage. The example here is pretty helpful:
许多程序员从使用 Date 开始,它有许多已弃用的重载构造函数(使其难以使用),但是一旦您弄清楚 GregorianCalendar,它就会变得更容易管理。这里的例子很有帮助:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html
http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html
回答by Daniel Spiewak
Date APIs are very difficult to design, especially if they have to deal with localization. Try to roll your own and see, it's worth doing at least once. The fact that Joda was able to do such a good job is a real credit to its developers. To answer your question, I've heard nothing but good things about that library, though I have never played around with it myself.
日期 API 非常难以设计,尤其是当它们必须处理本地化时。尝试自己动手看看,至少值得做一次。Joda 能够完成如此出色的工作,这是对其开发人员的真正功劳。为了回答您的问题,我只听说过有关该库的好消息,尽管我自己从未玩过它。
回答by oxbow_lakes
It's really simple to write your own date API which sits on top of the raw Java classes, Date and Calendar. Basically both date and Calendar suffer from the fact that they are trying to cram two concepts into one class:
编写自己的日期 API 非常简单,它位于原始 Java 类 Date 和 Calendar 之上。基本上日期和日历都受到这样一个事实的影响:他们试图将两个概念塞进一个类中:
- Date (i.e. Year-Month-Day)
- Instant (i.e. currentTimeMillis)
- 日期(即年-月-日)
- 即时(即 currentTimeMillis)
When you understand this, it will just revolutionize how you handle date-like concepts in your code. Things will be simpler, clearer, better. In every sense!
当您理解这一点时,它将彻底改变您在代码中处理类似日期的概念的方式。事情会更简单、更清晰、更好。各种意义上!
For me, Joda is over-complicated, at least for the overwhelming majority of purposes and I particularly don't like the fact that they have gone against standard Java forms, one example being how they parse and format dates. Stephen Colebourne, the guy behind JODA, is the spec lead of JSR-310 and this suffers from the same problems imho (I've followed and contributed to the discussions for the last few years).
对我来说,Joda 过于复杂,至少对于绝大多数用途而言,我特别不喜欢它们与标准 Java 形式背道而驰的事实,其中一个例子是它们如何解析和格式化日期。JODA 背后的人 Stephen Colebourne 是 JSR-310 的规范负责人,恕我直言,这也遇到了同样的问题(我一直关注并参与了过去几年的讨论)。
Do it yourself; it's easy. Just fill in the following classes: MyDate (wrapping year-month-day), Month (an enum), TimeOfDay (hour-min-sec-millis), DayOfWeek (enum), Instant (wrapping a long). Always consider time-zones when converting between Instants and Dates.
自己做; 这简单。只需填写以下类:MyDate(包装年-月-日)、Month(一个枚举)、TimeOfDay(时-分-秒-毫秒)、DayOfWeek(枚举)、Instant(一个长的包装)。在 Instants 和 Dates 之间转换时,请始终考虑时区。
If this seems daunting, you can use Calendar and SimpleDateFormat under the hood. You'll do this in a day and never regret it.
如果这看起来令人生畏,您可以在幕后使用 Calendar 和 SimpleDateFormat。你会在一天内做到这一点,永远不会后悔。


