Java日期和时间类总结

本文详细介绍了Java中处理日期和时间的类,包括Date的基本使用,Calendar的方法及其注意事项,以及Java8引入的新的日期时间API如LocalDate、LocalTime、LocalDateTime等,并给出了它们之间的转换示例。文章还强调了Calendar的add()和roll()方法的区别,以及设置容错性和延迟修改的特点。
摘要由CSDN通过智能技术生成

本文作为知识点记录,拷贝自:https://blog.csdn.net/u014163312/article/details/122271790

1. Date类

Java在java.util包中提供了Date类,这个类封装了当前的日期和时间。
JDK1.0开始就有了。
注意:Date不能实现国际化,偏移量也不统一,它的月份和小时都是从0开始的,月份的天数则是从1开始,年又是从1900年开始的。
该类的大部分方法都已过时。

1.1 常用的方法

Date类支持两种构造函数:
1.第一个构造函数,初始化对象的当前日期和时间。

Date()

2.下面的构造函数接收一个参数等于自1970年1月1日 00::00:00 起已经经过的毫秒数

Date(long millisec)

方法描述
boolean after(Date date)如果调用Date对象包含或晚于指定的日期则返回true,否则,返回false
boolean before(Date date)如果调用Date对象包含或早于指定的日期则返回true,否则,返回false
Object clone()重复调用Date对象
int compareTo(Date date)调用对象的值日期比较。如果这两个值相等返回0。如果调用对象是早于日期返回负数。如果调用对象迟于日期返回正值
boolean equals(Object date)如果调用Date对象包含相同的时间及日期则返回true,否则,返回false。
long getTime()返回自1970年1月1日起已经过的毫秒数。
void setTime(long time)设置所指定的时间,这表示从1970年1月1日 00:00:00 以毫秒为单位经过的时间

2. Calendar类

从JDK1.1开始有的。用于表示日历,指最通用的 Gregorian Calendar,即公历,它是一个抽象类,它是所有日历类的模板,所以不能使用沟槽函数来创建Calendar对象,但它提供了几个静态方法来获取Calendar对象根据TimeZone,Locale类获取特定的Calendar,如果不指定,则使用默认的TimeZone,Locale来创建Calendar。

	@Test
    public void test() {
        // 创建一个默认的calendar对象
        Calendar calendar = Calendar.getInstance();

        // 从Calendar对象中取出Date对象
        Date date = calendar.getTime();

        // 通过Date对象获得对应的Calendar对象
        // Calendar 没有直接接收Date对象的构造函数,因此只能通过下面的方式
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date);
    }

注意的时间字段:
Calendar.MONTH:代表月份,月份的起始是0,0代表1月。
Calendar.HOUR:12小时制的小时
Calendar.HOUR_OF_DAY:24小时制的小时

2.1 常用的方法

方法描述
add(int field,int amount)根据日历规则,给指定的日历字段添加(正数)或减去(负数)指定的时间量
roll(int field,int amount)与add方法类似,区别在于,加上amount后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。
get(int field)返回指定日历字段的值
getActualMaximum(int field)获取指定日历字段可能拥有的最大值
getActualMinimum(int field)获取指定日历字段可能拥有的最小值
set(int field,int value)将给定日历字段设置为给定值
set(int year,int month,int date)设置Calendar对象的年、月、日
set(int year,int month,int date,int hourOdDay,int minute,int second)设置Calendar对象的年、月、日、时、分、秒

2.2 重要的注意点

2.2.1 add() 和 roll() 的区别:

add(int field,int amount)方法:根据日历规则,给灰顶的日历字段添加(正数)或减去(负数)指定的时间量
1.当被修改的字段超出它允许的范围时,会发生进位,即上一级字段也会发生变化。
2.如果下一级的字段也要发生变化,那么该字段也会修正到变化自小的值。

	@Test
    public void test() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calendar = Calendar.getInstance();
        calendar.set(2023,0,31);
        System.out.println(sdf.format(calendar.getTime()));
        // 2023-01-31

        calendar.add(Calendar.MONTH,1);
        System.out.println(sdf.format(calendar.getTime()));
        // 2023-02-28

        calendar.add(Calendar.MONTH,15);
        System.out.println(sdf.format(calendar.getTime()));
        // 2024-05-28
    }

roll(int field,int amount)
1.与add()类似。区别在于,加上amount后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。
2.下一级字段的处理规则与add()相似。

	@Test
    public void test() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calendar = Calendar.getInstance();
        calendar.set(2023,0,31);
        System.out.println(sdf.format(calendar.getTime()));
        // 2023-01-31

        calendar.roll(Calendar.MONTH,15);
        System.out.println(sdf.format(calendar.getTime()));
        // 2023-04-30

    }
2.2.2 设置Calendar的容错性

调用set()来改变指定时间字段的值时,可能会传入一个不合法的参数,例如MONTH超过11。

通过调用 setLenient(boolean lenient)方法实现:
它用于设置容错性,Calendar默认支持较好的容错性。通过setLenient(false)来关闭容错性,让它进行严格的参数校验。当超过指定的时间字段允许的取值范围时,程序会抛出异常。

2.2.3 set()方法延迟修改

set(int field,int value)
尽管字段field是立即修改的,但该Calendar所代表的时间却不会一级修改,直到调用get()、getTime()、getTimeInMillis()、add()、roll()时,才会重新计算日历的时间,这被称为set()方法的延迟修改。
优势:多次调用set()方法不会触发多次不必要的计算(计算一个代表时间的long型整数)。

3. Java8新增的日期、时间包

Java8新增乐乐拉一个java.time的包。
同时也增加了一个java.time.temporal包,包括Temporal、TemporalAdjuster等接口,下面的一些类都实现了这些接口,使用的时候注意下。

3.1 Clock

获取指定时区的当前日期、时间。
该类可取代System类的currentTimeMillis()方法,而且提供了更多方法获取日期、时间。

3.2 Duration

代表持续时间。可以方便的获取一段时间。

3.3 Instant

代表一个具体的时刻可以精确到纳秒。

3.4 LocalDate

代表一个不带时区的日期。

	@Test
    void test2() {
        LocalDate today = LocalDate.now();
        // 获取本周周一和周日
        LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        System.out.println(monday); // 2023-03-13
        LocalDate sunday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        System.out.println(sunday); // 2023-03-19
    }

3.5 LocalTime

代表一个不带时区的时间。

3.6 LocalDateTime

代表一个不带时区的日期、时间

3.7 MonthDay

代表月日。

3.8 Year

代表年。

3.9 YearMonth

代表年月。

3.10 ZonedDateTime

代表一个带时区的日期、时间

3.11 Zoneld

代表一个时区

3.12 DayOfWeek

枚举类,定义了周日到周六的枚举。

3.13 Month

枚举类,定义了一月到十二月的枚举。
相关案例如下:

@Test
    public void test3() {

        Clock clock = Clock.systemUTC();
        System.out.println("当前时刻:" + clock.instant());
        System.out.println(clock.getZone());
        // 获取clock对应的毫秒数,和System.currentTimeMillis()输出相同
        System.out.println(System.currentTimeMillis());
        System.out.println(clock.millis());

        Duration duration = Duration.ofSeconds(60100);
        System.out.println(duration.toHours());

        Instant instant = Instant.now();
        System.out.println(instant);
        System.out.println(instant.plusMillis(5));

        LocalDate localDate = LocalDate.now();
        System.out.println(localDate);

        // 设置为某一天
        System.out.println(LocalDate.of(2021, 1, 1));

        LocalTime localTime = LocalTime.now();
        System.out.println(localTime);

        Year year = Year.now();
        System.out.println(year);

        YearMonth yearMonth = YearMonth.now();
        System.out.println(yearMonth);

        MonthDay monthDay = MonthDay.now();
        System.out.println(monthDay);
        System.out.println(monthDay.withMonth(2).withDayOfMonth(4));
    }

4. LocalDateTime、LocalDate、Date的相互转换

4.1 LocalDateTime 转 LocalDate

直接调用 toLocalDate() 方法

LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();

4.2 LocalDateTime 转 Date

在LocalDateTime 转 Date 时,需要使用到 Java 8的几个类

ZoneId/ZoneOffset:表示时区
ZoneDateTime:表示特定时区的日期和时间
Instant:表示时刻,不直接对应年月日信息,需要通过时区转换

LocalDateTime localDateTime = LocalDateTime.now();
//获取系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
//时区的日期和时间
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
//获取时刻
Date date = Date.from(zonedDateTime.toInstant());
System.out.println("格式化前:localDateTime:" + localDateTime + "  Date:" + date);
//格式化LocalDateTime、Date
DateTimeFormatter localDateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("格式化后:localDateTime:" + localDateTimeFormat.format(localDateTime) + "  Date:" + dateFormat.format(date));

输出结果如下:

格式化前:localDateTime:2022-01-03T17:43:54.544  Date:Mon Jan 03 17:43:54 CST 2022
格式化后:localDateTime:2022-01-03 17:43:54  Date:2022-01-03 17:43:54

4.3 LocalDate 转 LocalDateTime

一般调用 atTime() 方法进行赋值

LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime1 = localDate.atStartOfDay();
LocalDateTime localDateTime2 = localDate.atTime(8,20,33);
LocalDateTime localDateTime3 = localDate.atTime(LocalTime.now());

4.4 LocalDate 转 Date

先调用 atStartOfDay() 方法转 LocalDateTime 再转 Date

LocalDate localDate = LocalDate.now();
ZoneId zoneId = ZoneId.systemDefault();
Date date = Date.from(localDate.atStartOfDay().atZone(zoneId).toInstant());

4.5 Date 转 LocalDateTime

先转 ZonedDateTime 再转 LocalDateTime

Date date = new Date();
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDateTime = date.toInstant().atZone(zoneId).toLocalDateTime();

4.6 Date 转 LocalDate

跟 LocalDate 同理

Date date = new Date();
ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = date.toInstant().atZone(zoneId).toLocalDate();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值