公历日期

时间:2019-01-28 14:57:50

标签: java date-conversion java.util.date java-date java.util.calendar

这应该很简单

customerSearch.get("DateOfBirth"),其中customerSearch是一个HashMap<String, Object>,它是一个公历日期。

但是我需要一个普通的Date对象。

我尝试过

Date dateOfBirth = new Date(
        ((GregorianCalendar) customerSearch.get("DateOfBirth")).getTimeInMillis());

但表示公历日期不能转换为日期。

有帮助吗?

2 个答案:

答案 0 :(得分:2)

tl; dr

( (GregorianCalendar) customerSearch.get( "DateOfBirth" ) )  // Retrieve and cast object of legacy class `GregorianCalendar`.
.toZonedDateTime()                                           // Convert from terrible legacy class to modern *java.time* class.
.toLocalDate()                                               // Extract the date-only portion, omitting time-of-day and time zone.

java.time

您正在使用并且可能滥用由JSR 310定义的 java.time 类在多年前取代的可怕的日期时间类。

  • ZonedDateTime代替GregorianCalendar
  • Instant代替java.util.Date
  • LocalDate代替java.sql.Date

如果必须与尚未更新为 java.time 的旧代码进行互操作,则可以来回转换。调用添加到旧类中的新转换方法。

GregorianCalendar gc = customerSearch… ;
ZonedDateTime zdt = gt.toZonedDateTime() ;

如果您只想获取没有日期和时区的日期,请提取LocalDate

LocalDate dateOfBirth = zdt.toLocalDate() ;

如果用Datejava.sql.Date类的意思,则应该使用上面的行来代替LocalDate的使用。

如果用Date来表示java.util.Date,那将是错误的类。该课程代表UTC的时刻。通过将GregorianCalendar / ZonedDateTime中的时区调整为UTC,您可以更改日期。

转换

如果您需要一个java.util.Date对象来与尚未为 java.time 更新的旧代码进行互操作,则可以进行转换。 java.util.Date代表UTC的时刻,因此我们需要等价于 java.time Instant的UTC时刻,但分辨率要比纳秒更好,而不是毫秒

我们可以从上面看到的Instant中提取一个ZonedDateTime。实际上,这只是从区域值调整为UTC值。同一时刻,时间轴上的同一点,不同的时钟时间。

Instant instant = zdt.toInstant() ;  // Extract a `Instant`, adjusting from zone to UTC.

在旧类上使用新的转换方法。

java.util.Date myJavaUtilDate = java.util.Date.from( instant ) ;  // Beware of possible data-loss in the fractional second, truncating from nanos to millis.

如果您需要从传统到现代的另一个方向。

Instant instant = myJavaUtilDate.toInstant() ;

使用适当的类型

如果您通常要尝试表示生日,只有日期没有时间,没有区域,则在地图中使用LocalDate。类GregorianCalendarjava.util.DateZonedDateTime都代表时刻,即时间轴上的特定点。绝对不要将它们用于仅日期。

java.sql.Date假装是仅日期的,但是通过可怕的设计决策,java.util.Date的子类实际上确实占用了一天的时间和偏移量/区域。如上所述,该类已由LocalDate代替。

  

正常日期对象

对于java.util.Datejava.sql.Date而言,没有什么比其他任何日期时间类更“正常”了。

  • java.util.Date代表UTC中的时刻,始终代表UTC,尽管其toString方法设计得很糟糕(说谎)。如果您需要UTC时间,请改用java.time.Instant
  • java.sql.Date仅表示日期,但如上所述,实际上在内部带有时间和时区/偏移量。使用java.time.LocalDate代替日期而不是时刻。
  • GregorianCalendar代表特定区域(时区)的人们使用的挂钟时间所显示的时刻。为此,请使用ZonedDateTime
  • java.sql.Timestamp代表UTC的时刻,但具有更精细的纳秒而不是毫秒的分辨率。 java.time 中所有与时刻相关的类都使用纳秒级的分辨率。因此,在具有UTC分辨率的UTC中,请暂时使用java.time.Instant而不是Timestamp

从JDBC 4.2开始,我们可以直接与数据库交换 java.time 类。因此,无需再触摸java.sql.Datejava.sql.Timestamp即可完成数据库工作。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

没有Java类GregorianDate。除非是您自己的课程,否则您不会提及。因此,以防万一公历日期只是常规的Date,因为当今世界上大多数地区都使用公历?因此,您的地图在您的HashMap<String, Object>中属于哪个类别的实例?如果它只是常规的Date,则您的代码应为:

Date dateOfBirth = (Date)(customerSearch.get("DateOfBirth"));