java.time中日期时间的创建、增减、修改、查询、格式化、解析

Java用线程安全的java.time代替了原来线程不安全的Date和Calendar。

通过查阅资料,学习了新增的time的一些基本使用方法。

打开任意分割线内的代码块注释,都可以直接运行。

package com.my.timetest;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.MonthDay;
import java.time.Period;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Iterator;
import java.util.Set;

/**
 * 
 * @author Zhang
 * 
 * 包括java.time中日期时间的创建、增减、修改、查询、格式化、解析
 * 
 */
public class TimeTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

//		//使用 now 方法创建 Instant的实例对象
//		Instant mInstantNow = Instant.now();
//		//使用 now 方法创建 LocalDate的实例对象
//		LocalDate mLocalDateNow = LocalDate.now();
//		//使用 now 方法创建 LocalTime的实例对象
//		LocalTime mLocalTimeNow = LocalTime.now();
//		//使用 now 方法创建 LocalDateTime的实例对象
//		LocalDateTime mLocalDateTimeNow = LocalDateTime.now();
//		//使用 now 方法创建 ZonedDateTime的实例对象
//		ZonedDateTime mZonedDateTimeNow = ZonedDateTime.now();
//		
//		//祖鲁时间(格林威治时间/国际标准时间) Instant:2022-08-14T10:37:28.878641900Z
//		System.out.println("Instant: " + mInstantNow);
//		//年-月-日 yyyy-mm-dd LocalDate:2022-08-14
//		System.out.println("LocalDate: " + mLocalDateNow);
//		//时:分:秒 HH:mm:ss LocalTime:18:37:28.905570800
//		System.out.println("LocalTime: " + mLocalTimeNow);
//		//年-月-日T时:分:秒 LocalDateTime:2022-08-14T18:37:28.905570800
//		System.out.println("LocalDateTime: " + mLocalDateTimeNow);
//		//年-月-日T时:分:秒+时区 ZonedDateTime:2022-08-14T18:37:28.906567200+08:00[Asia/Shanghai]
//		System.out.println("ZonedDateTime: " + mZonedDateTimeNow);
		
//===============================================================================================
		
//		//使用 now 方法创建 Year类的实例对象
//		Year mYear = Year.now();
//		//使用 now 方法创建 YearMonth类的实例对象
//		YearMonth mYearMonth = YearMonth.now();
//		//使用 now 方法创建 MonthDay类的实例对象
//		MonthDay mMonthDay = MonthDay.now();
//		
//		//Year:2022
//		System.out.println("Year: " + mYear);
//		//YearMonth:2022-08
//		System.out.println("YearMonth: " + mYearMonth);
//		//MonthDay:--08-14
//		System.out.println("MonthDay: " + mMonthDay);
		
//===============================================================================================
		
//		//初始化2022年8月8日的LocalDate对象
//		LocalDate mLocalDate = LocalDate.of(2022, Month.AUGUST, 8);
//		//LocalDate: 2022-08-08
//		System.out.println("LocalDate: " + mLocalDate);
//		
//		/*
//		 * 初始化晚上8点0分0秒的 LocalDate对象 -> 如果是晚上需要加上12
//		 * LocalTime.of方法的重载形式有以下几种,可以根据实践情况自行使用:
//		 * LocalTime.of(int hour,int minute) -> 根据小时/分钟生成对象
//		 * LocalTime.of(int hour,int minute,int second) -> 根据小时/分钟/秒生成对象
//		 * LocalTime.of(int hour,int minute,int second,int nanoOfSecond) -> 根据小时/分钟/秒/毫秒/纳秒生成对象
//		 */
//		LocalTime mLocalTime = LocalTime.of(20, 0);
//		//LocalTime: 20:00  若尾秒为0则省略
//		System.out.println("LocalTime: " + mLocalTime);
//		
//		/*
//		 * 初始化2022年8月8日下午8点0分的LocalDateTime对象。
//		 * LocalDateTime.of方法的重载形式有以下几种:
//		 * LocalDateTime.of(int year,int month,int dayOfMonth,int hour,int minute) -> 根据年/月/日/时/分生成对象
//		 * LocalDateTime.of(int year,int month,int dayOfMonth,int hour,int minute,int second,int nanoOfSencond)
//		 * -> 根据年/月/日/时/分/秒/毫秒/纳秒生成对象
//		 */
//		LocalDateTime mLocalDateTime = LocalDateTime.of(2022, Month.AUGUST, 8, 8, 0);
//		//LocalDateTime: 2022-08-08T08:00
//		System.out.println("LocalDateTime: " + mLocalDateTime);
//		
//		/*
//		 * LocalDateTime的of方法的特殊使用:
//		 * LocalDateTime.of(LocalDate localDate,LocalTime localTime);
//		 */
//		LocalDateTime mLocalDateTimeOf = LocalDateTime.of(mLocalDate, mLocalTime);
//		//LocalDateTime: 2022-08-08T20:00
//		System.out.println("LocalDateTime2: " + mLocalDateTimeOf);
		
//===============================================================================================
		
//		//获取所有时区信息
//		Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
//		//输出所有时区,Europe/Monaco、America/Los_Angeles等等
//		for (String availableZoneId : availableZoneIds) {
//			System.out.println(availableZoneId);
//		}
//		//获取当前系统默认的时区
//		ZoneId zoneId = ZoneId.systemDefault();
//		//系统默认时区:Asia/Shanghai
//		System.out.println("系统默认时区:" + zoneId);
		
//===============================================================================================
		
//		/*
//		 * 封装LocalDateTime并添加时区
//		 */
//		//1、封装LocalDateTime对象,参数自定义:2022年11月11日 8点54分38秒
//		LocalDateTime mLocalDateTime = LocalDateTime.of(2022, Month.NOVEMBER, 11, 8, 54, 38);
//		//2、LocalDateTime对象现在只是封装了时间,并没有时区信息,添加时区信息用atZone()方法
//		ZonedDateTime mZonedDateTime = mLocalDateTime.atZone(ZoneId.of("Asia/Shanghai"));
//		//上海当前的时间是:2022-11-11T08:54:38+08:00[Asia/Shanghai]
//		System.out.println("上海当前的时间是:" + mZonedDateTime);
//		//3、更改时区查看其他时区的当前时间,通过 withZoneSameInstant()方法即可
//		ZonedDateTime tokyoZonedDateTime = mZonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
//		//4、在上海同一时刻,Asia/Tokyo的时间是:2022-11-11T09:54:38+09:00[Asia/Tokyo]
//		System.out.println("在上海同一时刻,Asia/Tokyo的时间是:" + tokyoZonedDateTime);
		
//===============================================================================================
		
//		/*
//		 * 推荐初始化LocalDate和LocalDateTime对象的时候,月份的传入使用枚举。
//		 */
//		//初始化LocalDate和LocalDateTime的时候月份传入枚举类,Month -> 2011年5月15日11时11分11秒
//		LocalDateTime mLocalDateTime = LocalDateTime.of(2011, Month.MAY, 15, 11, 11, 11);
//		//输出时间:2011-05-15T11:11:11
//		System.out.println("初始化的时间是:" + mLocalDateTime);
//		//Month枚举类 -> of可以根据传入的数字返回对应的月份枚举
//		Month month = Month.of(5);
//		//输出对应枚举:2022-11-11T09:54:38+09:00[Asia/Tokyo]
//		System.out.println(month);
		
//===============================================================================================
		
//		/*
//		 * 练习:
//		 * 1、创建当前时间(不带时区)
//		 * 2、创建当前时间(只包含年月日)
//		 * 3、创建当前时间(包含年月日时分秒并带有时区)
//		 * 4、创建2012年12月31日7时38分46秒的日期对象,月份用枚举表示
//		 * 5、创建2012年12月31日的日期对象,月份用枚举表示
//		 * 6、创建7时38分46秒的时间对象
//		 */
//			
//		//1、创建当前时间(不带时区) 2022-08-14T20:18:59.063597700
//		LocalDateTime mLocalDateTime = LocalDateTime.now();
//		System.out.println(mLocalDateTime);
//		//2、创建当前时间(只包含年月日) 2022-08-14
//		LocalDate mLocalDate = LocalDate.now();
//		System.out.println(mLocalDate);
//		//3、创建当前时间(包含年月日时分秒并带有时区) 2022-08-14T20:18:59.064594800+08:00[Asia/Shanghai]
//		ZonedDateTime mZonedDateTime = ZonedDateTime.now();
//		System.out.println(mZonedDateTime);
//		//4、创建2012年12月31日7时38分46秒的日期对象,月份用枚举表示 2012-12-31T07:38:46
//		LocalDateTime mLocalDateTime2 = LocalDateTime.of(2012, Month.DECEMBER, 31, 7, 38, 46);
//		System.out.println(mLocalDateTime2);
//		//5、创建2012年12月31日的日期对象,月份用枚举表示 2012-12-31
//		LocalDate mLocalDate2 = LocalDate.of(2012, Month.DECEMBER, 31);
//		System.out.println(mLocalDate2);
//		//6、创建7时38分46秒的时间对象 07:38:46
//		LocalTime mLocalTime = LocalTime.of(7, 38, 46);	
//		System.out.println(mLocalTime);

//===============================================================================================
		
//		/*
//		 * 1、想要修改某个日期/时间对象的现有实例时,我们可以使用 plus和 minus方法来完成操作。
//		 * 2、Java8中日期时间相关的API中的所有实例都是不可改变的,一旦创建LocalDate,LocalTime,LocalDateTime
//		 *    就无法修改他们(类似于String),这对于线程安全时非常有利的。
//		 * 3、plus方法在LocalDate中的使用:
//		 * LocalDate.plusDays(long days);     //增加天数
//		 * LocalDate.plusWeeks(long weeks);   //增加周数
//		 * LocalDate.plusMonths(long months); //增加月数
//		 * LocalDate.plusYears(long years);   //增加年数
//		 * minus方法类似
//		 */
//		
//		//封装LocalDate对象,设置当前时间的参数是2016年2月13号
//		LocalDate mLocalDate = LocalDate.of(2016, Month.FEBRUARY, 13);
//		//当前的时间是:2016-02-13
//		System.out.println("当前的时间是:" + mLocalDate);
//		//计算当前时间4天后的时间, *注意:返回的是一个新的对象
//		LocalDate mLocalDate1 = mLocalDate.plusDays(4);	
//		//当前时间四天后是:2016-02-17
//		System.out.println("当前时间四天后是:" + mLocalDate1);
//		//计算当前时间3周后的时间
//		LocalDate mLocalDate2 = mLocalDate.plusWeeks(3);
//		//当前时间三周后是:2016-03-05  *三周后确定是3月5号?好像不对吧。。
//		System.out.println("当前时间三周后是:" + mLocalDate2);
//		//计算当前时间5个月后的时间
//		LocalDate mLocalDate3 = mLocalDate.plusMonths(5);
//		//当前时间五个月后是:2016-07-13
//		System.out.println("当前时间五个月后是:" + mLocalDate3);
//		//计算当前时间2年后的时间
//		LocalDate mLocalDate4 = mLocalDate.plusYears(2);
//		//当前时间两年后是:2018-02-13
//		System.out.println("当前时间两年后是:" + mLocalDate4);
		
//===============================================================================================
		
//		/*
//		 * plus方法在LocalTime中的使用
//		 * LocalTime.plusNanos(long nanos);   	//增加纳秒
//		 * LocalTime.plusSeconds(long seconds);	//增加秒数
//		 * LocalTime.plusMinutes(long minutes); //增加分钟
//		 * LocalTime.plusHours(long hours);		//增加小时
//		 * minus方法类似
//		 */
//		
//		//封装LocalTime对象,并设置当前时间参数为8点14分39秒218纳秒
//		LocalTime mLocalTime = LocalTime.of(8, 14, 39, 218);
//		//当前时间是:08:14:39.000000218
//		System.out.println("当前时间是:" + mLocalTime);
//		//就算当前时间500纳秒后并打印
//		LocalTime mLocalTime2 = mLocalTime.plusNanos(500);
//		//当前时间500纳秒后是:08:14:39.000000718
//		System.out.println("当前时间500纳秒后是:" + mLocalTime2);
//		//计算当前时间45秒后的时间并打印
//		LocalTime mLocalTime3 = mLocalTime.plusSeconds(45);
//		//当前时间45秒后是:08:15:24.000000218
//		System.out.println("当前时间45秒后是:" + mLocalTime3);
//		//计算当前时间19分钟后的而时间并打印
//		LocalTime mLocalTime4 = mLocalTime.plusMinutes(19);
//		//当前时间19分钟后是:08:33:39.000000218
//		System.out.println("当前时间19分钟后是:" + mLocalTime4);
//		//计算当前时间3小时后的时间并打印
//		LocalTime mLocalTime5 = mLocalTime.plusHours(3);
//		//当前时间3小时后是:11:14:39.000000218
//		System.out.println("当前时间3小时后是:" + mLocalTime5);
		
//===============================================================================================
		
//		/*
//		 * plus方法的单独使用方式 1
//		 * 1、以minus开头的方法对应的即为减少,实际上minus方法调用的也是plus方法,只不过传入的参数是负数
//		 * 2、LocalTime.plus(long amountToadd, TemporalUnit unit));
//		 * 	  LocalTime.plus(TemporalAmount amoutToadd);
//		 * 3、emporalAmount 是一个接口,当接口作为方法的参数的时候,实际上传入的是接口的实现类对象,
//		 * 	根据查看这个接口的体系,可以看到这个接口有一个实现类,名字叫做Period,表示一段时间。
//		 * 4、如何使用Period来表示一段时间呢?这个类本身提供了of(int year, int month, int day)来表示,
//		 * 	例如:Period.of(1,2,3)返回的对象即为1年2个月3天这么一个时间段。
//		 */
//
//		//车险还有2年3个月8天到期,计算到期时间
//		//1、封装当前时间
//		LocalDateTime mNow = LocalDateTime.now();
//		//2、在当前时间的基础上进行 +2年,+3月,+8天的操作
//		//  然后获得一个截止日期对象,这个对象表示的时间就是保险到期的时间
//		LocalDateTime mEndTime = mNow.plusYears(2).plusMonths(3).plusDays(8);
//		//当前时间是:2022-08-14T21:22:50.506700900,保险到期时间是:2024-11-22T21:22:50.506700900
//		System.out.println("当前时间是:" + mNow + ",保险到期时间是:" + mEndTime);
//		
//		//plus(TemporalAmount amoutToadd);
//		//1、首先封装period.of()方法穿进去参数
//		Period mPeriod = Period.of(2, 3, 8);
//		//2、通过plus方法传进去
//		LocalDateTime mEndTime2 = mNow.plus(mPeriod);
//		//当前时间是:2022-08-14T21:22:50.506700900,保险到期时间是:2024-11-22T21:22:50.506700900
//		System.out.println("当前时间是:" + mNow + ",保险到期时间是:" + mEndTime2);
		
//===============================================================================================
		
//		/*
//		 * plus方法的单独使用方式 2
//		 * TemporalUnit是一个接口,通过查看体系接口发现,可以使用子类ChronoUnit来表示,ChronoUnit封装了很多时间段供我们使用。
//		 */
//		
//		//结婚10年为锡婚,2020年2月2日11时11分11秒称为对称日,如果那天结婚了,锡婚会在什么时候?
//		//封装一个日期,表示结婚时间点
//		LocalDateTime mMarriedTime = LocalDateTime.of(2020, Month.FEBRUARY, 2, 11, 11, 11);
//		//用plus方法进行计算
//		LocalDateTime mTime = mMarriedTime.plus(1,ChronoUnit.DECADES);
//		//如果在 2020-02-02T11:11:11 结婚,那么锡婚在 2030-02-02T11:11:11
//		System.out.println("如果在 " + mMarriedTime + " 结婚,那么锡婚在 " + mTime);
//		//如果锡婚后的半天需要请所有亲戚朋友吃饭,计算吃饭的时间节点
//		LocalDateTime mEat = mTime.plus(1,ChronoUnit.HALF_DAYS);
//		//吃饭的时间是:2030-02-02T23:11:11
//		System.out.println("吃饭的时间是:" + mEat);
		
//===============================================================================================
		
//		/*
//		 * with方法在LocalDateTime类的应用 1
//		 * 如果不需要对日期进行加减而是要直接修改日期的话,那么可以使用with方法,with方法提供了很多种修改时间的方式
//		 * LocalDateTime.withNano(int i);		//修改纳秒
//		 * LocalDateTime.withSecond(int i);		//修改秒
//		 * LocalDateTime.withMinute(int i);		//修改分钟
//		 * LocalDateTime.withHour(int i);		//修改小时
//		 * LocalDateTime.withDayOfMonth(int i);	//修改天
//		 * LocalDateTime.withMonth(int i);		//修改月份
//		 * LocalDateTime.withYear(int i);		//修改年
//		 */
//		
//		LocalDateTime mLocalDateTime = LocalDateTime.of(1999, Month.DECEMBER,12, 12, 12, 0);
//		//当前时间:1999-12-12T12:12
//		System.out.println("当前时间:" + mLocalDateTime);
//		//若发现mLocalDateTime的日期有误,需要将日期修改为1号
//		//在不知道具体时间的情况下,无法直接进行增减操作,需要使用with方法进行修改
//		LocalDateTime mResultTime = mLocalDateTime.withDayOfMonth(1);
//		//修改后的时间:1999-12-01T12:12
//		System.out.println("修改后的时间:" + mResultTime);
		
//===============================================================================================
		
//		/*
//		 * with方法在LocalDateTime类的应用 2
//		 * 
//		 * with(TemporalField field, long newValue)
//		 *
//		 * temporalField是一个接口,通过查看体系结构,可以使用它的子类
//		 * ChronoField,ChronoField中封装了一些日期时间中的组成成分,可以直接选择之后传入第二个参数进行修改。
//		 * 例如:with(ChronoField.DAY_OFMONTH,1);将日期中的月份中的天数改为1
//		 * 例如:with(ChronoField.YEAR,2021);将日期中的年份改为2021。
//		 */
//		
//		LocalDateTime mLocalDateTime = LocalDateTime.of(1999, Month.DECEMBER,12, 12, 12, 0);
//		//当前时间:1999-12-12T12:12
//		System.out.println("当前时间:" + mLocalDateTime);
//		//若发现mLocalDateTime的日期有误,需要将日期修改为1号
//		//在不知道具体时间的情况下,无法直接进行增减操作,需要使用with方法进行修改
//		LocalDateTime mResultTime = mLocalDateTime.with(ChronoField.DAY_OF_MONTH,1);
//		//修改后的时间:1999-12-01T12:12
//		System.out.println("修改后的时间:" + mResultTime);
		
//===============================================================================================
		
//		/*
//		 * 调节器TemporalAdjuster
//		 * 1、通过with方法可以修改日期时间对象中封装的数据,有一些时候可能会做一些复杂的操作,
//		 *  比如说将时间调整到下个周的周日,下一个工作日,或者本月中的某一天,这个时候可以使用调节器
//		 *  TemporalAdjuster来更方便的处理日期。
//		 * 2、使用方式:
//		 *  with(TemporalAdjuster adjuster)
//		 *  需要传入一个TemporalAdjuster对象,通过查看发现TemporalAdjuster是一个接口,
//		 *  那么实际上传入的是这个接口的实现类对象。
//		 * 3、TemporalAdjusters类常用的静态方法:
//		 * 1)、static TemporalAdjusters.firstDayofNextMonth()   //下个月的第一天
//		 * 2)、static TemporalAdjusters.firstDayOfNextYear()   	//下一年的第一天
//		 * 3)、static TemporalAdjusters.firstDayOfYear()    	//当年的第一天
//		 * 4、通过with方法传入TemporalAdjuster类的实现对象,就可以进行修改,实现类对象是由TemporalAdjuseters类
//		 *  的静态方法来实现。
//		 * 5、注意:TemporalAdjusters 是一个接口,with方法实际上传入的是这个接口的实现类对象,TemporalAdjusters
//		 *  并不是TemporalAdjuster的实现类,只不过TemporalAdjusters的静态方法实现了TemporalAdjuster,
//		 *  并且将实现类对象返回了。
//		 */
//		
//		//封装日期对象为当前时间
//		LocalDate mNow = LocalDate.now();
//		//当前时间:2022-08-15
//		System.out.println("当前时间:" + mNow);
//		//修改时间为当月的第一天
//		LocalDate mFirstDayOfMonth = mNow.with(TemporalAdjusters.firstDayOfMonth());
//		//将时间修改为当月的第一天,具体时间为:2022-08-01
//		System.out.println("将时间修改为当月的第一天,具体时间为:" + mFirstDayOfMonth);
//		//修改时间为下个月的第一天
//		LocalDate mFirstDayOfNextMonth = mNow.with(TemporalAdjusters.firstDayOfNextMonth());
//		//将时间修改为下个月的第一天,具体时间为:2022-09-01
//		System.out.println("将时间修改为下个月的第一天,具体时间为:" + mFirstDayOfNextMonth);
//		//修改时间为下一年的第一天
//		LocalDate mFirstDayOfNextYear = mNow.with(TemporalAdjusters.firstDayOfNextYear());
//		//将时间修改为下一年的第一天,具体时间为:2023-01-01
//		System.out.println("将时间修改为下一年的第一天,具体时间为:" + mFirstDayOfNextYear);
//		//修改时间为当年的第一天
//		LocalDate mFirstDayOfYear = mNow.with(TemporalAdjusters.firstDayOfYear());
//		//将时间修改为当年的第一天,具体时间为:2022-01-01
//		System.out.println("将时间修改为当年的第一天,具体时间为:" + mFirstDayOfYear);
//		//修改时间为当月的最后一天
//		LocalDate mLastDayOfMonth = mNow.with(TemporalAdjusters.lastDayOfMonth());
//		//将时间修改为当月的最后一天,具体时间为:2022-08-31
//		System.out.println("将时间修改为当月的最后一天,具体时间为:" + mLastDayOfMonth);
//		//修改时间为当年的最后一天
//		LocalDate mLastDayOfYear = mNow.with(TemporalAdjusters.lastDayOfYear());
//		//将时间修改为当年的最后一天,具体时间为:2022-12-31
//		System.out.println("将时间修改为当年的最后一天,具体时间为:" + mLastDayOfYear);
		
//===============================================================================================
		
//		/*
//		 * DayOfWeek枚举类封装了从周一到周日
//		 */
//		
//		//封装当前日期
//		LocalDate mNow = LocalDate.now();
//		//当前日期为:2022-08-15
//		System.out.println("当前日期为:" + mNow);
//		//将当前时间修改为下一个周日
//		LocalDate mNextSunday = mNow.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
//		//下一个周日是:2022-08-21
//		System.out.println("下一个周日是:" + mNextSunday);
//		//将时间修改为上一个周三
//		LocalDate mPreviousWednesday = mNow.with(TemporalAdjusters.previous(DayOfWeek.WEDNESDAY));
//		//上一个周三是:2022-08-10
//		System.out.println("上一个周三是:" + mPreviousWednesday);
		
//===============================================================================================
		
//		/*
//		 * 自定义TemporalAdjuster调节器:
//		 * 通过Java8本身提供的TemporalAdjusters中的方法可以完成一些常用的操作,
//		 * 如果要自定义日期时间的更改逻辑,可以通过实现TemporalAdjuster类接口的方式来完成。
//		 * 1、创建类实现TemporalAdjuster接口
//		 * 2、实现TemporalAdjuster中的 adjusterInto()方法,传入一个日期时间对象,完成逻辑之后返回日期事件对象。
//		 * 3、通过with方法传入自定义调节器对象完成更改。
//		 * 
//		 * 例如:假如员工一个月中领取工资,发薪日是每个月的15日,如果发薪日是周末,则调整为周五。
//		 */
//		
//		//1、创建PayDayAdjuster类,并实现TemporalAdjuster接口
//		//2、封装LocalDate对象,设置参数为2022年5月1号
//		LocalDate mPayDay = LocalDate.of(2022, Month.MAY, 1);
//		//3、计算真实发薪日
//		LocalDate mRealPayDay = LocalDate.from(new PayDayAdjuster().adjustInto(mPayDay));
//		//预计发薪日:2022年5月15日
//		System.out.println("预计发薪日:" + mPayDay.getYear() + "年" + mPayDay.getMonthValue() + "月15日");
//		//实际发薪日:2022-05-13
//		System.out.println("实际发薪日:" + mRealPayDay);
		
//===============================================================================================
		
//		/*
//		 * TemporalQuery的使用:
//		 * 1、query方法可以对日期进行查询,使用方式:
//		 *   R query(TemporalQuery query)
//		 *   这是一个泛型方法,返回的数据就是传入的泛型类的类型,TemporalQuery是一个泛型接口,里面有一个抽象方法
//		 *   是R queryFrom(TemporalAccessor temporal),TemporalAccessor是Temporal的父接口,实际上也就是
//		 *   LocalDate,LocalDateTime相关类的顶级父接口,这个queryFrom的方法的实现逻辑就是,传入一个日期/时间
//		 *   对象通过自定义逻辑返回数据。
//		 * 2、如果要计算某日期距离某一天(特定)差距多少天,可以自定义类实现TemporalQuery接口并且作为参数传到
//		 *   query方法中。
//		 *   
//		 * 例如:计算当前时间距离下一个劳动节还有多少天?
//		 */
//		
//		//创建UtilDayQueryImpl类,并实现TemporalQuery<>接口,泛型设置为 Long 型
//		//封装当前日期
//		LocalDate mNow = LocalDate.now();
//		//计算当前日期距离下一个劳动节的天数,调用query方法,将已经实现类UtilDayQueryImpl作为参数传入
//		Long mDay = mNow.query(new UtilDayQueryImpl());
//		//当前日期:2022-08-15
//		System.out.println("当前日期:" + mNow);
//		//距离下一个劳动节的天数:259
//		System.out.println("距离下一个劳动节的天数:" + mDay);
		
//===============================================================================================
		
//		/*
//		 * parse和format方法:
//		 * 格式化类:DateTimeFormatter
//		 * 可以通过日期时间对象的parse和format方法直接进行转换
//		 */
//		
//		//将LocalDateTime对象初始化为当前时间
//		LocalDateTime mLocalDateTime = LocalDateTime.now();
//		//直接调用format方法进行格式化
//		String mStr1 = mLocalDateTime.format(DateTimeFormatter.ISO_DATE);
//		String mStr2 = mLocalDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
//		//LocalDateTime:2022-08-15T20:53:32.786227700
//		System.out.println("LocalDateTime:" + mLocalDateTime);
//		//ISO_DATE:2022-08-15
//		System.out.println("ISO_DATE:" + mStr1);
//		//IOS_DATE_TIME:2022-08-15T20:53:32.7862277
//		System.out.println("IOS_DATE_TIME:" + mStr2);
//		//解析字符串:通过LocalDateTime的parse方法解析
//		LocalDateTime mParse = LocalDateTime.parse(mStr2);
//		//解析ISO_DATE_TIME格式化后的字符串,得到的LocalDateTime为:2022-08-15T20:53:32.786227700
//		System.out.println("解析ISO_DATE_TIME格式化后的字符串,得到的LocalDateTime为:" + mParse);
		
//===============================================================================================
		
//		/*
//		 * 通过DateTimeFormatter的ofLocalizedDate的方法也可以调整格式化的方式
//		 * 此方法需要传入一个FormatStyle类对象,FormaStyle对象是一个枚举类,其中有几种方式:
//		 * FULL:全显示(年月日+星期) 全文风格
//		 * LONG:全显示(年月日) 长文字风格
//		 * MEDIUM:中等文字风格 
//		 * SHORT:精简显示  短文本样式,通常为数字
//		 */
//		
//		//将LocalDateTime对象初始化为当前时间
//		LocalDateTime mLocalDateTime = LocalDateTime.now();
//		//通过DateTimeFormatter的ofLocalizedDate指定格式化格式
//		String mStr1 = mLocalDateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
//		String mStr2 = mLocalDateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));
//		String mStr3 = mLocalDateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM));
//		String mStr4 = mLocalDateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));
//		//FULL:2022年8月15日星期一
//		System.out.println("FULL:" + mStr1);
//		//LONG:2022年8月15日
//		System.out.println("LONG:" + mStr2);
//		//MEDIUM:2022年8月15日
//		System.out.println("MEDIUM:" + mStr3);
//		//SHORT:2022/8/15
//		System.out.println("SHORT:" + mStr4);
		
//===============================================================================================
		
//		/*
//		 * 自定义格式化器
//		 * 通过DateTimeFormatter类提供的ofPattern方法创建自定时格式化器
//		 */
//		
//		//将LocalDateTime对象初始化为当前时间
//		LocalDateTime mLocalDateTime = LocalDateTime.now();
//		//通过DateTimeFormatter类提供的ofPattern方法自定义格式化格式
//		String mStr = mLocalDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd cccc hh:mm:ss"));
//		//当前时间:2022-08-15T21:17:54.505236100
//		System.out.println("当前时间:" + mLocalDateTime);
//		//格式化后的时间:2022-08-15 星期一 09:17:54
//		System.out.println("格式化后的时间:" + mStr);
		
	}

}

两个实现接口的类:

1、

package com.my.timetest;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;

/**
 * 
 * @author Zhang
 * 
 * 输入一个日期,判断真实发薪日:
 * 
 * 假如员工一个月中领取工资,发薪日是每个月的15号,如果发薪日是周末,则调整为周五。
 * 
 * 传入一个日期时间对象,判断是不是15号,如果不是就修改为15号,如果是周六或者周日就修改为周五(上一个)。
 *
 */
public class PayDayAdjuster implements TemporalAdjuster {

	@Override
	public Temporal adjustInto(Temporal temporal) {

		//Temporal是time包下所有日期时间类对象的顶级父接口,
		//实际上可以理解为传入的是LocalDate或LocalTime对象
		//1、需要将Temporal转换为LocalDate对象
		LocalDate mPayDay = LocalDate.from(temporal);
		//2、判断当前封装的时间是不是15号,如果不是就修改为15号
		int mDay ;
		if(mPayDay.getDayOfMonth() != 15) {
			mDay = 15;
		}else {
			mDay = mPayDay.getDayOfMonth();
		}		
		//将发薪日的日期改为15号
		LocalDate mRealPayDay = mPayDay.withDayOfMonth(mDay);
		//判断发薪日的星期数是不是周六、周日,如果是就修改为上一个周五
		if(mRealPayDay.getDayOfWeek() == DayOfWeek.SATURDAY || mRealPayDay.getDayOfWeek() == DayOfWeek.SUNDAY) {
			//发薪日是周末,则修改日期为上一个周五
			mRealPayDay = mRealPayDay.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
		}
		
		return mRealPayDay;
	}

}

2、

package com.my.timetest;

import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQuery;

/**
 * 
 * @author Zhang
 * 
 * 获取距离下一个劳动节实际天数的实现类
 * 
 */
public class UtilDayQueryImpl implements TemporalQuery<Long> {

	@Override
	public Long queryFrom(TemporalAccessor temporal) {
		
		//1、TemppralAccessor是localDateTime的顶级父接口,相当于LocalDate就是
		// 这个接口,将Temporal转换为LocalDate使用
		LocalDate mNow = LocalDate.from(temporal);
		//2、将当年的劳动节时间封装到LocalDate中
		LocalDate mLaborDay = LocalDate.of(mNow.getYear(), Month.MAY, 1);
		//3、判断当前时间是否已经过了当年的劳动节,如果超过了就计算下一年的劳动节
		if(mNow.isAfter(mLaborDay)) {
			mLaborDay = mLaborDay.plusYears(1);
		}
		//通过ChronoUnit的between来计算两个时间点的差值
		long mDay = ChronoUnit.DAYS.between(mNow, mLaborDay);
		
		return mDay;
	}

}

工程结构:初学者可直接参照,复制代码即可运行。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值