Java8笔记6

本文深入解析Java中的新日期和时间API,包括LocalDate、LocalTime、Instant等类的使用,如何利用TemporalAdjuster进行复杂日期操作,以及DateTimeFormatter的线程安全特性。文章通过实例展示了如何创建和操作日期时间对象,调整日期至特定条件,和格式化日期时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                              新的日期和时间API

 

1.LocalDateLocalTimeInstantDuration 以及 Period

        开始使用新的日期和时间 API 时,你最先碰到的可能是 LocalDate 类。该类的实例是一个不 可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
       你可以通过静态工厂方法 of 创建一个 LocalDate 实例。 LocalDate 实例提供了多种方法来 读取常用的值,比如年份、月份、星期几等

LocalDate:

LocalDate date = LocalDate.of(2020, 5, 20);
        System.out.println("this year is :" + date.getYear());
        System.out.println("the month is :" + date.getMonth());
        System.out.println(" the day of month is :" + date.getDayOfMonth());
        System.out.println("the day of week is :" + date.getDayOfWeek());
        System.out.println("this month has days :" + date.lengthOfMonth());
        System.out.println("this year was leap ? :" + date.isLeapYear()) ;

        LocalDate now = LocalDate.now();
        System.out.println("the time now is :" + now);
this year is :2020
the month is :MAY
 the day of month is :20
the day of week is :WEDNESDAY
this month has days :31
this year was leap ? :true
the time now is :2020-05-19

LoaclTime:

 LocalTime localTime = LocalTime.now();
        System.out.println("now time is :" + localTime);
        System.out.println("hour is " + localTime.getHour());
        System.out.println("minute is " + localTime.getMinute());
        System.out.println("second is " + localTime.getSecond());
now time is :11:45:18.117740500
hour is 11
minute is 45
second is 18

LocalDateTime

LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println("now is :" + localDateTime);
        System.out.println(localDateTime.getDayOfMonth());
        System.out.println(localDateTime.getDayOfWeek());
        System.out.println(localDateTime.getDayOfYear());
        System.out.println(localDateTime.getMonthValue());
now is :2020-05-19T11:49:09.700690500
19
TUESDAY
140
5

2.机器的日期和时间格式

       作为人,我们习惯于以星期几、几号、几点、几分这样的方式理解日期和时间。毫无疑问, 这种方式对于计算机而言并不容易理解。从计算机的角度来看,建模时间最自然的格式是表示一 个持续时间段上某个点的单一大整型数。这也是新的java.time.Instant 类对时间建模的方 式,基本上它是以Unix 元年时间(传统的设定为 UTC 时区 1970 1 1 日午夜时分)开始所经历的 秒数进行计算。
       你可以通过向静态工厂方法 ofEpochSecond 传递一个代表秒数的值创建一个该类的实例。静态工厂方法ofEpochSecond 还有一个增强的重载版本,它接收第二个以纳秒为单位的参数值,对传入作为秒数的参数进行调整。重载的版本会调整纳秒参数,确保保存的纳秒分片在0 999 999 999之间。这意味着下面这些对 ofEpochSecond 工厂方法的调用会返回几乎同样的 Instant 对象:
 
 Instant instant = Instant.now();
        System.out.println(instant);
        System.out.println(instant.getEpochSecond());
        //多加了1天时间
        Instant instant1 = Instant.ofEpochSecond((instant.getEpochSecond() + (long) 60 * 60* 24));
        System.out.println(instant1);
        System.out.println(instant1.getEpochSecond());
2020-05-19T04:04:09.401508500Z
1589861049
2020-05-20T04:04:09Z
1589947449

 

 

3.使用 TemporalAdjuster

       截至目前,你所看到的所有日期操作都是相对比较直接的。有的时候,你需要进行一些更加 复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,你可 以使用重载版本的with 方法,向其传递一个提供了更多定制化选择的 TemporalAdjuster 对象, 更加灵活地处理日期。对于最常见的用例,日期和时间API 已经提供了大量预定TemporalAdjuster。你可以通过 TemporalAdjuster 类的静态工厂方法访问它们,如下所示。
 LocalDate date = LocalDate.now();
        LocalDate localDate = date.with(nextOrSame(DayOfWeek.SUNDAY));
        System.out.println(localDate);
        LocalDate localDate4 = date.with(previousOrSame(DayOfWeek.SUNDAY));
        System.out.println(localDate4);
        LocalDate localDate1 = localDate.with(lastDayOfMonth());
        System.out.println(localDate1);
        //第三周的星期五
        LocalDate localDate2 = localDate.with(dayOfWeekInMonth(3, DayOfWeek.FRIDAY));
        System.out.println(localDate2);
        //当前月的第一个星期一
        LocalDate localDate3 = localDate.with(firstInMonth(DayOfWeek.MONDAY));
        System.out.println(localDate3);
2020-05-24
2020-05-17
2020-05-31
2020-05-15
2020-05-04
      正如我们看到的,使用 TemporalAdjuster 我们可以进行更加复杂的日期操作,而且这些方 法的名称也非常直观,方法名基本就是问题陈述。此外,即使你没有找到符合你要求的预定义的 TemporalAdjuster,创建你自己的 TemporalAdjuster 也并非难事。实际上, TemporalAdjuster接口只声明了单一的一个方法(这使得它成为了一个函数式接口),定义如下。
TemporalAdjuster 接口
@FunctionalInterface 
public interface TemporalAdjuster { 
 Temporal adjustInto(Temporal temporal); 
}
        这意味着 TemporalAdjuster 接口的实现需要定义如何将一个 Temporal 对象转换为另一 个Temporal 对象。你可以把它看成一个 UnaryOperator<Temporal>
 
       
       设计一个 NextWorkingDay 类,该类实现了 TemporalAdjuster 接口,能够计算明天 的日期,同时过滤掉周六和周日这些节假日。格式如下所示:
 如果当天的星期介于周一至周五之间,日期向后移动一天;如果当天是周六或者周日,则 返回下一个周一。
 LocalDate localDate5 = date.with(temporal -> {
            DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
            int addToDay = 1;
            if (dayOfWeek == DayOfWeek.FRIDAY)
                addToDay = 3;
            else if (dayOfWeek == DayOfWeek.SATURDAY)
                addToDay = 2;
            return temporal.plus(addToDay, ChronoUnit.DAYS);
        });
        System.out.println(localDate5);
      你大概会希望在你代码的多个地方使用同样的方式去操作日期,为了达到这一目的,我们 建议你像我们的示例那样将它的逻辑封装到一个类中。对于你经常使用的操作,都应该采用类 似的方式,进行封装。最终,你会创建自己的类库,让你和你的团队能轻松地实现代码复用。
        如果你想要使用 Lambda 表达式定义 TemporalAdjuster 对象,推荐使用 TemporalAdjusters类的静态工厂方法 ofDateAdjuster ,它接受一个UnaryOperator<LocalDate>  类型的参数,代码如下:
import static java.time.temporal.TemporalAdjusters.*;

TemporalAdjuster temporalAdjuster = ofDateAdjuster(temporal -> {
            DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
            int addToDay = 1;
            if (dayOfWeek == DayOfWeek.FRIDAY)
                addToDay = 3;
            else if (dayOfWeek == DayOfWeek.SATURDAY)
                addToDay = 2;
            return temporal.plus(addToDay, ChronoUnit.DAYS);
        });
        LocalDate localDate6 = date.with(temporalAdjuster);
        System.out.println(localDate6);
   
DateTimeFormatter :线程安全的类
 LocalDate of = LocalDate.of(2019, 6, 20);
        String format = of.format(DateTimeFormatter.BASIC_ISO_DATE);
        String format1 = of.format(DateTimeFormatter.ISO_DATE);
        System.out.println(format);
        System.out.println(format1);
        String format2 = of.format(DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(format2);

        LocalDate parse = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println(parse);
        LocalDate parse1 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(parse1);

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        System.out.println(now.format(dateTimeFormatter1));
        System.out.println(now.format(dateTimeFormatter));
20190620
2019-06-20
2019-06-20
2014-03-18
2014-03-18
2020/05/19
2020-05-19 16:28:47

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值