Java各类日期和时间转换超强总结(Date和LocalDateTime相互转换等)

一、前言

大家在开发过程中必不可少得和日期打交道,对接别的系统时,时间日期格式不一致,每次都要转换!
从 Java1 到 Java8 将近 20 年,再加上 Java8 的普及时间、各种历史 API 兼容过渡时间。我们很多时候需要在旧时间 API 与新时间 API 之间切换,并行使用!!!
每次写完就忘记了,小编专门来整理一篇来详细说一下他们转换的方法,方便后面使用!!

在Java开发中,日期和时间的处理随着JDK的迭代发展经历了几个阶段,从最初的java.util.Datejava.util.Calendar到Java 8(java.time包下的类)引入全新的日期时间API。现今在Java中,JDK提供了多种日期和时间相关类,主要包括以下几种:

  • java.util.Date:这是Java最早提供的日期和时间类表示特定的时间瞬间,精确到毫秒。可以通过System.currentTimeMillis()来获取当前时间的毫秒表示。
  • java.sql.Date:这是为数据库应用设计的日期类,只包含年、月、日信息,不包含时间和时区信息。
  • java.sql.Time:类似java.sql.Date,但它只包含小时、分钟和秒信息。
  • java.sql.Timestamp:这是一个比java.util.Date更加精确的时间戳类,它可以精确到纳秒级别。
  • java.util.Calendarjava.util.GregorianCalendar:Calendar是一个抽象类,提供了日期和时间的计算方法。GregorianCalendarCalendar的一个具体实现,用于处理公历(格里高利历)。
  • java.time包中的类:在Java 8及以上版本,推荐使用java.time包中的类来处理日期和时间,因为它们设计更加合理且功能更加强大。主要类包括LocalDateLocalTimeLocalDateTimeZonedDateTimeInstantDurationPeriod等。

二、日期格式转换

LocalDateTime 和 Date 互相转换

Date 转 LocalDateTime、LocalDate、LocalTime

要将java.util.Date转换为LocalDate、LocalTime或LocalDateTime,可以使用java.time.Instant类作为中间桥梁,因为Instant类可以表示时间线上的一个瞬时点,与java.util.Date有相似的用途(尽管Instant是以UTC表示的,而Date是相对于默认时区的)。

Java8 发行的时候,也考虑到了新旧 API 之间的转换,所以在java.util.Date中增加了toInstance()方法,可以得到一个Instance实例。Instance表示时间线上的一个瞬时点,没有时区概念,所以我们需要通过atZone()指定时区,得到ZonedDateTime实例,然后转换为java.time.LocalDateTime

如下:

Date dateNow = new Date();

LocalDateTime localDateTime = dateNow.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime()

LocalDate localDate = dateNow.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();

LocalTime localTime = dateNow.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalTime();

同样的,我们也可以借助Instance的ofEpochMilli()方法创建实例。如下:

Date dateNow = new Date();

LocalDateTime localDateTime = Instant.ofEpochSecond(dateNow.getTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();

LocalDate localDate = Instant.ofEpochSecond(dateNow.getTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDate();

LocalTime localTime = Instant.ofEpochSecond(dateNow.getTime())
                .atZone(ZoneId.systemDefault())
                .toLocalTime();
}

在上述示例中,首先将java.util.Date对象转换为java.time.Instant,然后通过atZone(ZoneId.systemDefault())方法将其转换为特定时区(这里是系统默认时区)的ZonedDateTime对象。由于LocalDate、LocalTime和LocalDateTime都是时区无关的(对于LocalDateTime来说,它实际上是“本地”的,不包含时区信息,但在这里通过指定时区来从Instant获取它),最后通过调用.toLocalDate()、.toLocalTime()或.toLocalDateTime()方法将它们从ZonedDateTime中提取出来。

注意,在转换过程中,需要指定一个时区,因为java.util.Date本身并不包含时区信息,它只是自epoch以来的毫秒数。因此,在转换为LocalDate、LocalTime或LocalDateTime时,需要明确想要哪个时区的日期或时间。如果想要的是UTC时间,你可以使用ZoneId.of(“UTC”)代替ZoneId.systemDefault()。

LocalDateTime、LocalDate、LocalTime 转 Date

LocalDateTime localDateTime = LocalDateTime.now();
Date dateFromLocalDateTime = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

// 由于`LocalDate`不带有时间信息,所以必须设置时间,才能转 Date。atStartOfDay,自动赋予午夜时间,返回 LocalDateTime,设置时区返回 ZonedDateTime,进而得到 Instant
LocalDate localDate = LocalDate.now();
Date dateFromLocalDate = Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

// 由于`LocalDate`不带有日期信息,所以必须设置日期,才能转 Date。
LocalTime localTime = LocalTime.now();
Date dateFromLocalTime = Date.from(localTime.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant());

LocalDateTime 和 String 互相转换

LocalDateTime 转 String

LocalDate类有一个format()方法,可以将日期转成字符串。format()方法需要一个DateTimeFormatter对象作为参数。

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeStr = LocalDateTime.now().format(dateTimeFormatter);

String 转 LocalDateTime

我们可以使用parse()方法从字符串中解析日期对象

String dateTimeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime localDateTime = LocalDateTime.parse(dateTimeStr);

LocalDateTime 和 Instant 互相转换

LocalDateTime表示没有时区的日期时间,如2019-10-25T12:15:30,而Instant是时间线上的一个瞬时点。

LocalDateTime 转 Instant

LocalDateTime localDateTime = LocalDateTime.now();

Instant instant;
//第一种方式:Using LocalDateTime.toInstant()
instant = localDateTime.toInstant(ZoneOffset.UTC);

//第二种方式:Using LocalDateTime.atZone() and Instant.atZone()
instant =localDateTime.atZone(ZoneId.systemDefault()).toInstant();

//第三种方式:Using LocalDateTime.toEpochSecond() and Instant.ofEpochSecond()
long timeInSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC);
instant = Instant.ofEpochSecond(timeInSeconds);

Instant 转 LocalDateTime

//Using LocalDateTime.ofInstant
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());

long timeInSeconds = 1567109422L;
localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timeInSeconds), ZoneId.systemDefault());

localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timeInSeconds, 0), ZoneId.systemDefault());

long timeInMillis = 1567109422123L;
localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeInMillis), ZoneId.systemDefault());

//Using Timestamp
localDateTime = Timestamp.from(Instant.now()).toLocalDateTime(); 

Date 和 String 互相转换

Date 转 String

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
String dateStr = df.format(now);

String 转 Date

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
String dateStr = df.format(now);
Date date = df.parse(dateStr);
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值