java - time教程 - localdatetime to date
LocalDate到java.util.Date,反之亦然最简单的转换? (5)
TL;博士
有没有一种简单的方法将LocalDate(Java 8引入)转换为java.util.Date对象? 通过'简单',我的意思是比这更简单
不。 你做得恰当,尽可能简洁。
java.util.Date.from( // Convert from modern java.time class to troublesome old legacy class. DO NOT DO THIS unless you must, to inter operate with old code not yet updated for java.time.
myLocalDate.atStartOfDay( // Let java.time determine the first moment of the day on that date in that zone. Never assume the day starts at 00:00:00.
ZoneId.of( "America/Montreal" ) // Specify time zone using proper name in `continent/region` format, never 3-4 letter pseudo-zones such as “PST”, “CST”, “IST”.
) // Produce a `ZonedDateTime` object.
.toInstant() // Extract an `Instant` object, a moment always in UTC.
)
请阅读下面的问题,然后再考虑一下。 怎么会更简单? 如果你问我约会的时间是什么时候开始的,我怎么回答却问你“哪里?”? 新的一天在巴黎FR早些时候比在加利福尼亚州的蒙特利尔,早些时候在加尔各答IN,甚至早些时候在新西兰奥克兰,所有不同的时刻。
因此,在将仅日期(
LocalDate
)转换为日期时,我们
必须
应用时区(
ZoneId
)来获取分区值(
ZonedDateTime
),然后转换为UTC(
Instant
)以匹配
java.util.Date
的定义
java.util.Date
。
细节
首先,尽可能避免旧的遗留日期时间类,如
java.util.Date
。
它们的设计很糟糕,令人困惑,也很麻烦。
实际上,由于种种原因,它们被java.time类取代了。
但如果必须,您可以将java.time类型转换为旧版本。 寻找添加到旧类的新转换方法。
java.util.Date
→
java.time.LocalDate
请记住,
java.util.Date
是一个误称,因为它表示日期
加上
时间,以UTC表示。
相反,
LocalDate
类表示没有时间且没有时区的仅日期值。
从
java.util.Date
到java.time意味着转换为java.time.Instant的等效类。
Instant
类表示
UTC
时间轴上的一个时刻,分辨率为
nanoseconds
(最多九(9)位小数)。
Instant instant = myUtilDate.toInstant();
LocalDate
类表示没有时间且没有时区的仅日期值。
时区对于确定日期至关重要。 对于任何给定的时刻,日期在全球范围内因地区而异。 例如, 法国巴黎 午夜过后几分钟是新的一天,而在 魁北克蒙特利尔 仍然是“昨天”。
所以我们需要将
Instant
移动到一个时区。
我们应用
ZoneId
来获取
ZonedDateTime
。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
从那里,请求仅限日期,
LocalDate
。
LocalDate ld = zdt.toLocalDate();
java.time.LocalDate
→
java.util.Date
要从另一个方向移动,从
java.time.LocalDate
到
java.util.Date
意味着我们将从仅日期转到日期时间。
所以我们必须指定一个时间。
你可能想要一天中的第一时间。
不要认为是
00:00:00
。
夏令时(DST)等异常意味着第一时刻可能是另一个时间,例如
01:00:00
。
让java.time通过在
LocalDate
上调用atStartOfDay来确定该值。
ZonedDateTime zdt = myLocalDate.atStartOfDay( z );
现在提取一个
Instant
。
Instant instant = zdt.toInstant();
通过调用
from( Instant )
将该
Instant
转换为
java.util.Date
。
java.util.Date d = java.util.Date.from( instant );
更多信息
- Oracle教程
- 类似的问题, 将java.util.Date转换为“java.time”类型?
关于 java.time
java.time
框架内置于Java 8及更高版本中。
这些类取代了麻烦的旧
legacy
日期时间类,如
java.util.Date
,
Calendar
和
SimpleDateFormat
。
现在处于 维护模式 的 Joda-Time 项目建议迁移到 java.time 类。
要了解更多信息,请参阅 Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是 JSR 310 。
您可以直接与数据库交换
java.time
对象。
使用符合
JDBC 4.2
或更高版本的
JDBC驱动程序
。
不需要字符串,不需要
java.sql.*
类。
从哪里获取java.time类?
-
Java SE 8
,
Java SE 9
及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小功能和修复。
-
Java SE 6
和
Java SE 7
- 许多java.time功能都被反向移植到 ThreeTen-Backport Java 6和7。
-
Android
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android(<26), ThreeTenABP 项目采用 ThreeTen-Backport (如上所述)。 请参见 如何使用ThreeTenABP ....
ThreeTen-Extra
项目使用其他类扩展了java.time。
该项目是未来可能添加到java.time的试验场。
您可以在这里找到一些有用的课程,如
Interval
,
YearWeek
,
YearQuarter
等。
这个问题在这里已有答案:
有没有一种简单的方法将
LocalDate
(Java 8引入)转换为
java.util.Date
对象?
通过'简单',我的意思是比这更简单:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
这对我来说似乎有点尴尬。
由于我们只对日期部分感兴趣,并且两个对象中都没有时区信息,为什么要明确引入时区? 应该隐式采用午夜时间和系统默认时区进行转换。
实际上有。
在
java.sql.Date
对象中有一个静态方法
valueOf
就是这样做的。
所以我们有
java.util.Date date = java.sql.Date.valueOf(localDate);
就是这样。 没有明确设置时区,因为隐式采用了本地时区。
来自docs:
提供的LocalDate被解释为本地时区的本地日期。
java.sql.Date
是
java.util.Date
子类,因此结果也是
java.util.Date
。
对于反向操作,java.sql.Date类中有一个 toLocalDate 方法。 所以我们有:
LocalDate ld = new java.sql.Date(date.getTime()).toLocalDate();
我用以下解决方案解决了这个问题
import org.joda.time.LocalDate;
Date myDate = new Date();
LocalDate localDate = LocalDate.fromDateFields(myDate);
System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016);
System.out.println("My date using joda.time LocalTime" 2016-11-18);
在这种情况下,localDate以“yyyy-MM-dd”格式打印您的日期
日期 - > LocalDate:
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate - >日期:
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
将LocalDateTime转换为java.util.Date
LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.systemDefault());
Instant instant = zonedDateTime.toInstant();
Date date = Date.from(instant);
System.out.println("Result Date is : "+date);