这应该很简单
customerSearch.get("DateOfBirth")
,其中customerSearch是一个HashMap<String, Object>
,它是一个公历日期。
但是我需要一个普通的Date
对象。
我尝试过
Date dateOfBirth = new Date(
((GregorianCalendar) customerSearch.get("DateOfBirth")).getTimeInMillis());
但表示公历日期不能转换为日期。
有帮助吗?
答案 0 :(得分:2)
( (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.
您正在使用并且可能滥用由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() ;
如果用Date
是java.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
。类GregorianCalendar
,java.util.Date
和ZonedDateTime
都代表时刻,即时间轴上的特定点。绝对不要将它们用于仅日期。
java.sql.Date
类假装是仅日期的,但是通过可怕的设计决策,java.util.Date
的子类实际上确实占用了一天的时间和偏移量/区域。如上所述,该类已由LocalDate
代替。
正常日期对象
对于java.util.Date
或java.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.Date
或java.sql.Timestamp
即可完成数据库工作。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance 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中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:0)
没有Java类GregorianDate
。除非是您自己的课程,否则您不会提及。因此,以防万一公历日期只是常规的Date
,因为当今世界上大多数地区都使用公历?因此,您的地图在您的HashMap<String, Object>
中属于哪个类别的实例?如果它只是常规的Date
,则您的代码应为:
Date dateOfBirth = (Date)(customerSearch.get("DateOfBirth"));