Java日期 - 使用的正确类是什么?

时间:2011-12-14 20:48:45

标签: java android

所以整个Java Date / Calendar / GregorianCalendar事情显然是一个笑话。什么是正确的Date类?

修改:在Android上为第三方构建SDK,其中应用程序需要提供日期

更多编辑:这些事情显然是一个笑话:

  • 99%的日期已弃用
  • 日期年份从1900
  • 偏移
  • 日期的月份为零索引,而日期为一个索引
  • 日期是可变的
  • 您应该使用日历创建日期...
  • ...除了你真的必须使用GregorianCalendar
    • 是否有相当一部分开发人员想要使用不同的日历?
  • Calendar.getTime()返回日期
  • 没有日期数学(比如多年的两个日期相隔多远)
    • 由于纪元不计算,所以用毫秒来弥补
  • 您不能将部分链接在一起以获得表达(如一年前的今天)
  • 可能更多的东西

3 个答案:

答案 0 :(得分:17)

Joda-Time。甚至在Android上。

如果你想坚持Java SE课程,那取决于你想要做什么。

修改:您不断更改自己的问题。 DateCalendar

答案 1 :(得分:1)

“正确”的日期类型完全取决于您的申请;但是,java.util.Calendar通常被接受为java.util.Date的替代,因为它提供了更多功能(特别是关于提取单个日期元素,如年,月等)。实际上,Date在某些情况下可以更容易使用(并且是Java自己的DateFormat类使用的那种情况),因此它是一个判断调用。

在两者之间进行转换并不困难,所以我会选择一个并坚持使用它的API。如果我选择一个,我会使用Date,因为它是最简单的,恕我直言。

答案 2 :(得分:0)

避免遗留日期时间类

  

所以整个Java Date / Calendar / GregorianCalendar事情显然是一个笑话。

是的,与最早版本的Java捆绑在一起的旧日期时间类非常混乱。设计糟糕,笨拙的尝试改进,很多黑客。

但公平地说,这些课程是一项勇敢的努力,旨在解决整个信息产业几十年来一直忽视的令人惊讶的棘手问题。基于TaligentIBM的先前工作,这些类的作者至少尝试过,几乎所有其他编程语言,平台和工具都只通过了最少的日期支持时间处理。

幸运的是,我们现在拥有业界领先的 java.time 类(JSR 310),内置于Java 8及更高版本中。这些都受到Joda-Time项目成功的启发。事实上,这两项努力都是由同一个人领导的,Stephen Colebourne

java.time

通过使用java.time来纠正您的每一项投诉项目。

  • 99%的日期已弃用
    Instant取代java.util.Date。 AFAIK,Java 8中的java.time中不推荐使用任何内容。 Java 9。
  • 日期偏离1900年年份在java.time中有合理的编号,2018是2018年。
  • 日期的月份为零索引,而日期为一个索引年份在java.time中有合理的编号,1-12在1月到12月。更好的是,Month enum提供了表示一年中每个月的对象,而不仅仅是整数。因此,您可以获得有效值type-safety和自我记录代码。
  • 日期是可变的
    几乎所有的java.time都是immutable。任何改变java.time对象某些方面的调用都会返回一个新的不同对象。甚至隐藏构造函数,而是使用静态工厂方法。
  • 您应该使用日历创建日期...
    ZonedDateTime替换java.util.Calendar
  • ...除了你真的必须使用GregorianCalendar <{1}}取代java.util.GregorianCalendar。 java.time框架使用的接口主要仅供内部使用,鼓励应用程序仅使用具体类。这是一个特定于java.time作为框架需求的设计决策,并且意味着您应该在应用程序中使用相同的内容。
  • Calendar.getTime()返回日期
    只需使用ZonedDateTime作为java.time中的基本构建块类,始终以UTC为单位表示分辨率纳秒。其他类型如Instant&amp; OffsetDateTime可以使用ZonedDateTime来回转换。
  • 没有日期数学(比如几年中两个日期相隔多远)
    java.time类有许多方便的Instant / {{1 }} 方法。此外,java.time提供了强大的Symmetry454 French Republican Calendar,并使您能够编写自己的。{3}} TemporalAduster。另请查看implementations方法,例如plus…
    • 由于纪元不计数而以毫秒为单位的混乱<如果必须使用count-from-epoch,请查看minus…ChronoUnit.YEARS.between( thisLocalDate , that LocalDate ),但当然不可取。最好使用java.time对象和ISO 8601字符串来表示日期时间值。
  • 您不能将部分链接在一起以获得表达式(如一年前的今天)
    java.time类绝对是为呼叫链设计的。示例:Instant::toEpochMilli&gt; Instant.ofEpochMilli。有时是合适的,但不要坚持 - 这是我的建议。
  • 可能更多的东西
    是旧的遗产类的更多问题。你会发现java.time是一个激进偏离旧的东西,完全现代化和精心设计,一个巨大的改进。

其他问题之一是与数据库交换日期时间值。请注意,使用符合ChronoUnit::between或更高版本(JDBC 4.2)的JDBC驱动程序,可以避免与日期时间相关的java.sql类(如JSR 221类)。那些旧课程与麻烦的旧遗产课程有关,不再需要。

LocalDate.now( ZoneId.of( "Europe/Paris" ) ).minusYears( 1 ).getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.FRANCE )

...和...

dimanche

关于java.time

java.sql.Timestamp框架内置于Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacyjava.util.Date和&amp; Calendar

现在位于SimpleDateFormatJoda-Time项目建议迁移到maintenance mode类。

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

从哪里获取java.time类?

  • JSR 310Java SE 8以及之后
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小功能和修复。
  • Java SE 9Java SE 6
    • 大部分java.time功能都被反向移植到Java 6&amp; 7 {in Java SE 7
  • ThreeTen-Backport
    • 更新版本的Android捆绑java.time类的实现。
    • 对于早期的Android,Android项目会调整 ThreeTen-Backport (如上所述)。见ThreeTenABP