其他分享
首页 > 其他分享> > No.3.1_28_5 JDK8新特性【Date】之ChronoField类详解

No.3.1_28_5 JDK8新特性【Date】之ChronoField类详解

作者:互联网

相关链接


5. 新API详解


id=24 ChronoField 时间结界

id类名作用
24 Enum ChronoField
时间结界
  类中所有方法都会返回一个 TemporalAdjuster 对象。
  表示一些 常用时间节点,供时间计算。(常用 g. 日期调节器 with:作为*.with的参数,按照一些特殊规则计算时间,还有get方法向下转型)
  例如:纳秒(在秒中)(ChronoField.NANO_OF_SECOND取值范围[0, 999999999]
      纳秒(在天中)(ChronoField.NANO_OF_DAY取值范围[0, 86399999999999],需要使用getLong方法
      微秒(在秒中)(ChronoField.MICRO_OF_SECOND取值范围[0, 999999]
      微秒(在天中)(ChronoField.MICRO_OF_DAY取值范围[0, 86399999999],需要使用getLong方法
      毫秒(在秒中) (ChronoField.MILLI_OF_SECOND取值范围[0, 999]
      毫秒(在天中) (ChronoField.MILLI_OF_DAY取值范围[0, 86399999]
      秒(在分中)(ChronoField.SECOND_OF_MINUTE取值范围[0, 59]
      秒(在天中)(ChronoField.SECOND_OF_DAY取值范围[0, 86399]
      秒(从UTC/格林威治的偏移秒数)(ChronoField.OFFSET_SECONDS取值范围[-64800, 64800]
      注意:对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)
      举例:long offsetSecond = ZonedDateTime.of(ldt, ZoneId.of(“Asia/Shanghai”)).getLong(ChronoField.OFFSET_SECONDS); => 获取中国时区偏移秒数"29143"≈ 8.059小时,即东八区
      秒(Unix 时间戳1)(ChronoField.INSTANT_SECONDS取值范围[ Long.MIN_VALUE, Long.MAX_VALUE ],需要使用getLong方法,其中:
        LONG.MIN_VALUE = 0x8000000000000000L = - 264
        LONG.MAX_VALUE = 0x7fffffffffffffffL = 264 - 1
      注意:对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)

     分钟(在天中)(ChronoField.MINUTE_OF_DAY取值范围[0, 1439]
     分钟(在小时中)(ChronoField.MINUTE_OF_HOUR取值范围[0, 59]
     12小时制(用0代表当天0:00AM或0:00PM)(ChronoField.HOUR_OF_AMPM取值范围[0, 11]
     12小时制(用12代表当天0:00AM或0:00PM)(ChronoField.CLOCK_HOUR_OF_AMPM取值范围[1, 12]
       2022-02-01T01:00.with(ChronoField.CLOCK_HOUR_OF_AMPM, 5) => 2022-02-01T05:00(当天AM5:00,因为01:00属于上午)
       2022-02-01T14:00.with(ChronoField.CLOCK_HOUR_OF_AMPM, 5) => 2022-02-01T17:00(当天PM5:00,因为14:00属于下午)
     24小时制(用0代表当天0点) (ChronoField.HOUR_OF_DAY取值范围[0, 23]
     24小时制(用24代表当天0点)(ChronoField.CLOCK_HOUR_OF_DAY取值范围[1, 24]
     半天(AM=0,PM=1)(ChronoField.AMPM_OF_DAY取值范围[0,1]
     日(在周中)(ChronoField.DAY_OF_WEEK取值范围[1,7]
     日(在月中)(ChronoField.DAY_OF_MONTH取值范围[1,x],其中x∈[28,31] ,取决于当月有几天
     日(在年中)(ChronoField.DAY_OF_YEAR取值范围[1,x],其中x∈[365,366] ,取决于当年有几天
     日(自纪元时间2起)(ChronoField.EPOCH_DAY取值范围[(Year.MIN_VALUE * 365.25), (Year.MAX_VALUE * 365.25)],需要使用getLong方法,其中:
       Year.MIN_VALUE = -999999999;  => 最小值 Year.MIN_VALUE * 365.25 = -365249999634
       Year.MAX_VALUE = 999999999; => 最大值 Year.MAX_VALUE * 365.25 = 365249999634
     周几(月对齐3)(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH取值范围[1, 7]
     周几(年对齐4)(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR取值范围[1, 7]
     第几周(月对齐)(ChronoField.ALIGNED_WEEK_OF_MONTH取值范围[1, 5],其中x∈[4,5] ,取决于当月有几周(实际测试平年2月x=5也可以)
     第几周(年对齐)(ChronoField.ALIGNED_WEEK_OF_YEAR取值范围[1, 53]
     月(在年中)(ChronoField.MONTH_OF_YEAR取值范围[1, 12]
     月(自公元50年起)(ChronoField.PROLEPTIC_MONTH取值范围[Year.MIN_VALUE * 12L, Year.MAX_VALUE * 12L + 11],需要使用getLong方法,其中:
       Year.MIN_VALUE = -999999999; => 最小值 Year.MIN_VALUE * 12L = 11999999988
       Year.MAX_VALUE = 999999999; => 最大值 Year.MAX_VALUE * 12L + 11 = 11999999999

     年(ChronoField.YEAR取值范围[ Year.MIN_VALUE, Year.MAX_VALUE],需要使用getLong方法,其中:
       Year.MIN_VALUE = -999999999; => 最小值
       Year.MAX_VALUE = 999999999; => 最大值
     年(自公元1年起)(ChronoField.YEAR_OF_ERA取值范围需要分类讨论,需要使用getLong方法,其中:
       ① 0001-01-01T00:00之前的时间(包含此刻), 属于公元前,取值范围[ 1, Year.MAX_VALUE + 1 ] => [ 1, 1000000000 ]
       ② 0001-01-01T00:00之后的时间(不包含此刻),属于公元前,取值范围[ 1, Year.MAX_VALUE ] => [ 1, 999999999 ]
       其原因是:公元后开始于1年1月1日0点,所以 年份∈ [ -999999999 ,0 ] 时,是公元前。年份∈ [ 1, 999999999 ] 时,是公元后。就时间范围来说,公元前比公元后要多1年。

     时代(公元前=0,公元后=1)(ChronoField.ERA取值范围[0, 1],举例(伪代码):
       2022-02-01T00:00.with(ChronoField.EPOCH_DAY, 0) => -2022-02-01T00:00(变为负值)
       2022-02-01T00:00.with(ChronoField.EPOCH_DAY, 1) => 2022-02-01T00:00(不变)
  举例(伪代码): 2022-01-01T02:03:04
      “2022-01-01T02:03:04”.get(ChronoField.MINUTE_OF_DAY); => 123
      “2022-01-01T02:03:04”.getLong(ChronoField.MINUTE_OF_HOUR);; => 3
--------------------------------------------------------------------------------------
  19.TemporalAdjusters 调节器 和 24.ChronoField 时间结界 都可以作为with参数修改时间(当然这2个的中文名字都是我自己编的,网上资料实在太少),区别在于:
  TemporalAdjusters 的修改日期是 基于当前时间 的,规则较为简单(例如上个星期一当月第1个星期五明年第5天等)。
  ChronoField 的修改时间是 基于一个新的时间 ,规则较为复杂的(例如 ChronoField.SECOND_OF_DAY先根据当前时间获取所在天,舍弃小时、分的信息,再基于这个时间设置一个新的秒数
      => 秒(在天中)(ChronoField.SECOND_OF_DAY取值范围[0, 86399],下面是一行伪代码,便于理解什么是"基于一个新的时间"
      => 2022-01-01T02:03:04.000056789.with(ChronoField.SECOND_OF_DAY, 8) => 2022-01-01T00:00:08.000056789
  2022-01-01T02:03:04.000056789 => 先获取所在天的信息 => 2022-01-01T00:00:00.000056789 (小于秒的信息还保留着)
  2022-01-01T00:00:00.000056789 => 对其赋值 SECOND=8 => 2022-01-01T00:00:08.000056789

 1 Unix 时间戳:Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。

 2 纪元时间:指1970年1月1日格林威治午夜12点为起点,纪元日的定义与UNIX发展历史有关。

 3 月对齐:重新定义一个关于星期几的新规则,规则描述:每月的1日作为周一(1.1日/2.1日/…12.1日),例如"2022年2月1日"是星期二,但在月对齐(ALIGNED_xxxx_MONTH)的新规则下,"2022年2月1日"是星期一

 4 年对齐:重新定义一个关于星期几的新规则,规则描述:每年的1月1日作为周一,例如"2022年1月1日"是星期六,但在年对齐(ALIGNED_xxxx_YEAR)的新规则下,"2022年1月1日"是星期一

 5 公元:公元,即公历纪年法,是一种源自于西方社会的纪年方法。原称基督纪元,又称西历或西元。


*10个


纳秒(在秒中)(ChronoField.NANO_OF_SECOND取值范围[0, 999999999]
纳秒(在天中)(ChronoField.NANO_OF_DAY取值范围[0, 86399999999999],需要使用getLong方法
微秒(在秒中)(ChronoField.MICRO_OF_SECOND取值范围[0, 999999]
微秒(在天中)(ChronoField.MICRO_OF_DAY取值范围[0, 86399999999],需要使用getLong方法
毫秒(在秒中) (ChronoField.MILLI_OF_SECOND取值范围[0, 999]
毫秒(在天中) (ChronoField.MILLI_OF_DAY取值范围[0, 86399999]
秒(在分中)(ChronoField.SECOND_OF_MINUTE取值范围[0, 59]
秒(在天中)(ChronoField.SECOND_OF_DAY取值范围[0, 86399]
秒(从UTC/格林威治的偏移秒数)(ChronoField.OFFSET_SECONDS取值范围[-64800, 64800]
注意:对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)
举例:long offsetSecond = ZonedDateTime.of(ldt, ZoneId.of(“Asia/Shanghai”)).getLong(ChronoField.OFFSET_SECONDS); => 获取中国时区偏移秒数"29143"≈ 8.059小时,即东八区
秒(Unix 时间戳1)(ChronoField.INSTANT_SECONDS取值范围[ Long.MIN_VALUE, Long.MAX_VALUE ],需要使用getLong方法,其中:
LONG.MIN_VALUE = 0x8000000000000000L = - 264
LONG.MAX_VALUE = 0x7fffffffffffffffL = 264 - 1
注意:对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)

作为get方法的参数 - 获取
/*
2022-01-01T02:03:04.000056789
56789 => 纳秒(在秒中) 参数:ChronoField.NANO_OF_SECOND
7384000056789 => 纳秒(在天中) 参数:ChronoField.NANO_OF_DAY
56 => 微秒(在秒中) 参数:ChronoField.MICRO_OF_SECOND
7384000056 => 微秒(在天中) 参数:ChronoField.MICRO_OF_DAY
0 => 毫秒(在秒中) 参数:ChronoField.MILLI_OF_SECOND
7384000 => 毫秒(在天中) 参数:ChronoField.MILLI_OF_DAY
4 => 秒(在分中) 参数:ChronoField.SECOND_OF_MINUTE
7384 => 秒(在天中) 参数:ChronoField.SECOND_OF_DAY
28800 => 秒(从UTC/格林威治的偏移秒数) 参数:ChronoField.OFFSET_SECONDS
1640973784 => 秒(Unix 时间戳) 参数:ChronoField.INSTANT_SECONDS
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 2, 3, 4, 56789);
        System.out.println(ldt);
        
        int i1 = ldt.get(ChronoField.NANO_OF_SECOND);
        System.out.println(i1 + " => 纳秒(在秒中) 参数:ChronoField.NANO_OF_SECOND");

        //需要使用getLong方法
        long l2 = ldt.getLong(ChronoField.NANO_OF_DAY);
        System.out.println(l2 + " => 纳秒(在天中) 参数:ChronoField.NANO_OF_DAY");

        int i3 = ldt.get(ChronoField.MICRO_OF_SECOND);
        System.out.println(i3 + " => 微秒(在秒中) 参数:ChronoField.MICRO_OF_SECOND");

        //需要使用getLong方法
        long l4 = ldt.getLong(ChronoField.MICRO_OF_DAY);
        System.out.println(l4 + " => 微秒(在天中) 参数:ChronoField.MICRO_OF_DAY");

        int i5 = ldt.get(ChronoField.MILLI_OF_SECOND);
        System.out.println(i5 + " => 毫秒(在秒中) 参数:ChronoField.MILLI_OF_SECOND");

        int i6 = ldt.get(ChronoField.MILLI_OF_DAY);
        System.out.println(i6 + " => 毫秒(在天中) 参数:ChronoField.MILLI_OF_DAY");

        int i7 = ldt.get(ChronoField.SECOND_OF_MINUTE);
        System.out.println(i7 + " => 秒(在分中) 参数:ChronoField.SECOND_OF_MINUTE");

        int i8 = ldt.get(ChronoField.SECOND_OF_DAY);
        System.out.println(i8 + " => 秒(在天中) 参数:ChronoField.SECOND_OF_DAY");

        //对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)
        ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("+08:00"));
        int i9 = zdt.get(ChronoField.OFFSET_SECONDS);
        System.out.println(i9 + " => 秒(从UTC/格林威治的偏移秒数) 参数:ChronoField.OFFSET_SECONDS");

        //对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime),需要使用getLong方法
        long l10 = zdt.getLong(ChronoField.INSTANT_SECONDS);
        System.out.println(l10 + " => 秒(Unix 时间戳) 参数:ChronoField.INSTANT_SECONDS");
    }
作为with方法的参数 - 修改
/*
2022-01-01T02:03:04.000056789
2022-01-01T02:03:04.000000001 => 纳秒(在秒中) 参数:ChronoField.NANO_OF_SECOND, 1
2022-01-01T00:00:00.000000002 => 纳秒(在天中) 参数:ChronoField.NANO_OF_DAY, 2
2022-01-01T02:03:04.000003 => 微秒(在秒中) 参数:ChronoField.MICRO_OF_SECOND, 3
2022-01-01T00:00:00.000004 => 微秒(在天中) 参数:ChronoField.MICRO_OF_DAY, 4
2022-01-01T02:03:04.005 => 毫秒(在秒中) 参数:ChronoField.MILLI_OF_SECOND, 5
2022-01-01T00:00:00.006 => 毫秒(在天中) 参数:ChronoField.MILLI_OF_DAY, 6
2022-01-01T02:03:07.000056789 => 秒(在分中) 参数:ChronoField.SECOND_OF_MINUTE, 7
2022-01-01T00:00:08.000056789 => 秒(在天中) 参数:ChronoField.SECOND_OF_DAY, 8
2022-01-01T02:03:04.000056789+08:00 => 秒(从UTC/格林威治的偏移秒数) 参数:ChronoField.OFFSET_SECONDS, 9
1970-01-01T08:00:10.000056789+08:00 => 秒(Unix 时间戳) 参数:ChronoField.INSTANT_SECONDS, 10
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 2, 3, 4, 56789);
        System.out.println(ldt);
        
        //纳秒(在秒中)(ChronoField.NANO_OF_SECOND)取值范围[0, 999999999]
        LocalDateTime ldt1 = ldt.with(ChronoField.NANO_OF_SECOND, 1);
        System.out.println(ldt1 + " => 纳秒(在秒中)1.NANO_OF_SECOND");

        //纳秒(在天中)(ChronoField.NANO_OF_DAY)取值范围[0, 86399999999999]
        LocalDateTime ldt2 = ldt.with(ChronoField.NANO_OF_DAY, 2);
        System.out.println(ldt2 + " => 纳秒(在天中)2.NANO_OF_DAY");

        //微秒(在秒中)(ChronoField.MICRO_OF_SECOND)取值范围[0, 999999]
        LocalDateTime ldt3 = ldt.with(ChronoField.MICRO_OF_SECOND, 3);
        System.out.println(ldt3 + " => 微秒(在秒中)3.MICRO_OF_SECOND");

        //微秒(在天中)(ChronoField.MICRO_OF_DAY)取值范围[0, 86399999999]
        LocalDateTime ldt4 = ldt.with(ChronoField.MICRO_OF_DAY, 4);
        System.out.println(ldt4 + " => 微秒(在天中)4.MICRO_OF_DAY");

        //毫秒(在秒中) (ChronoField.MILLI_OF_SECOND)取值范围[0, 999]
        LocalDateTime ldt5 = ldt.with(ChronoField.MILLI_OF_SECOND, 5);
        System.out.println(ldt5 + " => 毫秒(在秒中) 5.MILLI_OF_SECOND");

        //毫秒(在天中) (ChronoField.MILLI_OF_DAY)取值范围[0, 86399999]
        LocalDateTime ldt6 = ldt.with(ChronoField.MILLI_OF_DAY, 6);
        System.out.println(ldt6 + " => 毫秒(在天中) 6.MILLI_OF_DAY:");

        //秒(在分中)(ChronoField.SECOND_OF_MINUTE)取值范围[0, 59]
        LocalDateTime ldt7 = ldt.with(ChronoField.SECOND_OF_MINUTE, 7);
        System.out.println(ldt7 + " => 秒(在分中)7.SECOND_OF_MINUTE:");

        //秒(在天中)(ChronoField.SECOND_OF_DAY)取值范围[0, 86399]
        LocalDateTime ldt8 = ldt.with(ChronoField.SECOND_OF_DAY, 8);
        System.out.println(ldt8 + " => 秒(在天中)8.SECOND_OF_DAY:");

        //对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)
        ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("+08:00"));
        //秒(从UTC/格林威治的偏移秒数)(ChronoField.OFFSET_SECONDS)取值范围[-64800, 64800]
        ZonedDateTime zdt9 = zdt.with(ChronoField.OFFSET_SECONDS, 9);
        System.out.println(zdt9 + " => 秒(从UTC/格林威治的偏移秒数)9.OFFSET_SECONDS:");

        //对象必须是包含时区信息的(OffsetDateTime、ZonedDateTime)
        //秒(Unix 时间戳1)(ChronoField.INSTANT_SECONDS)取值范围[ Long.MIN_VALUE, Long.MAX_VALUE ]
        ZonedDateTime zdt10 = zdt.with(ChronoField.INSTANT_SECONDS, 10);
        System.out.println(zdt10 + " => 秒(Unix 时间戳)10.INSTANT_SECONDS:");
    }

分钟 *2个


分钟(在天中)(ChronoField.MINUTE_OF_DAY取值范围[0, 1439]
分钟(在小时中)(ChronoField.MINUTE_OF_HOUR取值范围[0, 59]

作为get方法的参数 - 获取
/*
2022-01-01T02:03:04.000056789
123 => 分钟(在天中) 参数:ChronoField.MINUTE_OF_DAY
3 => 分钟(在小时中) 参数:ChronoField.MINUTE_OF_HOUR
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 2, 3, 4, 56789);
        System.out.println(ldt);

        int i1 = ldt.get(ChronoField.MINUTE_OF_DAY);
        System.out.println(i1 + " => 分钟(在天中) 参数:ChronoField.MINUTE_OF_DAY");

        int i2 = ldt.get(ChronoField.MINUTE_OF_HOUR);
        System.out.println(i2 + " => 分钟(在小时中) 参数:ChronoField.MINUTE_OF_HOUR");
    }
作为with方法的参数 - 修改
/*
2022-01-01T02:03:04.000056789
2022-01-01T00:01:04.000056789 => 纳秒(在秒中) 参数:ChronoField.MINUTE_OF_DAY, 1
2022-01-01T02:02:04.000056789 => 纳秒(在天中) 参数:ChronoField.MINUTE_OF_HOUR, 2
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 2, 3, 4, 56789);

        //分钟(在天中)(ChronoField.MINUTE_OF_DAY)取值范围[0, 1439]
        LocalDateTime ldt1 = ldt.with(ChronoField.MINUTE_OF_DAY, 1);
        System.out.println(ldt1 + " => 纳秒(在秒中) 参数:ChronoField.MINUTE_OF_DAY, 1");

        //分钟(在小时中)(ChronoField.MINUTE_OF_HOUR)取值范围[0, 59]
        LocalDateTime ldt2 = ldt.with(ChronoField.MINUTE_OF_HOUR, 2);
        System.out.println(ldt2 + " => 纳秒(在天中) 参数:ChronoField.MINUTE_OF_HOUR, 3");
    }

小时 *4个


12小时制(用0代表当天0:00AM或0:00PM)(ChronoField.HOUR_OF_AMPM取值范围[0, 11]
12小时制(用12代表当天0:00AM或0:00PM)(ChronoField.CLOCK_HOUR_OF_AMPM取值范围[1, 12]
2022-02-01T01:00.with(ChronoField.CLOCK_HOUR_OF_AMPM, 5) => 2022-02-01T05:00(当天AM5:00,因为01:00属于上午)
2022-02-01T14:00.with(ChronoField.CLOCK_HOUR_OF_AMPM, 5) => 2022-02-01T17:00(当天PM5:00,因为14:00属于下午)
24小时制(用0代表当天0点) (ChronoField.HOUR_OF_DAY取值范围[0, 23]
24小时制(用24代表当天0点)(ChronoField.CLOCK_HOUR_OF_DAY取值范围[1, 24]

作为get方法的参数 - 获取
/*
2022-01-01T14:03:04.000056789
2 => 12小时制(从0计数) 参数:ChronoField.HOUR_OF_AMPM
2 => 12小时制(钟表数字) 参数:ChronoField.CLOCK_HOUR_OF_AMPM
14 => 24小时制(从0计数) 参数:ChronoField.HOUR_OF_DAY
14 => 24小时制(钟表数字) 参数:ChronoField.CLOCK_HOUR_OF_DAY
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 14, 3, 4, 56789);
        System.out.println(ldt);
        
        int i1 = ldt.get(ChronoField.HOUR_OF_AMPM);
        System.out.println(i1 + " => 12小时制(从0计数) 参数:ChronoField.HOUR_OF_AMPM");

        int i2 = ldt.get(ChronoField.CLOCK_HOUR_OF_AMPM);
        System.out.println(i2 + " => 12小时制(钟表数字) 参数:ChronoField.CLOCK_HOUR_OF_AMPM");
        
        int i3 = ldt.get(ChronoField.HOUR_OF_DAY);
        System.out.println(i3 + " => 24小时制(从0计数) 参数:ChronoField.HOUR_OF_DAY");

        int i4 = ldt.get(ChronoField.CLOCK_HOUR_OF_DAY);
        System.out.println(i4 + " => 24小时制(钟表数字) 参数:ChronoField.CLOCK_HOUR_OF_DAY");
    }
作为with方法的参数 - 修改
/*
2022-01-01T15:03:04.000056789
2022-01-01T12:03:04.000056789 => 12小时制(用0代表当天0:00AM或0:00PM) 参数:ChronoField.HOUR_OF_AMPM, 0
2022-01-01T12:03:04.000056789 => 12小时制(用12代表当天0:00AM或0:00PM) 参数:ChronoField.CLOCK_HOUR_OF_AMPM, 12
2022-01-01T00:03:04.000056789 => 24小时制(用0代表当天0点) 参数:ChronoField.HOUR_OF_DAY, 0
2022-01-01T00:03:04.000056789 => 24小时制(用24代表当天0点) 参数:ChronoField.CLOCK_HOUR_OF_DAY, 24
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 1, 15, 3, 4, 56789);
        System.out.println(ldt);

        //12小时制(用0代表当天0:00AM或0:00PM)(ChronoField.HOUR_OF_AMPM)取值范围[0, 11]
        LocalDateTime ldt1 = ldt.with(ChronoField.HOUR_OF_AMPM, 0);
        System.out.println(ldt1 + " => 12小时制(用0代表当天0:00AM或0:00PM) 参数:ChronoField.HOUR_OF_AMPM, 0");

        //12小时制(用12代表当天0:00AM或0:00PM)(ChronoField.CLOCK_HOUR_OF_AMPM)取值范围[1, 12]
        LocalDateTime ldt2 = ldt.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12);
        System.out.println(ldt2 + " => 12小时制(用12代表当天0:00AM或0:00PM) 参数:ChronoField.CLOCK_HOUR_OF_AMPM, 12");

        //24小时制(用0代表当天0点) (ChronoField.HOUR_OF_DAY)取值范围[0, 23]
        LocalDateTime ldt3 = ldt.with(ChronoField.HOUR_OF_DAY, 0);
        System.out.println(ldt3 + " => 24小时制(用0代表当天0点) 参数:ChronoField.HOUR_OF_DAY, 0");

        //24小时制(用24代表当天0点)(ChronoField.CLOCK_HOUR_OF_DAY)取值范围[1, 24]
        LocalDateTime ldt4 = ldt.with(ChronoField.CLOCK_HOUR_OF_DAY, 24);
        System.out.println(ldt4 + " => 24小时制(用24代表当天0点) 参数:ChronoField.CLOCK_HOUR_OF_DAY, 24");
    }

*5个


半天(AM=0,PM=1)(ChronoField.AMPM_OF_DAY取值范围[0,1]
日(在周中)(ChronoField.DAY_OF_WEEK取值范围[1,7]
日(在月中)(ChronoField.DAY_OF_MONTH取值范围[1,x],其中x∈[28,31] ,取决于当月有几天
日(在年中)(ChronoField.DAY_OF_YEAR取值范围[1,x],其中x∈[365,366] ,取决于当年有几天
日(自纪元时间2起)(ChronoField.EPOCH_DAY取值范围[(Year.MIN_VALUE * 365.25), (Year.MAX_VALUE * 365.25)],需要使用getLong方法,其中:
  Year.MIN_VALUE = -999999999;  => 最小值 Year.MIN_VALUE * 365.25 = -365249999634
  Year.MAX_VALUE = 999999999; => 最大值 Year.MAX_VALUE * 365.25 = 365249999634

作为get方法的参数 - 获取
/*
2022-02-01T14:03:04.000056789
1 => 半天(AM=0,PM=1) 参数:ChronoField.AMPM_OF_DAY
2 => 日(在周中) 参数:ChronoField.DAY_OF_WEEK
1 => 日(在月中) 参数:ChronoField.DAY_OF_MONTH
32 => 日(在年中) 参数:ChronoField.DAY_OF_YEAR
19024 => 日(自纪元时间起) 参数:ChronoField.EPOCH_DAY
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 2, 1, 14, 3, 4, 56789);
        System.out.println(ldt);

        int i1 = ldt.get(ChronoField.AMPM_OF_DAY);
        System.out.println(i1 + " => 半天(AM=0,PM=1) 参数:ChronoField.AMPM_OF_DAY");

        int i2 = ldt.get(ChronoField.DAY_OF_WEEK);
        System.out.println(i2 + " => 日(在周中) 参数:ChronoField.DAY_OF_WEEK");

        int i3 = ldt.get(ChronoField.DAY_OF_MONTH);
        System.out.println(i3 + " => 日(在月中) 参数:ChronoField.DAY_OF_MONTH");

        int i4 = ldt.get(ChronoField.DAY_OF_YEAR);
        System.out.println(i4 + " => 日(在年中) 参数:ChronoField.DAY_OF_YEAR");
        
        //需要使用getLong方法
        long l5 = ldt.getLong(ChronoField.EPOCH_DAY);
        System.out.println(l5 + " => 日(自纪元时间起) 参数:ChronoField.EPOCH_DAY");
    }
作为with方法的参数 - 修改
/*
2022-02-01T15:03:04.000056789是星期二
2022-02-01T03:03:04.000056789 => 半天(AM=0,PM=1) 参数:ChronoField.AMPM_OF_DAY, 0
2022-01-31T15:03:04.000056789 => 日(在周中) 参数:ChronoField.DAY_OF_WEEK, 1
2022-02-02T15:03:04.000056789 => 日(在月中) 参数:ChronoField.DAY_OF_MONTH, 2
2022-01-03T15:03:04.000056789 => 日(在年中) 参数:ChronoField.DAY_OF_YEAR, 3
1970-01-05T15:03:04.000056789 => 日(自纪元时间起) 参数:ChronoField.EPOCH_DAY, 4
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 2, 1, 15, 3, 4, 56789);
        System.out.println(ldt + "是" + ldt.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE));

        //半天(AM=0,PM=1)(ChronoField.AMPM_OF_DAY)取值范围[0,1]
        LocalDateTime ldt1 = ldt.with(ChronoField.AMPM_OF_DAY, 0);
        System.out.println(ldt1 + " => 半天(AM=0,PM=1) 参数:ChronoField.AMPM_OF_DAY, 0");

        //日(在周中)(ChronoField.DAY_OF_WEEK)取值范围[1,7]
        LocalDateTime ldt2 = ldt.with(ChronoField.DAY_OF_WEEK, 1);
        System.out.println(ldt2 + " => 日(在周中) 参数:ChronoField.DAY_OF_WEEK, 1");

        //日(在月中)(ChronoField.DAY_OF_MONTH)取值范围[1,x],其中x∈[28,31] ,取决于当月有几天
        LocalDateTime ldt3 = ldt.with(ChronoField.DAY_OF_MONTH, 2);
        System.out.println(ldt3 + " => 日(在月中) 参数:ChronoField.DAY_OF_MONTH, 2");

        //日(在年中)(ChronoField.DAY_OF_YEAR)取值范围[1,x],其中x∈[365,366] ,取决于当年有几天
        LocalDateTime ldt4 = ldt.with(ChronoField.DAY_OF_YEAR, 3);
        System.out.println(ldt4 + " => 日(在年中) 参数:ChronoField.DAY_OF_YEAR, 3");

        //日(自纪元时间起)(ChronoField.EPOCH_DAY)取值范围[(Year.MIN_VALUE * 365.25), (Year.MAX_VALUE * 365.25)]
        LocalDateTime ldt5 = ldt.with(ChronoField.EPOCH_DAY, 4);
        System.out.println(ldt5 + " => 日(自纪元时间起) 参数:ChronoField.EPOCH_DAY, 4");
    }

*4个


周几(月对齐3)(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH取值范围[1, 7]
周几(年对齐4)(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR取值范围[1, 7]
第几周(月对齐)(ChronoField.ALIGNED_WEEK_OF_MONTH取值范围[1, 5],其中x∈[4,5] ,取决于当月有几周(实际测试平年2月x=5也可以)
第几周(年对齐)(ChronoField.ALIGNED_WEEK_OF_YEAR取值范围[1, 53]

作为get方法的参数 - 获取

  说明: 2022.2.8应该是星期二,但按照月对齐的方式来算,2022.2.1是周一(2022.2.8也是周一),所以i1 = 1,其他同理。

/*
2022-02-08T14:05:06是星期二
1 => 周(月对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH
4 => 周(年对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR
2 => 周(月对齐) 参数:ChronoField.ALIGNED_WEEK_OF_MONTH
6 => 周(年对齐) 参数:ChronoField.ALIGNED_WEEK_OF_YEAR
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 2, 8, 14, 5, 6);
        System.out.println(ldt + "是" + getDayOfWeekStr(ldt));

        int i1 = ldt.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH);
        System.out.println(i1 + " => 周(月对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH");

        int i2 = ldt.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR);
        System.out.println(i2 + " => 周(年对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR");

        int i3 = ldt.get(ChronoField.ALIGNED_WEEK_OF_MONTH);
        System.out.println(i3 + " => 周(月对齐) 参数:ChronoField.ALIGNED_WEEK_OF_MONTH");

        int i4 = ldt.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
        System.out.println(i4 + " => 周(年对齐) 参数:ChronoField.ALIGNED_WEEK_OF_YEAR");
    }

    /**
     * 工具类
     */
    public static String getDayOfWeekStr(LocalDateTime ldt) {
        return ldt.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE);
    }
作为with方法的参数 - 修改

  说明: 2022.1.8应该是星期六,但按照月对齐的方式来算,2022.1.1日是周一,ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH 首先计算出月对齐的规则下:[2022.1.8日 ~ 2022.1.15日] 属于第2周 (2022.1.1是第一周的周一,2022.1.8是第二周的周一),则第2周的周二是2022.1.9,所以ldt1=“2022-01-09T15:03:04”,其它同理。

/*
2022-01-08T15:03:04是星期六,按照月对齐的规则是星期1,按照年对齐的方式是星期1
2022-01-09T15:03:04 => 周(月对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, 1
2022-01-10T15:03:04 => 周(年对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR, 2
2022-01-22T15:03:04 => 第几周(月对齐) 参数:ChronoField.ALIGNED_WEEK_OF_MONTH, 3
2022-01-29T15:03:04 => 第几周(年对齐) 参数:ChronoField.ALIGNED_WEEK_OF_YEAR, 4
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 1, 8, 15, 3, 4);
        System.out.println(ldt + "是" + getDayOfWeekStr(ldt) +
                                   ",按照月对齐的规则是星期" + ldt.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH) +
                                   ",按照年对齐的方式是星期" + ldt.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR));

        //周(月对齐)(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)取值范围[1, 7]
        LocalDateTime ldt1 = ldt.with(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, 2);
        System.out.println(ldt1 + " => 周(月对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, 1");

        //周(年对齐)(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR)取值范围[1, 7]
        LocalDateTime ldt2 = ldt.with(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR, 3);
        System.out.println(ldt2 + " => 周(年对齐) 参数:ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR, 2");

        //第几周(月对齐)(ChronoField.ALIGNED_WEEK_OF_MONTH)取值范围[1, 5],其中x∈[4,5] ,取决于当月有几周(实际测试平年2月x=5也可以)
        LocalDateTime ldt3 = ldt.with(ChronoField.ALIGNED_WEEK_OF_MONTH, 4);
        System.out.println(ldt3 + " => 第几周(月对齐) 参数:ChronoField.ALIGNED_WEEK_OF_MONTH, 3");

        //第几周(年对齐)(ChronoField.ALIGNED_WEEK_OF_YEAR)取值范围[1, 53]
        LocalDateTime ldt4 = ldt.with(ChronoField.ALIGNED_WEEK_OF_YEAR, 5);
        System.out.println(ldt4 + " => 第几周(年对齐) 参数:ChronoField.ALIGNED_WEEK_OF_YEAR, 4");
    }
    
    /**
     * 工具类
     */
    public static String getDayOfWeekStr(LocalDateTime ldt) {
        return ldt.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE);
    }

*2个


月(在年中)(ChronoField.MONTH_OF_YEAR取值范围[1, 12]
月(自公元5 0年起)(ChronoField.PROLEPTIC_MONTH取值范围[Year.MIN_VALUE * 12L, Year.MAX_VALUE * 12L + 11],需要使用getLong方法,其中:
Year.MIN_VALUE = -999999999; => 最小值 Year.MIN_VALUE * 12L = 11999999988
Year.MAX_VALUE = 999999999; => 最大值 Year.MAX_VALUE * 12L + 11 = 11999999999

作为get方法的参数 - 获取
/*
2022-02-01T14:03:04.000056789
2 => 月(在年中) 参数:ChronoField.MONTH_OF_YEAR
24265 => 月(自公元0年起) 参数:ChronoField.PROLEPTIC_MONTH
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 2, 1, 14, 3, 4, 56789);
        System.out.println(ldt);

        int i1 = ldt.get(ChronoField.MONTH_OF_YEAR);
        System.out.println(i1 + " => 月(在年中) 参数:ChronoField.MONTH_OF_YEAR");

        //需要使用getLong方法
        long l2 = ldt.getLong(ChronoField.PROLEPTIC_MONTH);
        System.out.println(l2 + " => 月(自公元0年起) 参数:ChronoField.PROLEPTIC_MONTH");
    }
作为with方法的参数 - 修改
/*
2022-02-03T15:03:04.000056789
2022-01-03T15:03:04.000056789 => 月(在年中) 参数:ChronoField.MONTH_OF_YEAR, 1
0000-03-03T15:03:04.000056789 => 月(自公元0年起) 参数:ChronoField.PROLEPTIC_MONTH, 2
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 2, 3, 15, 3, 4, 56789);
        System.out.println(ldt);

        //月(自公元0年起)(ChronoField.MONTH_OF_YEAR)取值范围[1, 12]
        LocalDateTime ldt1 = ldt.with(ChronoField.MONTH_OF_YEAR, 1);
        System.out.println(ldt1 + " => 月(在年中) 参数:ChronoField.MONTH_OF_YEAR, 1");

        //月(自公元0年起)(ChronoField.PROLEPTIC_MONTH)取值范围[Year.MIN_VALUE * 12L, Year.MAX_VALUE * 12L + 11]
        LocalDateTime ldt2 = ldt.with(ChronoField.PROLEPTIC_MONTH, 2);
        System.out.println(ldt2 + " => 月(自公元0年起) 参数:ChronoField.PROLEPTIC_MONTH, 2");
    }

*2个


年(ChronoField.YEAR取值范围[ Year.MIN_VALUE, Year.MAX_VALUE],需要使用getLong方法,其中:
Year.MIN_VALUE = -999999999; => 最小值
Year.MAX_VALUE = 999999999; => 最大值
年(自公元1年起)(ChronoField.YEAR_OF_ERA取值范围需要分类讨论,需要使用getLong方法,其中:
 ① 0001-01-01T00:00之前的时间(包含此刻), 属于公元前,取值范围[ 1, Year.MAX_VALUE + 1 ] => [ 1, 1000000000 ]
 ② 0001-01-01T00:00之后的时间(不包含此刻),属于公元后,取值范围[ 1, Year.MAX_VALUE ] => [ 1, 999999999 ]
 其原因是:公元后开始于1年1月1日0点,所以 年份∈ [ -999999999 ,0 ] 时,是公元前。年份∈ [ 1, 999999999 ] 时,是公元后。就时间范围来说,公元前比公元后要多1年。

作为get方法的参数 - 获取
/*
2022-02-01T14:03:04.000056789
2022 => 年 参数:ChronoField.MONTH_OF_YEAR
2022 => 年(自公元1年起) 参数:ChronoField.PROLEPTIC_MONTH
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2022, 2, 1, 14, 3, 4, 56789);
        System.out.println(ldt);

        //需要使用getLong方法
        long l1 = ldt.getLong(ChronoField.YEAR);
        System.out.println(l1 + " => 年 参数:ChronoField.MONTH_OF_YEAR");

        //需要使用getLong方法
        long l2 = ldt.getLong(ChronoField.YEAR_OF_ERA);
        System.out.println(l2 + " => 年(自公元1年起) 参数:ChronoField.PROLEPTIC_MONTH");
    }
作为with方法的参数 - 修改
/*
-2022-02-03T15:03:04.000056789
0001-02-03T15:03:04.000056789 => 年 参数:ChronoField.YEAR, 1
0000-02-03T15:03:04.000056789 => 年(自公元1年起) 参数:ChronoField.YEAR_OF_ERA, 1
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(-2022, 2, 3, 15, 3, 4, 56789);
        System.out.println(ldt);

        //年(ChronoField.YEAR)取值范围[ Year.MIN_VALUE, Year.MAX_VALUE]
        LocalDateTime ldt1 = ldt.with(ChronoField.YEAR, 1);
        System.out.println(ldt1 + " => 年 参数:ChronoField.YEAR, 1");

        //年(自公元1年起)(ChronoField.YEAR_OF_ERA)取值范围需要分类讨论,需要使用getLong方法
        LocalDateTime ldt2 = ldt.with(ChronoField.YEAR_OF_ERA, 1);
        System.out.println(ldt2 + " => 年(自公元1年起) 参数:ChronoField.YEAR_OF_ERA, 1");
    }

公元 *1个


时代(公元前=0,公元后=1)(ChronoField.ERA取值范围[0, 1],举例(伪代码):
2022-02-01T00:00.with(ChronoField.ERA, 0) => -2022-02-01T00:00(变为负值)
2022-02-01T00:00.with(ChronoField.ERA, 1) => 2022-02-01T00:00(不变)

作为get方法的参数 - 获取
/*
-2022-02-01T14:03:04.000056789
0 => 时代(公元前=0,公元后=1) 参数:ChronoField.ERA
2022-02-01T14:03:04.000056789
1 => 时代(公元前=0,公元后=1) 参数:ChronoField.ERA
*/
    public static void main(String[] args) {
        LocalDateTime ldt1 = LocalDateTime.of(-2022, 2, 1, 14, 3, 4, 56789);
        System.out.println(ldt1);

        int i1 = ldt1.get(ChronoField.ERA);
        System.out.println(i1 + " => 时代(公元前=0,公元后=1) 参数:ChronoField.ERA");

        LocalDateTime ldt2 = LocalDateTime.of(2022, 2, 1, 14, 3, 4, 56789);
        System.out.println(ldt2);

        int i2 = ldt2.get(ChronoField.ERA);
        System.out.println(i2 + " => 时代(公元前=0,公元后=1) 参数:ChronoField.ERA");
    }
作为with方法的参数 - 修改

  因为 0001-01-01 起才是公元后,所以公元前转公元后,去掉负号还需要补+1

/*
-2022-02-03T15:03:04.000056789
2023-02-03T15:03:04.000056789 => 时代(公元前=0,公元后=1) 参数:ChronoField.ERA, 1
*/
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(-2022, 2, 3, 15, 3, 4, 56789);
        System.out.println(ldt);

        //时代(公元前=0,公元后=1)(ChronoField.ERA)取值范围[0, 1]
        LocalDateTime ldt1 = ldt.with(ChronoField.ERA, 1);
        System.out.println(ldt1 + " => 时代(公元前=0,公元后=1) 参数:ChronoField.ERA, 1");
    }

22/02/11

M

标签:28,JDK8,ChronoField,2022,ldt,println,取值,DAY
来源: https://blog.csdn.net/qq_43529621/article/details/122863820