专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java 17 java.time 时间操作这一篇就够了

temp10 2024-09-19 04:03:25 java教程 13 ℃ 0 评论

Java 17 java.time 日期时间知识点

思维导图

这篇开始说说 java.time 这个包中的内容, 来自模块 java.base 。

该包中的 API 主要包括日期(dates)、时间(times)、时间戳(instants)以及持续时间(durations)。

Java 17 java.time 时间操作这一篇就够了

它们主要基于 ISO 日历系统,该系统是遵循预测格列高利规则的事实上的世界日历。对于包里的类都是不可变并且是线程安全的。

日期 dates 和时间 times

对于 Instant 本质是一个数字时间戳。当前的 Instant 可以从 Clock 类中获得,这对于时间点的日志记录和持久化非常有用, 在 java 8 之前通常使用 System.currentTimeMillis() 获取时间戳。

对于日期而言, 主要分为 3 个大的情况。

  • LocalDate 存储日期,只有年月日。比如:2021-12-26
  • LocalTime 存储时间,只有时分秒。比如:5:00, 8:00:00
  • LocalDateTime 存储日期和时间,包含年月日时分秒。比如:2022-01-01 00:00:00

除了时间的获得, 每个时间都会有对应的时区,时区的不同时间也是有差别的。

持续时间 Duration 和周期类 Period

对于 Duration 可以理解为两个时间的差值,也就是持续的时间。 对于该类最小的单位是纳秒。

对于 Period 该类主要是用来基于(年,月,日)进行时间的定义。并且该类提供了很多的封装好的 get 方法。

除了这些类之后还有一些其他的附加类型。比方说 Month、Year、MonthDay 等。

对于实际的使用中, 多数情况下 LocalDate、LocalTime以及 LocalDateTime 这三个最常用。

LocalDate

我们先来看看 LocalDate,从纪元年开始的日期。1970-01-01。

ISO-8601 日历系统中没有时区的日期,例如:2021-12-26。LocalDate 是一个不可变的日期时间对象, 表示日期, 通常表示成年月日。当然类中也有对应的当前时间是一年的多少天, 一个月的多少天,以及星期几。

ISO-8601日历系统是当今世界大部分地区使用的现代民用日历系统。相当于现在的公历日历体系,其中表示闰年规则永远适用。

类的定义:

public final class LocalDate
        implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable

该类并没有构造类, 而是使用静态方法进行调用的。比方说活动当天时间: LocalDate.now();

该类有三个常量。 源码如下:

API 定义如下:

需要注意其中 EPOCH 是从 Java 9 开始有的。

演示代码:

LocalDate localDate = LocalDate.MAX;
System.out.println("最大的时间: " + localDate);
localDate = LocalDate.MIN;
System.out.println("最小的时间: " + localDate);
localDate = LocalDate.EPOCH;
System.out.println("纪元年: " + localDate);

案例演示:

//当前日期
LocalDate localDate = LocalDate.now();
System.out.println("当前日期:" + localDate);
System.out.println("年:" + localDate.getYear());
System.out.println("月:" + localDate.getMonthValue());
System.out.println("日:" + localDate.getDayOfMonth());
System.out.println("星期:" + localDate.getDayOfWeek());
System.out.println("今年已经过去了多少天:" + localDate.getDayOfYear());
// 判断是否是闰年
System.out.println("是否是闰年:" + localDate.isLeapYear());

除了这些基本的,还有设置当前日期的方式。

LocalDate setLocalDate = LocalDate.of(2022, 01, 01);
System.out.println("设置的日期为:" + setLocalDate);
System.out.println("日期天数加10:" + setLocalDate.plusDays(10));
System.out.println("月数加1:" + setLocalDate.plusMonths(1));
System.out.println("星期加1:" + setLocalDate.plusWeeks(1));
System.out.println("年数加1:" + setLocalDate.plusYears(1));

System.out.println("日期天数减10:" + setLocalDate.minusDays(10));
System.out.println("月数减1:" + setLocalDate.minusMonths(1));
System.out.println("星期减1:" + setLocalDate.minusWeeks(1));
System.out.println("年数减1:" + setLocalDate.minusYears(1));

// 可以根据atTime 转换成 LocalDateTime 时间。 
System.out.println("年月日加上时分:" + setLocalDate.atTime(10, 20));
System.out.println("年月日加上时分秒:" + setLocalDate.atTime(10, 20, 30));
System.out.println("年月日加上时分秒纳秒:" + setLocalDate.atTime(10, 20, 30, 100));

运行效果如下:

竟然说时间都少不了时间的比较。 对于 LocalDate 而言, 可以通过 isAfter 和 isBefore 以及 compareTo 方法。

对于 date1.isAfter(date2) 代表的意思是, 检查 date1 是否在 date2 日期之后。

对于 date1.isBefore(date2) 代表的意思是,检查date1 是否在 date2 日期之前。

System.out.println("date1.compareTo(date2): " + date1.compareTo(date2)); // 1
System.out.println("date1.compareTo(date1): " + date1.compareTo(date1)); // 0
System.out.println("date2.compareTo(date1): " + date2.compareTo(date1)); // -1

对于有些情况下需要获得对应的月份的第一天和最后一天怎么处理呢?

这里使用了 TemporalAdjusters 公共工具类, 获得一些常用的处理函数。

如果想格式化 2021-12-01 这个时间, 不使用中划线而是改用年和月加上日。 该怎么做呢?

可以使用 LocalDate 对象的 fotmat(DateTimeFormatter formatter) 方法

String format(DateTimeFormatter formatter)

先看一个简单的例子, 然后在详细说这个方法。

格式的定义以及含义如下:

LocalDate 案例

给一个综合案例, 显示给定月份的全月日历表:

效果如下:

public static void showMonth(LocalDate localDate){
    System.out.println("======" + localDate.getYear() + " 年 " + localDate.getMonthValue() + "   月 =======");
    LocalDate firstDay = localDate.with(TemporalAdjusters.firstDayOfMonth());
    LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
    System.out.println("一   二  三  四  五  六  日");
    int week = firstDay.getDayOfWeek().getValue();
    for (int i = 1; i < week % 7; i++) {
        System.out.printf("%2s  "," ");
    }
    LocalDate currDate = firstDay;
    for (int i = firstDay.getDayOfMonth(); i <= lastDay.getDayOfMonth(); i++) {
        week = currDate.getDayOfWeek().getValue();
        System.out.printf("%3d",i);
        if(currDate.getDayOfMonth() == localDate.getDayOfMonth()){
            System.out.print("*");
        }else{
            System.out.print(" ");
        }

        if(week == 7){
            System.out.println();
        }
        currDate = firstDay.plusDays(i);
    }
}

LocalTime

对于 LocalTime 来说主要是为了操作时分秒的对象,通常标识小时:分钟:秒。时间标识的精度为纳秒。

举例:10:21:32.123456789

同样的该方法会有一些静态常量以及对应的操作时间的方法,增加减少时,分,秒,纳秒数。同样可以进行格式化,以及字符串与时间的转换,并且也可以通过 isAfter 和 isBefore 进行判断时间的先后顺序。

定义:

public final class LocalTime
        implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable

对于 LocaTime对应了静态常量,其中包含如下图:

举个例子:

LocalTime localTime = LocalTime.now();   
System.out.println("当前时间:" + localTime);
System.out.println("最小值:" + LocalTime.MIN);
System.out.println("最大值:" + LocalTime.MAX);
System.out.println("午夜时间:" + LocalTime.MIDNIGHT);
System.out.println("中午时间:" + LocalTime.NOON);

效果如下:

也可以通过静态方法 of(int hour, int minute, int second, int nanoOfSecond) 设置当前的时间时分秒纳秒等。

of 也有一些重载方法。 可以进行直接使用。

LocalDateTime

对于 Java 中的 LocalDateTime 来说是包含年月日,时分秒的时间,这里可以看出来他可以理解为是日期和时间的汇合。LocalDateTime = LocalDate + LocalTime;

定义:

public final class LocalDateTime
      implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable

对于 LocalDateTime 的值举例:2021-12-25 10:00:00.123456789 它的方法,基本上是 LocalDate 和 LocalTime 的合集, 操作年月日, 时分秒的方法都包含。 类型转换, 格式化输出。

举例说明:

运行查看效果:

同样该类也可以进行输出格式化:

时间的操作这些应该都是最常用的了,更复杂的用法也是在这之上进行灵活应用。希望对你有所帮助。

感谢您的阅读。点赞,收藏,关注。以及您的评论。一起探讨学习。

最近在看书中的一句话说的很不错。 英国女作家夏洛蒂 · 勃朗特说过:“人们总得有行动,即使找不到行动也要创造行动”。时刻暗示自己,接下来要面对的一天,将是一生中最值得纪念的,最重要的一天。共勉!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表