我奶奶都能懂java8特性-日期时间
Posted 浦江之首
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我奶奶都能懂java8特性-日期时间相关的知识,希望对你有一定的参考价值。
java每个版本的更新,都会给java使用者极大的方便。其中,java8中的日期时间较之前的版本的进步的不是一个数量级,java8的问世,之前的很多方法都已被弃用。借着这次针对java8基础的考试,本博客介绍一下之前版本的问题,以及java8版本的使用。示例的源码可以直接通过csdn下载也可以通过git导出:https://github.com/igdnss/java8_date-time.git
之前版本
老版本中提供的日期时间处理的两个重要的类为java.util.Date,java.util.Calendar
。由于老版本的日期时间处理存在很多问题,因此很多方法都已经弃用 。例如,日期计算问题,存在线程不安全的问题。
示例
1,日期计算问题
某一商品生产日期为:2019年10月12日,距离当前有多少天。写起来真的很麻烦,我自己感觉都快疯了。
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
public class ProductDate {
public static void main(String[] args) {
//当前日期
Date currentDate = new Date();
//将日期转为long,方便计算(以格林维治为基础)
long currentTime = currentDate.getTime();
//定义商品生产日期
Calendar productDate1 = Calendar.getInstance();
//calendar中月份从0开始的,所以10月对应的应该是9,炸了。。。
productDate1.set(2019, 9, 12);
//将calendar 转换为date
Date productDateFinal = productDate1.getTime();
long productDateFinalTime = productDateFinal.getTime();
//计算相隔的天数,算了算去,结果还不知道对不对。又炸一次
long intervalDay1 = (currentTime-productDateFinalTime)/1000/60/60/24;
System.out.println("老版本实现商品距离今日有:"+intervalDay1+"天");
//java8 实现,一行代码
long intervalDay2 = ChronoUnit.DAYS.between(LocalDate.of(2019, 10, 12), LocalDate.now());
System.out.println("java8实现商品距离今日有:"+intervalDay2+"天");
}
}
2,线程安全问题
创建20个线程,每个线程里以同样的格式创建一个日期。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateThreadSafe {
final static SimpleDateFormat TEST = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
public static void main(String[] args) {
// 20个线程,创建日期
for (int i = 0; i < 20; i++) {
Runnable runnable = () -> {
Date date = null;
try {
date = TEST.parse("2020-11-11 10:10:10");
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
};
new Thread(runnable).start();
}
}
}
结果中报NumberFormatException,至于原因大家自己去看一下源码,有一个clear函数。
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at date.DateThreadSafe.lambda$0(DateThreadSafe.java:17)
at java.lang.Thread.run(Thread.java:748)
java8版本
这里介绍一下常用的一些类的常用用法,个人觉得这些基本能覆盖工作的需要,更深一步的学习,建议参考官方文档。但要强调一点的时,java8版本中的日期时间类生成的实例均为不可变的,它们是线程安全的,并且这些类不提供公共的构造方法,即不可以通过new来直接创建,而是通过工厂方法来创建。最常用的工厂方法有两个,now和of。另外还提供了三个修改日期的方法,plus,minus(内部也是使用plus实现的,不在举例),with。下文会对各个方法的使用作简单介绍。
Instant类
可以理解为某一精确的时间点,即时间戳,封装的时候为格林维治时间,常用于时间之间的转换。
Duration类
表示秒和纳秒的时间间隔,用于计算精确性较高的时间
Period类
表示一段时间的年、月、日
LocalDate类
表示一个不可变的日期对象,
LocalTime类
表示一个不可变的时间对象,包含纳秒部门
LocalDateTime类
表示一个不可变的日期时间对象,年-月-日 时-分-秒
ZoneDateTime类
表示一个具有时区的日期时间对象,存储了所示的日期和时间字段,精度为纳秒,时区为区域偏移量,用于处理模糊的本地日期时间。
使用
now方法的使用
根据当前时间或日期创建实例。接下来介绍的类的实例都可以通过now方法来创建。
示例1
使用Now创建日期,时间等
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
public class NowExample1 {
public static void main(String[] args) {
Instant instant = Instant.now();
System.out.println("instant:"+instant);
LocalDate localDate = LocalDate.now();
System.out.println("localDate:"+localDate);
LocalTime localTime = LocalTime.now();
System.out.println("localTime:"+localTime);
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime:"+localDateTime);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("zonedDateTime:"+zonedDateTime);
}
}
=====result=====
instant:2021-05-27T13:47:47.651Z //格林维治时间
localDate:2021-05-27
localTime:21:47:47.701 //后三位表示纳秒
localDateTime:2021-05-27T21:47:47.701//后三位表示纳秒
zonedDateTime:2021-05-27T21:47:47.701+08:00[Asia/Shanghai] //东8区
示例2
使用Now创建年,月,日
import java.time.MonthDay;
import java.time.Year;
import java.time.YearMonth;
public class NowExample2 {
public static void main(String[] args) {
Year year = Year.now();
System.out.println("year:"+year);
YearMonth yearMonth = YearMonth.now();
System.out.println("yearMonth:"+yearMonth);
MonthDay monthDay = MonthDay.now();
System.out.println("monthDay:"+monthDay);
}
}
=====result=====
year:2021
yearMonth:2021-05
monthDay:--05-27
of方法的使用
now是根据当前时间或日期创建实例,如果需要创建指定的日期和时间那么就需要借助of方法来完成。接下来介绍的类的实例都可以通过now方法来创建。
示例
创建指定的LocalDate对象
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class OfExample1 {
public static void main(String[] args) {
// 创建指定的LocalDate对象-- 2025-06-01,其中月份可以使用Month的枚举
LocalDate localDate = LocalDate.of(2025, 06, 01);
System.out.println("localDate:"+localDate);
//创建指定的LocalTime对象--17:00
LocalTime localTime = LocalTime.of(17, 0);//还有其它的形式,读都可以自己试试
System.out.println(localTime);
//第一种方法,创建指定的LocalDateTime对象--2025-06-01 17:00
LocalDateTime localDateTime1 = LocalDateTime.of(2025, 06, 01, 17, 0);
System.out.println("localDateTime1:"+localDateTime1);
//第二种方法,创建指定的LocalDateTime对象--2025-06-01 17:00
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
System.out.println("localDateTime2:"+localDateTime2);
//为LocalDateTime添加时区
ZonedDateTime atZone = localDateTime2.atZone(ZoneId.of("Asia/Shanghai"));//zoneId可以通过ZoneId.getAvailableZoneIds()获取
System.out.println("atZone: "+atZone);
}
}
plus方法的使用
plus可以实现对LocalDate和LocalTime进行增加的功能。
LoalDate
//增加天数
LocalDate plusDays(long days)
//增加周数
LocalDate plusWeeks(long weeks)
//增加月数
LocalDate plusMonths(long months)
//增加年数
LocalDate plusYears(long years)
示例
在当前的日期基础上做各种增加操作
import java.time.LocalDate;
import java.time.Month;
public class PlusDate {
public static void main(String[] args) {
LocalDate localDate = LocalDate.of(2025, Month.JUNE, 1);
System.out.println("localDate : "+localDate);
//增加5天
LocalDate localDatePlus5Days = localDate.plusDays(5);
System.out.println("localDatePlus5Days : "+localDatePlus5Days);
//增加1周
LocalDate localDatePlus1Week = localDate.plusWeeks(1);
System.out.println("localDatePlus1Week : "+localDatePlus1Week );
//增加1月
LocalDate localDatePlus1Month = localDate.plusMonths(1);
System.out.println("localDatePlus1Month : "+localDatePlus1Month );
//增加1年
LocalDate localDatePlus1Year = localDate.plusYears(1);
System.out.println("localDatePlus1Year : "+localDatePlus1Year);
//增加1年1个月
LocalDate localDatePlus1YearAnd1Month = localDate.plusYears(1).plusMonths(1);
System.out.println("localDatePlus1Year : "+localDatePlus1YearAnd1Month);
}
}
LocalTime
//增加纳秒
LocalTime plusNanos(long nanos)
//增加秒
LocalTime plusSeconds(long seconds)
//增加分钟
LocalTime plusMinutes(long minutes)
//增加小时
LocalTime plusHours(long hours)
示例
在当前的时间基础上做各种增加操作
import java.time.LocalTime;
public class PlusTime {
public static void main(String[] args) {
LocalTime localTime = LocalTime.of(11, 49, 11, 500);
System.out.println("localTime : "+localTime);
//增加100纳秒
LocalTime plus100Nanos = localTime.plusNanos(100);
System.out.println("plus100Nanos : "+plus100Nanos);
//增加9秒
LocalTime plus9Seconds = localTime.plusSeconds(9);
System.out.println("plus9Seconds : "+plus9Seconds);
//增加1分钟
LocalTime plusMinutes = localTime.plusMinutes(1);
System.out.println("plusMinutes : "+plusMinutes);
//增加1小时
LocalTime plus1Hours = localTime.plusHours(1);
System.out.println("plus1Hours : "+plus1Hours);
//增加1小时1分钟
LocalTime plus1Hour1Minute = localTime.plusHours(1).plusMinutes(1);
System.out.println("plus1Hour1Minute : "+plus1Hour1Minute);
}
}
Period
示例
在当前时间的基础上加1年两个月零3天
import java.time.LocalDate;
import java.time.Period;
public class Plus1 {
public static void main(String[] args) {
//在当前时间的基础上加1年两个月零3天
LocalDate now = LocalDate.now();
System.out.println("now:"+now);
//方法1
LocalDate plusPeriod1 = now.plusYears(1).plusMonths(2).plusDays(3);
System.out.println("plusPeriod1: " +plusPeriod1);
//方法2
Period period = Period.of(1, 2, 3);
LocalDate plusPeriod2 = now.plus(period);
System.out.println("plusPeriod2: " +plusPeriod2);
}
}
ChronoUnit
ChronoUnit提供了一系列方便日期运算的枚举,例如10年,100年,1个世纪等。
示例
在原有的日期基础上增加20年
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoUnit;
public class ChronoUnitPlus {
public static void main(String[] args) {
LocalDate localDate = LocalDate.of(2024, Month.MAY,3);
System.out.println(以上是关于我奶奶都能懂java8特性-日期时间的主要内容,如果未能解决你的问题,请参考以下文章