java基础-java8日期api

原文连接

1.LocalDate 和 LocalTime

LocalDate、 LocalTime、 LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息 .

你可以通过静态工厂方法of创建一个LocalDate实例。 LocalDate实例提供了多种方法来
读取常用的值,比如年份、月份、星期几等

now()静态方法, 根据当前时间创建对象LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now(); LocalDateTime localDateTime = LocalDateTime.now();
of()静态方法, 根据指定日期/时间创建 对象LocalDate localDate = LocalDate.of(2016, 10, 26); LocalTime localTime = LocalTime.of(02, 22, 56); LocalDateTime localDateTime = LocalDateTime.of(2016, 10, 26, 12, 10, 55);
plusDays, plusWeeks, plusMonths, plusYears向当前 LocalDate 对象添加几天、 几周、 几个月、 几年
minusDays, minusWeeks, minusMonths, minusYears从当前 LocalDate 对象减去几天、 几周、 几个月、 几年
plus, minus添加或减少一个 Duration 或 Period
withDayOfMonth, withDayOfYear, withMonth, withYear将月份天数、 年份天数、 月份、 年 份 修 改 为 指 定 的 值 并 返 回 新 的 LocalDate 对象
getDayOfMonth获得月份天数(1-31)
getDayOfYear获得年份天数(1-366)
getDayOfWeek获得星期几(返回一个 DayOfWeek 枚举值)
getMonth获得月份, 返回一个 Month 枚举值
getMonthValue获得月份(1-12)
getYear获得年份
until获得两个日期之间的 Period 对象, 或者指定 ChronoUnits 的数字
isBefore, isAfter比较两个 LocalDate
isLeapYear判断是否是闰年

构造及创建方式以LocalDate为例

	 //创建初始化LocalDate对象
        LocalDate date = LocalDate.of(2021, 3, 18);
        //获取年份
        int year = date.getYear();

        //获取当前是几月输出为当权月份的英文表示
        Month month = date.getMonth();
        //获取月份的原始数值
        int value = date.getMonthValue();
        //获取对象中的日的原始数值为18
        int day = date.getDayOfMonth();
        //获取今天属于周几
        DayOfWeek dow = date.getDayOfWeek();
        //获取当前月分的天数
        int len = date.lengthOfMonth();
        //判断是否为闰年
        boolean leap = date.isLeapYear();

        //获取当前的年月日对象
        LocalDate now = LocalDate.now();

        LocalDateTime now1 = LocalDateTime.now();

        System.out.println(now);
        System.out.println(now1);
		/**
		now:2021-03-05
		now1:2021-03-05T18:15:43.816
		**/

注:

  • LocalDateTime另外多了获取时分秒的方法
  • 也可以通过使用TemporalField 作为参数获取响应的时间字段
	//ChronoField为一个枚举类实现了TemporalField 	
	int year1 = date.get(ChronoField.YEAR);
        int month1 = date.get(ChronoField.MONTH_OF_YEAR);
        int day1 = date.get(ChronoField.DAY_OF_MONTH);

LocalDate和LocalTime都可以通过解析代表它们的字符串创建。使用静态方法parse,你
可以实现这一目的

LocalDate date = LocalDate.parse("2021-03-18");
LocalTime time = LocalTime.parse("13:45:20");

你可以向parse方法传递一个DateTimeFormatter。该类的实例定义了如何格式化一个日
期或者时间对象。

2.Instant 时间戳

:只能操作事件戳的形式,常用形式如"2021-03-18"不可用。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算.

你可以通过向静态工厂方法ofEpochSecond传递一个代表秒数的值创建一个该类的实例。你可以通过向静态工厂方法ofEpochSecond传递一个代表秒数的值创建一个该类的实例。

构造示例如下

//下面四个为		1970年1月1日午夜时分后三秒的时间戳
	Instant instant1 = Instant.ofEpochSecond(3);
        Instant instant2 = Instant.ofEpochSecond(3, 0);
//下面两个为添加偏移量
        Instant instant3 = Instant.ofEpochSecond(2, 1_000_000_000);
        Instant instant4 = Instant.ofEpochSecond(4, -1_000_000_000);

        long timeMillis = System.currentTimeMillis();
        Instant instant = 		Instant.ofEpochSecond(System.currentTimeMillis());
        Instant now = Instant.now();
        Instant now = Instant.now();//获取当前时间戳

可以通过Duration和Period类使用Instant

3.Duration 和 Period

Duration:用于计算两个“时间”间隔 ,Duration类表示秒或纳秒时间间隔,适合处理较短的时间,需要更高的精确性。我们能使用between()方法比较两个瞬间的差:

Period:用于计算两个“日期”间隔 ,Period 类表示一段时间的年、月、日,开使用between()方法获取两个日期之间的差作为Period 对象返回:

目前为止,你看到的所有类都实现了Temporal接口, Temporal接口定义了如何读取和操纵
为时间建模的对象的值。 LocalDateTime和Instant是为不同的目的而设计的,一个是为了便于人阅读使用,另一个是为了便于机器处理,所以你不能将二者混用。

Duration类和Period类共享了很多相似的方法

方 法 名是否是静态方法方法描述
between创建两个时间点之间的 interval
from由一个临时时间点创建 interval
of是 由它的组成部分创建 interval 的实例
parse由字符串创建 interval 的实例
addTo创建该 interval 的副本,并将其叠加到某个指定的 temporal 对象
get读取该 interval 的状态
isNegative检查该 interval 是否为负值,不包含零
isZero检查该 interval 的时长是否为零
minus通过减去一定的时间创建该 interval 的副本
multipliedBy将 interval 的值乘以某个标量创建该 interval 的副本
negated以忽略某个时长的方式创建该 interval 的副本
plus以增加某个指定的时长的方式创建该 interval 的副本
subtractFrom从指定的 temporal 对象中减去该 interval

Period 类

Period 类表示一段时间的年、月、日,开使用between()方法获取两个日期之间的差作为Period 对象返回:

Period  duration = Period .between(LocalDate.of(2018, 9, 8),
                LocalDate.of(2020, 3, 18));


        long YEARS = duration.get(ChronoUnit.YEARS);
        long month = duration.get(ChronoUnit.MONTHS);
        long day = duration.get(ChronoUnit.DAYS);
        System.out.println("相差:"+YEARS+"year"+month+"month"+day+"day");
//相差:1year6month10day
//也可通过下面的方法
		LOG.info("Years:" + period.getYears() + 
 		 " months:" + period.getMonths() + 
 		 " days:"+period.getDays());
//创建Period类型对象是基于年、月、日和周,构造日期差值
        Period fromUnits = Period.of(3, 10, 10);
        Period fromDays = Period.ofDays(50);
        Period fromMonths = Period.ofMonths(5);
        Period fromYears = Period.ofYears(10);
        Period fromWeeks = Period.ofWeeks(40);


Duration类

Duration类表示秒或纳秒时间间隔,适合处理较短的时间,需要更高的精确性。我们能使用between()方法比较两个瞬间的差:

    Instant instant1 = Instant.ofEpochSecond(3);
        Instant instant2 = Instant.ofEpochSecond(System.currentTimeMillis());
        //也可以通过LocalTime构造
        Duration between = Duration.between(instant1, instant2);

        System.out.println(between.getSeconds());
         //我们能基于下面的方法获得Duration对象,ofDays(), ofHours(), ofMillis(), ofMinutes(), ofNanos(), ofSeconds():
        // 可以使用toDays(), toHours(), toMillis(), toMinutes()方法把Duration对象可以转成其他时间单元:
        long days = between.toDays();
        //将间隔的秒数转化为天数
        System.out.println(days);

在测试程序运行时间时,可获取指定单位的时间

	long startup = System.currentTimeMillis();
        run();
        long end = System.currentTimeMillis();
        long runTime= startup-end;
        Duration duration = Duration.ofMillis(runTime);
        long minutes = duration.toMinutes();
        log.info("总共花费了{}分钟",minutes);

4. 日期的操纵

一般方法

如果你已经有一个LocalDate对象,想要创建它的一个修改版,最直接也最简单的方法是使
用withAttribute方法。 withAttribute方法会创建对象的一个副本,并按照需要修改它的属
性。

LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.withYear(2011); //修改了年份
LocalDate date3 = date2.withDayOfMonth(25);
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9)

以相对方式修改LocalDate对象的属性

LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.plusWeeks(1);//其他的类也有类似plus方法去调整日期
LocalDate date3 = date2.minusYears(3);//减
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);

像LocalDate、 LocalTime、 LocalDateTime以及Instant这样表示时间点的日期时间类提供了大量通用的方法

在这里插入图片描述

使用 TemporalAdjuster

TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。

TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现

进行一些更加复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,你可以使用重载版本的with方法,向其传递一个提供了更多定制化选择的TemporalAdjuster对象,更 加 灵 活 地 处 理 日 期 。 对 于 最 常 见 的 用 例 , 日 期 和 时 间 API 已 经 提 供 了 大 量 预 定 义 的TemporalAdjuster。你可以通过TemporalAdjuster类的静态工厂方法访问它们 。

import static java.time.temporal.TemporalAdjusters.*;
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY));
LocalDate date3 = date2.with(lastDayOfMonth());

TemporalAdjuster类为是一个函数式接口

@FunctionalInterface
public interface TemporalAdjuster {
	Temporal adjustInto(Temporal temporal);
}

TemporalAdjusters 工厂中的方法

方 法 名描述
dayOfWeekInMonth创建一个新的日期,它的值为同一个月中每一周的第几天
firstDayOfMonth创建一个新的日期,它的值为当月的第一天
firstDayOfNextMonth创建一个新的日期,它的值为下月的第一天
firstDayOfNextYear创建一个新的日期,它的值为明年的第一天
firstDayOfYear创建一个新的日期,它的值为当年的第一天
firstInMonth创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值
lastDayOfMonth创建一个新的日期,它的值为当月的最后一天
lastDayOfNextMonth创建一个新的日期,它的值为下月的最后一天
lastDayOfNextYear创建一个新的日期,它的值为明年的最后一天
lastDayOfYear创建一个新的日期,它的值为今年的最后一天
lastInMonth创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值
next/previous创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期
nextOrSame/previousOrSame创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期,如果该日期已经符合要求,直接返回该对象

实例

请设计一个NextWorkingDay类,该类实现了TemporalAdjuster接口,能够计算明天 的日期,同时过滤掉周六和周日这些节假日。格式如下所示: date = date.with(new NextWorkingDay()); 如果当天的星期介于周一至周五之间,日期向后移动一天;如果当天是周六或者周日,则 返回下一个周一.

public class NextWorkingDay implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
		DayOfWeek dow =
		DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
		int dayToAdd = 1;
		if (dow == DayOfWeek.FRIDAY) dayToAdd = 3;
		else if (dow == DayOfWeek.SATURDAY) dayToAdd = 2;
			return temporal.plus(dayToAdd, ChronoUnit.DAYS);
		}
}

================测试===============
    @Test
    public void temporalAdjuster(){
        LocalDate date = LocalDate.of(2020, 3, 18);
    //方式一
        date = date.with(new NextWorkingDay());
    // 方式二   或者通过lambda
        date = date.with(temporal -> {
            DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
            int dayToAdd = 1; //正常增加一天
            if (dow == DayOfWeek.FRIDAY) dayToAdd = 3; //周五增加三天
            else if (dow == DayOfWeek.SATURDAY) dayToAdd = 2; //周六增加两天
            return temporal.plus(dayToAdd, ChronoUnit.DAYS); //返回修改后的日期
        });
        System.out.println(date);

    //   方式三 也可以使用工厂类
        TemporalAdjuster nextWorkingDay = TemporalAdjusters.ofDateAdjuster(
                temporal -> {
                    DayOfWeek dow =               DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
                    int dayToAdd = 1;
                    if (dow == DayOfWeek.FRIDAY) dayToAdd = 3;
                    if (dow == DayOfWeek.SATURDAY) dayToAdd = 2;
                    return temporal.plus(dayToAdd, ChronoUnit.DAYS);
                });
        date = date.with(nextWorkingDay);
        System.out.println();
    }

注:调用with方法是会将对象本身传入TemporalAdjuster的实例中,进行处理后返回该实例

5.DateTimeFormatter 类

处理日期和时间对象时,格式化以及解析日期时间对象是另一个非常重要的功能。新的
java.time.format包就是特别为这个目的而设计的。这个包中,最重要的类是DateTimeFormatter。创建格式器最简单的方法是通过它的静态工厂方法以及常量。像BASIC_ISO_DATE和 ISO_LOCAL_DATE 这 样 的 常 量 是 DateTimeFormatter 类 的 预 定 义 实 例 。 所 有 的DateTimeFormatter实例都能用于以一定的格式创建代表特定日期或时间的字符串。比如,下面的这个例子中,我们使用了两个不同的格式器生成了字符串

LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);20140318
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);2014-03-18

你也可以通过解析代表日期或时间的字符串重新创建该日期对象。所有的日期和时间API
都提供了表示时间点或者时间段的工厂方法,你可以使用工厂方法parse达到重创该日期对象的目的 .

LocalDate date1 = LocalDate.parse("20140318",DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2014-03-18",DateTimeFormatter.ISO_LOCAL_DATE);

和老的java.util.DateFormat相比较,所有的DateTimeFormatter实例都是线程安全
的。所以,你能够以单例模式创建格式器实例,就像DateTimeFormatter所定义的那些常量,并能在多个线程间共享这些实例。 DateTimeFormatter类还支持一个静态工厂方法,它可以按照某个特定的模式创建格式器,代码清单如下。

        //自定义格式,这段代码中, LocalDate的formate方法使用指定的模式生成了一个代表该日期的字符串。紧接着,静态的parse方法使用同样的格式器解析了刚才生成的字符串,并重建了该日期对象。
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        LocalDate date1 = LocalDate.of(2020,3, 18);
        String formattedDate = date1.format(formatter);
        LocalDate date2 = LocalDate.parse(formattedDate, formatter);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值