有人能建议当前的“最佳实践”围绕日期和日历类型。
在编写新代码时,最好总是使用Calendar而不是Date,还是在某些情况下Date是更合适的数据类型?
有人能建议当前的“最佳实践”围绕日期和日历类型。
在编写新代码时,最好总是使用Calendar而不是Date,还是在某些情况下Date是更合适的数据类型?
当前回答
Date and Calendar are really the same fundamental concept (both represent an instant in time and are wrappers around an underlying long value). One could argue that Calendar is actually even more broken than Date is, as it seems to offer concrete facts about things like day of the week and time of day, whereas if you change its timeZone property, the concrete turns into blancmange! Neither objects are really useful as a store of year-month-day or time-of-day for this reason. Use Calendar only as a calculator which, when given Date and TimeZone objects, will do calculations for you. Avoid its use for property typing in an application. Use SimpleDateFormat together with TimeZone and Date 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 uses Calendar 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.
其他回答
博士tl;
建议当前的“最佳实践”围绕日期和日历 日历比日期更好吗
完全避免这些遗留类。使用java。而是时间类。
在UTC中,暂时使用Instant(现代版的Date) 在特定的时区,使用ZonedDateTime(现代版的GregorianCalendar) 在特定的offset-from-UTC中,使用OffsetDateTime(在遗留类中没有等效内容) 对于时区或偏移量未知的date-time(不是moment),使用LocalDateTime(在遗留类中没有等效内容)
细节
Ortomala Lokni的回答是正确的,建议使用现代java。时间类,而不是麻烦的旧遗留日期-时间类(日期、日历等)。但这个答案暗示了一个错误的等价类(见我对那个答案的评论)。
使用java.time
java。时间类是对传统日期-时间类的巨大改进。旧的类设计很差,令人困惑,而且很麻烦。您应该尽可能避免使用旧的类。但是,当您需要从旧类/新类转换或从旧类/新类转换时,可以通过调用添加到旧类的新方法来实现。
有关转换的更多信息,请参阅我的回答和另一个问题的漂亮图表,将java.util. date转换为什么“java. util. date”。时间”类型?。
搜索Stack Overflow提供了数百个关于使用java.time的示例问题和答案。但这里有一个快速的概要。
即时
用即时获取当前时刻。Instant类表示UTC时间轴上的一个时刻,其分辨率为纳秒(最多为十进制分数的九(9)位)。
Instant instant = Instant.now();
分区日期时间
要通过某些特定地区的挂钟时间来查看同一时刻,可以应用一个时区(ZoneId)来获得一个zoneeddatetime。
时区
请指定合适的时区名称,如“America/Montreal”、“Africa/Casablanca”或“Pacific/Auckland”。不要使用3-4个字母的缩写,如EST或IST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone();
抵消
时区是一个区域相对于utc偏移量的变化历史。但有时你只得到一个偏移量而没有完整的区域。在这种情况下,使用OffsetDateTime类。
ZoneOffset offset = ZoneOffset.parse( "+05:30" );
OffsetDateTime odt = instant.atOffset( offset );
使用时区比仅仅使用偏移量更可取。
LocalDateTime
Local…类中的“Local”表示任何位置,而不是特定的位置。所以这个名字可能是反直觉的。
LocalDateTime、LocalDate和LocalTime故意缺乏任何关于偏移量或时区的信息。所以它们不代表实际的时刻,它们不是时间轴上的点。当有疑问或困惑时,使用zoneeddatetime而不是LocalDateTime。更多讨论请搜索Stack Overflow。
字符串
不要将日期-时间对象与表示其值的字符串合并。可以解析字符串以获得日期-时间对象,也可以从日期-时间对象生成字符串。但是字符串从来不是日期-时间本身。
了解在java中默认使用的标准ISO 8601格式。时间类。
关于java.time
java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。
Joda-Time项目现在处于维护模式,建议迁移到java。时间类。
要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。
使用与JDBC 4.2或更高版本兼容的JDBC驱动程序,您可以交换java。Time对象直接使用数据库。不需要字符串或java.sql。*类。
从哪里获取java。时间类?
Java SE 8、Java SE 9以及更高版本 内置的。 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小特性并进行了修复。 Java SE 6和Java SE 7 大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。 安卓 后续版本的Android捆绑实现的java。时间类。 对于早期的Android, ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。参见如何使用ThreeTenABP....
ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。
Date是一个更简单的类,主要是为了向后兼容。如果需要设置特定的日期或进行日期计算,请使用Calendar。日历也处理本地化。date之前的日期操作函数已弃用。
就我个人而言,如果有选择的话,我倾向于使用以毫秒为单位的时间作为long(或long,视情况而定)或Calendar。
Date和Calendar都是可变的,这在API中使用时往往会出现问题。
Date and Calendar are really the same fundamental concept (both represent an instant in time and are wrappers around an underlying long value). One could argue that Calendar is actually even more broken than Date is, as it seems to offer concrete facts about things like day of the week and time of day, whereas if you change its timeZone property, the concrete turns into blancmange! Neither objects are really useful as a store of year-month-day or time-of-day for this reason. Use Calendar only as a calculator which, when given Date and TimeZone objects, will do calculations for you. Avoid its use for property typing in an application. Use SimpleDateFormat together with TimeZone and Date 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 uses Calendar 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.
有点晚了,但是Java在JDK 8中有一个新的日期时间API。您可能希望升级JDK版本并采用该标准。没有更多凌乱的日期/日历,没有更多第三方罐子。
我一直提倡joda时间。这是为什么。
API是一致的和直观的。不像java.util。日期/日历api 它没有线程问题,不像java.text.SimpleDateFormat等(我见过许多客户端问题,没有意识到标准日期/时间格式不是线程安全的) 它是新的Java日期/时间api (JSR310,计划在Java 8中发布)的基础。因此,您将使用的api将成为核心Java api。
编辑:如果可以迁移到Java 8, Java 8引入的Java日期/时间类现在是首选的解决方案