Java 日期与日历
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1404210/
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
Java Date vs Calendar
提问by Marty Pitt
Could someone please advise the current "best practice" around Date
and Calendar
types.
有人可以建议当前的“最佳实践”Date
和Calendar
类型。
When writing new code, is it best to always favour Calendar
over Date
, or are there circumstances where Date
is the more appropriate datatype?
当编写新的代码,它是最好的总是青睐Calendar
过Date
,还是有地方的情况Date
是比较合适的数据类型?
采纳答案by cletus
Date is a simpler class and is mainly there for backward compatibility reasons. If you need to set particular dates or do date arithmetic, use a Calendar. Calendars also handle localization. The previous date manipulation functions of Date have since been deprecated.
Date 是一个更简单的类,主要是出于向后兼容的原因。如果您需要设置特定日期或进行日期算术,请使用日历。日历还处理本地化。Date 之前的日期操作功能已被弃用。
Personally I tend to use either time in milliseconds as a long (or Long, as appropriate) or Calendar when there is a choice.
就我个人而言,当有选择时,我倾向于使用以毫秒为单位的时间作为长(或长,视情况而定)或日历。
Both Date and Calendar are mutable, which tends to present issues when using either in an API.
Date 和 Calendar 都是可变的,这在 API 中使用时往往会出现问题。
回答by KLE
Date is best for storing a date object. It is the persisted one, the Serialized one ...
日期最适合存储日期对象。它是持久化的,序列化的......
Calendar is best for manipulating Dates.
日历最适合操作日期。
Note: we also sometimes favor java.lang.Long over Date, because Date is mutable and therefore not thread-safe. On a Date object, use setTime() and getTime() to switch between the two. For example, a constant Date in the application (examples: the zero 1970/01/01, or an applicative END_OF_TIME that you set to 2099/12/31 ; those are very useful to replace null values as start time and end time, especially when you persist them in the database, as SQL is so peculiar with nulls).
注意:我们有时也喜欢 java.lang.Long 而不是 Date,因为 Date 是可变的,因此不是线程安全的。在 Date 对象上,使用 setTime() 和 getTime() 在两者之间切换。例如,应用程序中的常量 Date(例如:零 1970/01/01,或您设置为 2099/12/31 的应用 END_OF_TIME ;这些对于将空值替换为开始时间和结束时间非常有用,尤其是当您将它们持久化到数据库中时,因为 SQL 对空值如此奇特)。
回答by dmeister
The best way for new code (if your policy allows third-party code) is to use the Joda Time library.
新代码的最佳方法(如果您的策略允许第三方代码)是使用Joda Time 库。
Both, Dateand Calendar, have so many design problems that neither are good solutions for new code.
回答by oxbow_lakes
Date
andCalendar
are really the same fundamental concept (both represent an instant in timeand are wrappers around an underlyinglong
value).One could argue that
Calendar
is actually even more broken thanDate
is, as it seems to offer concrete facts about things like day of the week and time of day, whereas if you change itstimeZone
property, the concrete turns into blancmange! Neither objects are really useful as a store of year-month-dayor time-of-dayfor this reason.Use
Calendar
only as a calculator which, when givenDate
andTimeZone
objects, will do calculations for you. Avoid its use for property typing in an application.Use
SimpleDateFormat
together withTimeZone
andDate
to generate display Strings.If you're feeling adventurous use Joda-Time, although it is unnecessarily complicated IMHO and is soon to be superceded by the JSR-310 date API in any event.
I have answered before that it is not difficult to roll your own
YearMonthDay
class, which usesCalendar
under the hood for date calculations. I was downvoted for the suggestion but I still believe it is a valid one because Joda-Time(and JSR-310) are really so over-complicated for most use-cases.
Date
并且Calendar
实际上是相同的基本概念(两者都代表时间中的瞬间并且是潜在long
价值的包装器)。有人可能会争辩说,
Calendar
它实际上比Date
现在更破碎,因为它似乎提供了关于星期几和一天中的时间之类的具体事实,而如果你改变它的timeZone
属性,混凝土就会变成 blancmange!由于这个原因,这两个对象都不能真正用作存储年月日或一天中的时间。使用
Calendar
仅作为一个计算器其中,由于在Date
和TimeZone
对象,会为你做计算。避免将其用于应用程序中的属性类型。使用
SimpleDateFormat
连同TimeZone
和Date
生成显示字符串。如果您喜欢冒险,请使用 Joda-Time,尽管恕我直言,它不必要地复杂化,并且很快就会被 JSR-310 日期 API 取代。
我之前已经回答说,推出自己的
YearMonthDay
课程并不难,它Calendar
在幕后用于日期计算。我对这个建议投了反对票,但我仍然相信这是一个有效的建议,因为Joda-Time(和JSR-310)对于大多数用例来说确实过于复杂。
回答by Brian Agnew
I always advocate Joda-time. Here's why.
我一直提倡Joda-time。这是为什么。
- the API is consistent and intuitive. Unlike the java.util.Date/Calendar APIs
- it doesn't suffer from threading issues, unlike java.text.SimpleDateFormatetc. (I've seen numerous client issues relating to not realising that the standard date/time formatting is not thread-safe)
- it's the basis of the new Java date/time APIs (JSR310, scheduled for Java 8. So you'll be using APIs that will become core Java APIs.
- API 一致且直观。与 java.util.Date/Calendar API 不同
- 与java.text.SimpleDateFormat等不同,它没有线程问题(我已经看到许多与没有意识到标准日期/时间格式不是线程安全的客户端问题有关)
- 它是新 Java 日期/时间 API(JSR310,计划用于 Java 8 的基础。因此,您将使用将成为核心 Java API 的 API。
EDIT: The Java date/time classes introduced with Java 8 are now the preferred solution, if you can migrate to Java 8
编辑:Java 8 中引入的 Java 日期/时间类现在是首选解决方案,如果您可以迁移到 Java 8
回答by Andrzej Doyle
Date
s should be used as immutable points in time; Calendar
s are mutable, and can be passed around and modified if you need to collaborate with other classes to come up with a final date. Consider them analogous to String
and StringBuilder
and you'll understand how I consider they should be used.
Date
s 应该用作不可变的时间点;Calendar
s 是可变的,如果您需要与其他类协作以提出最终日期,则可以传递和修改。将它们与String
and类似StringBuilder
,您就会明白我认为应该如何使用它们。
(And yes, I know Date isn't actually technically immutable, but the intention is that it should not be mutable, and if nothing calls the deprecated methods then it is so.)
(是的,我知道 Date 实际上在技术上并不是一成不变的,但目的是它不应该是可变的,如果没有任何东西调用已弃用的方法,那么它就是这样。)
回答by Archimedes Trajano
I generally use Date if possible. Although it is mutable, the mutators are actually deprecated. In the end it basically wraps a long that would represent the date/time. Conversely, I would use Calendars if I have to manipulate the values.
如果可能,我通常使用 Date。尽管它是可变的,但实际上不推荐使用增变器。最后,它基本上包装了一个代表日期/时间的 long。相反,如果我必须操纵这些值,我会使用日历。
You can think of it this way: you only use StringBuffer only when you need to have Strings that you can easily manipulate and then convert them into Strings using toString() method. In the same way, I only use Calendar if I need to manipulate temporal data.
您可以这样想:仅当您需要拥有可以轻松操作的字符串,然后使用 toString() 方法将它们转换为字符串时,才使用 StringBuffer。同样,如果我需要操作时态数据,我只使用 Calendar。
For best practice, I tend to use immutable objects as much as possible outside of the domain model. It significantly reduces the chances of any side effects and it is done for you by the compiler, rather than a JUnit test. You use this technique by creating private finalfields in your class.
为了最佳实践,我倾向于在域模型之外尽可能多地使用不可变对象。它显着降低了任何副作用的可能性,并且它是由编译器为您完成的,而不是 JUnit 测试。您可以通过在类中创建私有 final字段来使用此技术。
And coming back to the StringBuffer analogy. Here is some code that shows you how to convert between Calendar and Date
回到 StringBuffer 的类比。这是一些代码,向您展示如何在日历和日期之间进行转换
String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String
// immutable date with hard coded format. If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");
// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// mutate the value
cal.add(Calendar.YEAR, 1);
// convert back to Date
Date newDate = cal.getTime();
//
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);
回答by user2835562
Date should be re-developed. Instead of being a long interger, it should hold year, month, date, hour, minute, second, as separate fields. It might be even good to store the calendar and time zone this date is associated with.
日期应该重新开发。它不应是一个长整数,而应将年、月、日、时、分、秒作为单独的字段保存。存储与此日期相关联的日历和时区甚至可能更好。
In our natural conversation, if setup an appointment at Nov. 1, 2013 1pm NY Time, this is a DateTime. It is NOT a Calendar. So we should be able to converse like this in Java as well.
在我们的自然对话中,如果在纽约时间 2013 年 11 月 1 日下午 1 点设置约会,则这是日期时间。它不是日历。所以我们应该也可以在 Java 中进行这样的对话。
When Date is stored as a long integer (of mili seconds since Jan 1 1970 or something), calculating its current date depends on the calendar. Different calendars will give different date. This is from the prospective of giving an absolute time (eg 1 trillion seconds after Big Bang). But often we also need a convenient way of conversation, like an object encapsulating year, month etc.
当 Date 存储为长整数(自 1970 年 1 月 1 日以来的毫秒数)时,计算其当前日期取决于日历。不同的日历会给出不同的日期。这是从给出绝对时间的角度来看的(例如,大爆炸后的 1 万亿秒)。但通常我们也需要一种方便的对话方式,比如封装年、月等的对象。
I wonder if there are new advances in Java to reconcile these 2 objectives. Maybe my java knowledge is too old.
我想知道 Java 是否有新的进步来协调这两个目标。也许我的java知识太老了。
回答by Silviu Burcea
A little bit late at party, but Java has a new Date Time API in JDK 8. You may want to upgrade your JDK version and embrace the standard. No more messy date/calendar, no more 3rd party jars.
聚会有点晚了,但是 Java 在 JDK 8 中有一个新的日期时间 API。您可能想要升级 JDK 版本并接受标准。不再有凌乱的日期/日历,不再有 3rd 方罐子。
回答by xxxvodnikxxx
Btw "date" is usually tagged as "obsolete / deprecated" (I dont know exactly why) - something about it is wrote there Java: Why is the Date constructor deprecated, and what do I use instead?
顺便说一句,“日期”通常被标记为“过时/不推荐使用”(我不知道确切原因) - 那里写了一些关于它的内容 Java:为什么不推荐使用日期构造函数,我应该使用什么?
It looks like it's a problem of the constructor only- way via new Date(int year, int month, int day), recommended way is via Calendar and set params separately .. (Calendar cal = Calendar.getInstance();)
看起来这是构造函数的问题,只能通过new Date(int year, int month, int day) 进行,推荐的方法是通过 Calendar 并单独设置 params .. ( Calendar cal = Calendar.getInstance();)