java日期时间类运算Date,Calendar,LocalDateTime(详细用法)

发布时间 2023-11-23 10:09:54作者: 于上山之明月

✨前言✨
本片文章,主要在于使用Date,Calendar,LocalDateTime三种时间类,进行日期之间的运算,及使用

?欢迎点赞 ? 收藏 ⭐留言评论 ?私信必回哟?
?博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言

@

? 一,Date类型

1,获取当前时间

Date date=new Date();

2,获取年月日

Date date=new Date();
//获取指定日期的年
String year=String.format("%tY", date);
//获取指定日期的月
String mon=String .format("%tm", date);
//获取指定日期的日
String day=String .format("%td", date);
//获取指定日期的时
String h=String .format("%tH", date);
//获取指定日期的分
String ms=String .format("%tM", date);
//获取指定日期的秒
String s=String .format("%tS", date);

3,计算日期和时间

// 创建两个日期对象
Date date1 = new Date(); // 第一个日期
Date date2 = new Date(); // 第二个日期

// 计算日期之间的毫秒差值
long differenceInMilliseconds = date2.getTime() - date1.getTime();
// 转换毫秒差值为天数
long differenceInDays = TimeUnit.MILLISECONDS.toDays(differenceInMilliseconds);
System.out.println("天数差值:" + differenceInDays + "天");

? 二,Calendar类型

1,获取当前日期及和Date类型转化

Calendar类,专门用于转换特定时刻和日历字段之间的日期和时间。

Calendar calendar = Calendar.getInstance(); // 获取日历的当前实例
Calendar calendar = Calendar.getInstance();
// 从一个 Calendar 对象中获取 Date 对象
Date date = calendar.getTime();
// 将 Date 对象反应到一个 Calendar 对象中,
// Calendar/GregorianCalendar 没有构造函数可以接受 Date 对象
// 所以我们必需先获得一个实例,然后设置 Date 对象
calendar.setTime(new Date());

2,获取和设置年,月,日

cal.get(Calendar.YEAR); 		// 获取年份
cal.get(Calendar.MONTH); 		// 获取月份 (注意:Calendar 的月份从 0 开始计数)
cal.get(Calendar.DAY_OF_MONTH); // 获取日期
cal.get(Calendar.HOUR_OF_DAY);  // 获取 24 小时制的小时数
cal.get(Calendar.MINUTE); 		// 获取分钟数
cal.get(Calendar.SECOND); 		// 获取秒数
 
// 设置日期和时间
cal.set(Calendar.YEAR, 2020);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);

3,计算日期和时间

cal.add(Calendar.YEAR, 1); 			// 在当前日期的基础上加 1 年
cal.add(Calendar.MONTH, 1); 		// 在当前日期的基础上加 1 个月
cal.add(Calendar.DAY_OF_MONTH, 1);  // 在当前日期的基础上加 1 天
cal.add(Calendar.HOUR_OF_DAY, 1);   // 在当前日期的基础上加 1 小时
cal.add(Calendar.MINUTE, 1); 		// 在当前日期的基础上加 1 分钟
cal.add(Calendar.SECOND, 1); 		// 在当前日期的基础上加 1 秒

4,格式化日期和时间

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String strDate = sdf.format(cal.getTime()); // 将 Calendar 中的日期和时间格式化成字符串
System.out.println(strDate); 				// 输出格式化后的日期和时间

? 三,LocalDateTime类型

  • ZoneId: 时区ID,用来确定Instant和LocalDateTime互相转换的规则
  • Instant: 用来表示时间线上的一个点(瞬时)
  • LocalDate: 表示没有时区的日期, LocalDate是不可变并且线程安全的
  • LocalTime: 表示没有时区的时间, LocalTime是不可变并且线程安全的
  • LocalDateTime: 表示没有时区的日期时间, LocalDateTime是不可变并且线程安全的
  • Clock: 用于访问当前时刻、日期、时间,用到时区
  • Duration: 用秒和纳秒表示时间的数量(长短),用于计算两个日期的“时间”间隔
  • Period: 用于计算两个“日期”间隔

  其中,LocalDate、LocalTime、LocalDateTime是新API里的基础对象,绝大多数操作都是围绕这几个对象来进行的,有必要搞清楚:
LocalDate : 只含年月日的日期对象
LocalTime :只含时分秒的时间对象
LocalDateTime : 同时含有年月日时分秒的日期对象

1,根据指定日期/时间创建对象(以及获取当前时间)

//获取当前的时间
LocalDate localDate = LocalDate.now();			  //2023-11-20
LocalTime localTime = LocalTime.now();	 		  //20:04:15.448
LocalDateTime localDateTime = LocalDateTime.now();//2023-11-20T20:04:15.448
//根据指定日期/时间创建对象
LocalDate localDate = LocalDate.of(2023,11,20);
LocalTime localTime = LocalTime.of(20,10,30);
LocalDateTime localDateTime = LocalDateTime.of(2023,11,20,20,10,30);
//输出为
2023-11-20
20:10:30
2023-11-20T20:10:30

2,日期时间的加减

对于LocalDate,只有精度大于或等于日的加减,如年、月、日;
对于LocalTime,只有精度小于或等于时的加减,如时、分、秒、纳秒;
对于LocalDateTime,则可以进行任意精度的时间相加减;

 LocalDateTime localDateTime = LocalDateTime.now();
 //以下方法参数都是long类型,返回值都是LocalDateTime
LocalDateTime plusYearResult = localDateTime.plusYears(2L);
LocalDateTime plusMonthsResult = localDateTime.plusMonths(3L);
LocalDateTime plusDaysResult = localDateTime.plusDays(7L);
LocalDateTime plusHoursResult = localDateTime.plusHours(2L);
LocalDateTime plusMinutesResult = localDateTime.plusMinutes(10L);
LocalDateTime plusSecondsResult = localDateTime.plusSeconds(10L);

System.out.println("当前时间是:"+localDateTime+"\n"
                +"当前时间加2年后为:"+plusYearResult+"\n"
                +"当前时间加3个月后为:"+plusMonthsResult+"\n"
                +"当前时间加7日后为:"+plusDaysResult+"\n"
                +"当前时间加2小时后为:"+plusHoursResult+"\n"
                +"当前时间加10分钟后为:"+plusMinutesResult+"\n"
                +"当前时间加10秒后为:"+plusSecondsResult+"\n"
                );
                
//输出结果为:
当前时间是:2023-11-22T14:06:32.487
当前时间加2年后为:2025-11-22T14:06:32.487
当前时间加3个月后为:2024-02-22T14:06:32.487
当前时间加7日后为:2023-11-29T14:06:32.487
当前时间加2小时后为:2023-11-22T16:06:32.487
当前时间加10分钟后为:2023-11-22T14:16:32.487
当前时间加10秒后为:2023-11-22T14:06:42.487
//也可以已另一种方式来相加减日期,即plus (long amoutToAdd,TemoralUnit unit)
//  参数一表示: 要相加的数量      参数二表示: 相加的单位
LocalDateTime nextYear = localDateTime.plus(1, ChronoUnit.YEARS);
LocalDateTime nextMonth = localDateTime.plus(1, ChronoUnit.MONTHS);
LocalDateTime nextWeek = localDateTime.plus(1, ChronoUnit.WEEKS);

System.out.println("现在的时间:"+localDateTime+"\n"
		                +"当前时间加1年后:"+nextYear+"\n"
		                +"当前时间加1个月后:"+nextYear+"\n"
		                +"当前时间加1周后:"+nextYear+"\n");

//输出显示:
现在的时间:2023-11-22T15:13:16.618
当前时间加1年后:2024-11-22T15:13:16.618
当前时间加1个月后:2024-11-22T15:13:16.618
当前时间加1周后:2024-11-22T15:13:16.618

3,将年、月、日等修改为指定的值,并返回新的日期(时间)对象

其效果与时间日期相加减差不多,如今天是2023-11-22,要想变为2023-11-30有两种方式
a. localDate.plusDays(8L) -> 相加指定的天数
b. localDate.withDayOfYear(30) -> 直接指定到哪一天

LocalDate localDate = LocalDate.now();
//当前时间基础上,指定本年当中的第几天,取值范围为1-365,366
LocalDate withDayOfYearResult = localDate.withDayOfYear( 200);
//当前时间基础上,指定本月当中的第几天,取值范围为1-29,30,31
LocalDate withDayOfMonthResult = localDate.withDayOfMonth(5);
//当前时间基础上,直接指定年份
LocalDate withYearResult = localDate.withYear(2017);
//当前时间基础上,直接指定月份
LocalDate withMonthResult = localDate.withMonth(5);
        
System.out.println("当前时间是 :"+ localDate + "\n"
                +"指定本年当中的第200天 :"+ withDayOfYearResult +"\n"
                +"指定本月当中的第5天 :"+ withDayOfMonthResult + "\n"
                +"直接指定年份为2017 :" + withYearResult +"\n"
                +"直接指定月份为5月 :"+withMonthResult);
                
//输出结果为:
当前时间是 :2023-11-22
指定本年当中的第200天 :2023-07-19
指定本月当中的第5天 :2023-11-05
直接指定年份为2017 :2017-11-22
直接指定月份为5月 :2023-05-22

4,获取日期的年月日周时分秒

LocalDateTime localDateTime = LocalDateTime.now();
int dayOfYear = localDateTime .getDayOfYear();
int dayOfMonth = localDateTime.getDayOfMonth();
DayOfWeek dayofweek = localDateTime.getDayOfWeek();
System.out.println("今天是"+ localDateTime + "\n"
                + "本年当中第"+ dayOfYear +"天"+ "\n"
                +"本月当中第"+ dayOfMonth +"天"+ "\n"
                +"本周中星期"+ dayofweek.getValue() +"-即"+ dayofweek + "\n");

//输出显示为
今天是2023-11-22T15:37:18.390
本年当中第326天
本月当中第22天
本周中星期3-即WEDNESDAY

//获取当天时间的年月日时分秒
int year = localDateTime .getYear();
Month month = localDateTime .getMonth();
int day = localDateTime.getDayOfMonth();
int hour = localDateTime .getHour();
int minute = localDateTime .getMinute();
int second = localDateTime.getSecond();
System.out.println("今天是"+ localDateTime + "\n"
                +"年:"+ year + "\n"
                +"月:"+ month.getValue() + "-即"+ month + "\n"
                +"日:"+ day + "\n"
                +"时:" + hour + "\n"
                +"分:"+ minute + "\n"
                +"秒 :"+ second);

//输出显示
今天是2023-11-22T15:37:18.390
年:2023
月:11-即NOVEMBER
日:22
时:15
分:37
秒 :18

5,时间日期前后的比较与判断

//判断两个时间点的前后
LocalDate localDate1 = LocalDate.of(2023,1,1);
LocalDate localDate2 = LocalDate.of(2022,1,1);
boolean datelIsBeforeDate2 = localDate1.isBefore(localDate2);
System.out.println("date1IsBeforeDate2 : " + datelIsBeforeDate2);
//datelIsBeforeDate2 == false

//isBefore  表示在什么之前
//isAfter   表示在什么之后

6,时间转化,时间戳

事实上Instant就是java8以前的Date,
可以使用以下两个类中的方法在这两个类型之间进行转换,
比如Date.from(Instant)就是用来把Instant转换成java.util.date的,
而new Date().toInstant()就是将Date转换成Instant的

Instant instant = Instant.now();
//2023-11-22T07:45:02.313Z
System.out.println(instant);
Date date = Date.from(instant);
Instant instant2 = date.toInstant();
//Wed Nov 22 15:45:02 CST 2023
System.out.println(date);
//2023-11-22T07:45:02.313Z
System.out.println(instant2);

7,计算时间、日期间隔

Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔

//计算两个日期的日期间隔-年月日
LocalDate date1 = LocalDate.of(2018, 2, 13);
LocalDate date2 = LocalDate.of(2017, 3, 12);
//内部是用date2-date1,所以得到的结果是负数
Period period = Period.between(date1, date2);
System.out.println("相差年数 : " + period.getYears());
System.out.println("相差月数 : " + period.getMonths());
System.out.println("相差日数 : " + period.getDays());
//还可以这样获取相差的年月日
System.out.println("-------------------------------");
long years = period.get(ChronoUnit.YEARS);
long months = period.get(ChronoUnit.MONTHS);
long days = period.get(ChronoUnit.DAYS);
System.out.println("相差的年月日分别为 : " + years + "," + months + "," + days);
//注意,当获取两个日期的间隔时,并不是单纯的年月日对应的数字相加减,
//而是会先算出具体差多少天,在折算成相差几年几月几日的
        
//计算两个时间的间隔
System.out.println("-------------------------------");
LocalDateTime date3 = LocalDateTime.now();
LocalDateTime date4 = LocalDateTime.of(2018, 1, 13, 22, 30, 10);
Duration duration = Duration.between(date3, date4);
System.out.println(date3 + " 与 " + date4 + " 间隔  " + "\n"
        + " 天 :" + duration.toDays() + "\n"
        + " 时 :" + duration.toHours() + "\n"
        + " 分 :" + duration.toMinutes() + "\n"
        + " 毫秒 :" + duration.toMillis() + "\n"
        + " 纳秒 :" + duration.toNanos() + "\n"
        );
//注意,并没有获得秒差的,但既然可以获得毫秒,秒就可以自行获取了

输出显示为:

在这里插入图片描述

8,当计算程序的运行时间时,应当使用时间戳Instant

Instant ins1 = Instant.now();
for (int i = 0; i < 10080880; i++) {
     //循环一百万次
}
Instant ins2 = Instant.now();
Duration duration = Duration.between(ins1, ins2);
System.out.println("程序运行耗时为 : "
     + duration.toMillis() +"毫秒");

9,使用自定义格式

LocalDateTime date1 = LocalDateTime.now();
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年M月d日 HH:mm:ss");
String date2Str = formatter2.format( date1);
System.out.println(date2Str);

//输出显示为:
2023年11月22日 15:56:41

自定义转化的格式一定要与日期类型对应
LocalDate只能设置仅含年月日的格式
LocalTime只能设置仅含时分秒的格式
LocalDateTime可以设置含年月日时分秒的格式

DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(formatter3.format(LocalDate.now()));
System.out.println("————————————————————————————————");
DateTimeFormatter formatter4 = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(formatter4.format(LocalTime.now()));

//输出显示为
2023-11-22
————————————————————————————————
16:03:44

10,将时间字符串形式转化为日期对象

String datetime = "2023-11-13 21:27:30";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse(datetime, dtf);
System.out.println(ldt);

//输出显示为:
2023-11-13T21:27:30

注:格式的写法必须与字符串的形式一样

如:
2023-11-13 21:27:30 对应 yyyy-MM-dd HH:mm:ss
20231113213328 对应 yyyyMMddHHmmss 否则会报运行时异常!

但要记住:
得到的最终结果都是类似2018-01-13T21:27:30的格式,
因为在输出LocalDateTime对象时,会调用其重写的toString方法。

@Override
public String toString() {
    return date.toString()+"T"+time.toString();
}

11,将时间日期对象转为格式化后的时间日期对象

 //新的格式化API中,格式化后的结果都默认是string,有时我们也需要返回经过格式化的同类型对象
LocalDateTime ldt1 = LocalDateTime.now();
DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String temp = dtf1.format(ldt1);
LocalDateTime formatedDateTime = LocalDateTime.parse(temp, dtf1);
System.out.println(formatedDateTime);

//输出显示为:
2023-11-22T16:10:23

12,long毫秒值转换为日期

System.out.println("--long毫秒值转换为日期--");
DateTimeFormatter df= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String longToDateTime = df.format(LocalDateTime.ofInstant(
		Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
System.out.println(longToDateTime);

//输出显示为:
--long毫秒值转换为日期--
2023-11-22 16:12:44

✨最后✨

总结不易,希望uu们不要吝啬你们的?哟(^U^)ノ~YO!!
如有问题,欢迎评论区批评指正?