日期时间转换

在 java.time 包中,不同日期时间对象(如 LocalDate、LocalDateTime、Instant)之间的转换是常见操作。以下详细介绍核心转换方法及示例:

LocalDate 与 LocalDateTime 互转

LocalDate → LocalDateTime

LocalDate 表示日期(无时间),使用 atStartOfDay() 方法将其转换为 LocalDateTime,默认时间为当天 00:00:00。例如:

package com.hxstrive.java_date_time.convert;

import java.time.LocalDate;
import java.time.LocalDateTime;

public class DateToDateTime {
    public static void main(String[] args) {
        // 创建LocalDate对象
        LocalDate date = LocalDate.of(2023, 10, 5);
        
        // 转换为LocalDateTime(默认00:00:00)
        LocalDateTime dateTime = date.atStartOfDay();
        
        System.out.println("LocalDate: " + date);          // 输出:2023-10-05
        System.out.println("LocalDateTime: " + dateTime);  // 输出:2023-10-05T00:00
    }
}

运行结果:

LocalDate: 2023-10-05
LocalDateTime: 2023-10-05T00:00

LocalDateTime → LocalDate

LocalDateTime 包含日期和时间,toLocalDate() 方法提取其中的日期部分,得到 LocalDate。例如:

package com.hxstrive.java_date_time.convert;

import java.time.LocalDate;
import java.time.LocalDateTime;

public class DateTimeToDate {
    public static void main(String[] args) {
        // 创建LocalDateTime对象
        LocalDateTime dateTime = LocalDateTime.of(2023, 10, 5, 14, 30);
        
        // 提取日期部分,转换为LocalDate
        LocalDate date = dateTime.toLocalDate();
        
        System.out.println("LocalDateTime: " + dateTime);
        System.out.println("LocalDate: " + date);
    }
}

运行结果:

LocalDateTime: 2023-10-05T14:30
LocalDate: 2023-10-05

  

Instant 与 LocalDateTime 互转

Instant 表示UTC 时间戳(从 1970-01-01T00:00:00Z 开始的毫秒数),与 LocalDateTime(本地日期时间)的转换需要指定时区(TimeZone)。

Instant → LocalDateTime

将 Instant 转换为 LocalDateTime 需要先调用 atZone(ZoneId) 方法指定时区,然后再使用 toLocalDateTime() 方法进行转换。其中:

  • Instant.atZone(ZoneId)  将 UTC 时间戳转换为指定时区的ZonedDateTime;

  • toLocalDateTime() 提取本地日期时间。

示例代码:

package com.hxstrive.java_date_time.convert;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class InstantToDateTime {
    public static void main(String[] args) {
        // 获取当前UTC时间戳(Instant)
        Instant instant = Instant.now();
        
        // 转换为东八区(Asia/Shanghai)的LocalDateTime
        LocalDateTime dateTime = instant
            .atZone(ZoneId.of("Asia/Shanghai"))  // 绑定时区
            .toLocalDateTime();                  // 提取本地日期时间
        
        System.out.println("Instant: " + instant);
        System.out.println("LocalDateTime(东八区): " + dateTime);
    }
}

运行结果:

Instant: 2025-09-23T01:24:34.229381400Z
LocalDateTime(东八区): 2025-09-23T09:24:34.229381400

  

LocalDateTime → Instant

将 LocalDateTime 转换成 Instant 也需要两步,先使用 atZone(ZoneId) 将本地日期时间绑定到某个时区,得到 ZonedDateTime,然后通过 toInstant() 方法转换为 Instant。其中:

  • LocalDateTime.atZone(ZoneId)  方法用于将本地日期时间绑定到指定时区,得到ZonedDateTime。

  • toInstant() 方法用于将 ZonedDateTime 转换为 UTC 时间戳。

示例代码:

package com.hxstrive.java_date_time.convert;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class DateTimeToInstant {
    public static void main(String[] args) {
        // 创建本地日期时间(默认无时区)
        LocalDateTime dateTime = LocalDateTime.of(2023, 10, 5, 14, 30);
        
        // 绑定东八区,转换为Instant(UTC时间戳)
        Instant instant = dateTime
            .atZone(ZoneId.of("Asia/Shanghai"))  // 绑定时区
            .toInstant();                        // 转换为UTC时间
        
        System.out.println("LocalDateTime: " + dateTime);
        System.out.println("Instant(UTC): " + instant);
    }
}

运行结果:

LocalDateTime: 2023-10-05T14:30
Instant(UTC): 2023-10-05T06:30:00Z

  

Date 与 LocalDate、LocalDateTime、Instant 互转

Date → LocalDate、LocalDateTime、Instant

java.util.Date 与新的日期时间 API(LocalDateTime、LocalDate、Instant)之间的转换需要注意时区的处理,因为旧的 Date 包含时区信息(本质上是 UTC 时间),而新的本地日期时间类不包含时区信息。

转换说明:

  1. Date -> Instant:直接使用Date.toInstant()方法,两者都是表示 UTC 时间线上的一个点,可以直接转换。

  2. Date -> LocalDateTime:需要通过Instant作为中间转换,必须指定时区(ZoneId),因为LocalDateTime是本地时间,依赖时区计算。常用时区:ZoneId.systemDefault()(系统默认)、ZoneId.of("UTC")(UTC 时区)、ZoneId.of("Asia/Shanghai")(上海时区)

  3. Date -> LocalDate:先通过atZone(ZoneId)将Instant转换为带时区的ZonedDateTime,再调用toLocalDate()提取日期部分(忽略时间)。

示例代码:

package com.hxstrive.java_date_time.convert;

import java.util.Date;
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.time.Instant;
import java.time.ZoneId;

public class FromDate {
    public static void main(String[] args) {
        // 创建一个java.util.Date对象
        Date date = new Date();
        System.out.println("原始Date对象: " + date);
        
        // 1. Date转换为Instant
        Instant instant = date.toInstant();
        System.out.println("转换为Instant: " + instant);
        
        // 2. Date转换为LocalDateTime (需要指定时区)
        // 使用系统默认时区
        LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        System.out.println("转换为LocalDateTime(系统默认时区): " + localDateTime);
        
        // 使用指定时区,例如UTC
        LocalDateTime utcDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC"));
        System.out.println("转换为LocalDateTime(UTC时区): " + utcDateTime);
        
        // 3. Date转换为LocalDate (需要指定时区)
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        System.out.println("转换为LocalDate: " + localDate);
    }
}

运行结果:

原始Date对象: Tue Sep 23 09:32:18 CST 2025
转换为Instant: 2025-09-23T01:32:18.146Z
转换为LocalDateTime(系统默认时区): 2025-09-23T09:32:18.146
转换为LocalDateTime(UTC时区): 2025-09-23T01:32:18.146
转换为LocalDate: 2025-09-23

  

LocalDate、LocalDateTime、Instant → Date

要将 LocalDate、LocalDateTime、Instant 转换为 Date,需要先了解一下这几个日期类的核心差异:

  • LocalDate:仅包含日期(无时间、无时区)

  • LocalDateTime:包含日期和时间(无时区)

  • Instant:表示 UTC 时间线上的一个瞬间(无时区概念,本质是时间戳)

  • Date:包含日期和时间,内部存储为自 1970-01-01 UTC 以来的毫秒数

转换操作如果涉及 LocalDate 和 LocalDateTime 时,必须指定时区(ZoneId),且所有转换都需要通过Instant 作为中间桥梁。例如:

  • LocalDateTime → Date:必须通过 atZone(zoneId) 关联时区,得到包含时区信息的 ZonedDateTime,再通过 toInstant() 获取 Instant,最后用 Date.from(instant) 完成转换。

  • LocalDate → Date:由于 LocalDate 不含时间,需先用 atStartOfDay() 补充时间(默认当天 00:00:00),后续转换流程与 LocalDateTime 相同。

  • Instant → Date:转换最直接,因为 Instant 和 Date 都是基于 UTC 时间戳的,可直接用 Date.from(instant) 转换。

示例代码:

package com.hxstrive.java_date_time.convert;

import java.util.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.ZoneId;

public class ToDate {
    public static void main(String[] args) {
        // 指定时区
        ZoneId zoneId = ZoneId.of("Asia/Shanghai"); // 亚洲/上海时区
        
        // 1. LocalDateTime 转换为 Date
        LocalDateTime localDateTime = LocalDateTime.now();
        // 步骤:LocalDateTime + 时区 → ZonedDateTime → Instant → Date
        Instant ldtInstant = localDateTime.atZone(zoneId).toInstant();
        Date dateFromLdt = Date.from(ldtInstant);
        System.out.println("LocalDateTime 转换结果: " + dateFromLdt);
        
        // 2. LocalDate 转换为 Date(默认时间为当天00:00:00)
        LocalDate localDate = LocalDate.now();
        // 步骤:LocalDate → LocalDateTime(补充时间)→ ZonedDateTime → Instant → Date
        LocalDateTime ldToLdt = localDate.atStartOfDay(); // 补充时间为00:00:00
        Instant ldInstant = ldToLdt.atZone(zoneId).toInstant();
        Date dateFromLd = Date.from(ldInstant);
        System.out.println("LocalDate 转换结果: " + dateFromLd);
        
        // 3. Instant 转换为 Date
        Instant instant = Instant.now();
        Date dateFromInstant = Date.from(instant);
        System.out.println("Instant 转换结果: " + dateFromInstant);
        
        // 验证不同时区的影响(对比UTC时区)
        ZoneId utcZone = ZoneId.of("UTC");
        Date dateFromLdtUtc = Date.from(localDateTime.atZone(utcZone).toInstant());
        System.out.println("LocalDateTime(UTC时区) 转换结果: " + dateFromLdtUtc);
    }
}

运行结果:

LocalDateTime 转换结果: Tue Sep 23 10:04:56 CST 2025
LocalDate 转换结果: Tue Sep 23 00:00:00 CST 2025
Instant 转换结果: Tue Sep 23 10:04:56 CST 2025
LocalDateTime(UTC时区) 转换结果: Tue Sep 23 18:04:56 CST 2025

  

Calendar 与 LocalDate、LocalDateTime、Instant 互转

Calendar → LocalDate、LocalDateTime、Instant

Calendar与新日期时间 API(LocalDate、LocalDateTime、Instant)的转换可以通过Instant作为中间桥梁,再需要注意时区处理。

转换说明:

  1. Calendar → Instant:直接使用calendar.toInstant()方法,Calendar内部存储的是基于其自身时区的时间,转换为Instant时会自动转为 UTC 时间。

  2. Calendar → LocalDateTime:

    • 先通过calendar.getTimeZone().toZoneId()获取Calendar使用的时区

    • 再用LocalDateTime.ofInstant(...)结合时区进行转换

    • 也可以指定其他时区(如系统默认时区ZoneId.systemDefault())

  1. Calendar → LocalDate:

    • 先将Calendar转为Instant,再关联时区得到ZonedDateTime

    • 最后通过toLocalDate()提取日期部分(仅包含年、月、日)

示例代码:

package com.hxstrive.java_date_time.convert;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.TimeZone;

public class FromCalendar {
    public static void main(String[] args) {
        // 创建一个Calendar实例(默认时区和 Locale)
        Calendar calendar = Calendar.getInstance();
        System.out.println("原始Calendar: " + calendar.getTime());
        
        // 1. Calendar 转换为 Instant
        Instant instant = calendar.toInstant();
        System.out.println("Calendar -> Instant: " + instant);
        
        // 2. Calendar 转换为 LocalDateTime
        // 获取Calendar的时区
        ZoneId zoneId = calendar.getTimeZone().toZoneId();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(calendar.toInstant(), zoneId);
        System.out.println("Calendar -> LocalDateTime: " + localDateTime);
        
        // 3. Calendar 转换为 LocalDate
        LocalDate localDate = LocalDateTime.ofInstant(calendar.toInstant(), zoneId).toLocalDate();
        System.out.println("Calendar -> LocalDate: " + localDate);
    }
}

运行结果:

原始Calendar: Tue Sep 23 09:59:49 CST 2025
Calendar -> Instant: 2025-09-23T01:59:49.574Z
Calendar -> LocalDateTime: 2025-09-23T09:59:49.574
Calendar -> LocalDate: 2025-09-23

  

LocalDate、LocalDateTime、Instant → Calendar

将 LocalDate、LocalDateTime、Instant 这些新日期时间类型转换为 Calendar(旧的日期时间类)时,需要注意两者在设计上的差异:

  • 新日期类型(LocalDate等)本身不包含时区信息(Instant除外,它是 UTC 时间)

  • Calendar包含时区信息,且内部依赖Date进行时间存储

核心转换思路:新日期类型 → Instant → Date(或毫秒数) → Calendar

示例代码:

package com.hxstrive.java_date_time.convert;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.TimeZone;

public class ToCalendar {
    public static void main(String[] args) {
        Instant instant = Instant.parse("2024-10-22T12:30:00.000+08:00");
        System.out.println("instant=" + instant);

        LocalDateTime localDateTime = LocalDateTime.of(2024, 10, 22, 12, 30, 0, 0);
        System.out.println("localDateTime=" + localDateTime);
        
        LocalDate localDate = LocalDate.of(2024, 10, 22);
        System.out.println("localDate=" + localDate);

        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        
        // Instant 转换为 Calendar
        Calendar calendarFromInstant = Calendar.getInstance();
        calendarFromInstant.setTimeInMillis(instant.toEpochMilli());
        // 或使用TimeZone设置时区
        calendarFromInstant.setTimeZone(TimeZone.getTimeZone(zoneId));
        System.out.println("Instant -> Calendar: " + calendarFromInstant.getTime());
        
        // LocalDateTime 转换为 Calendar
        Calendar calendarFromLdt = Calendar.getInstance(TimeZone.getTimeZone(zoneId));
        calendarFromLdt.setTimeInMillis(localDateTime.atZone(zoneId).toInstant().toEpochMilli());
        System.out.println("LocalDateTime -> Calendar: " + calendarFromLdt.getTime());
        
        // LocalDate 转换为 Calendar(默认使用当天的00:00:00)
        Calendar calendarFromLd = Calendar.getInstance(TimeZone.getTimeZone(zoneId));
        calendarFromLd.setTimeInMillis(localDate.atStartOfDay(zoneId).toInstant().toEpochMilli());
        System.out.println("LocalDate -> Calendar: " + calendarFromLd.getTime());
    }
}

运行结果:

instant=2024-10-22T04:30:00Z
localDateTime=2024-10-22T12:30
localDate=2024-10-22
Instant -> Calendar: Tue Oct 22 12:30:00 CST 2024
LocalDateTime -> Calendar: Tue Oct 22 12:30:00 CST 2024
LocalDate -> Calendar: Tue Oct 22 00:00:00 CST 2024


说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号