java--1.8时间API

目录

概述

多线程安全问题

新时间日期的API

日期的操纵

DateTimeFormatter: 格式化时间/日期


概述

之前的时间API大部分过时过期的,都是线程不安全的,可变的;

新的API在java.time包下,整体都是不可变线程安全的,较之前的有规律许多;

多线程安全问题

jdk1.7

 @Test
     public void test01() throws Exception{
          //指定时间日期格式
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
          Callable<Date> dateCallable = () -> {
               return simpleDateFormat.parse("2016-11-02");
          };

          //线程池
          ExecutorService executorService = Executors.newFixedThreadPool(10);
          //执行10次
          List<Future<Date>> futures=new ArrayList<>();
          for (int i = 0; i < 10; i++) {

               futures.add(executorService.submit(dateCallable));
          }
          futures.forEach(x->{
               try {
                    System.out.println(x.get());
               } catch (InterruptedException e) {
                    e.printStackTrace();
               } catch (ExecutionException e) {
                    e.printStackTrace();
               }
          });
          executorService.shutdown();
     }

异常信息

java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: ""
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
	at cn.bufanli.time.TimeDemo01.lambda$test01$1(TimeDemo01.java:37)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at cn.bufanli.time.TimeDemo01.test01(TimeDemo01.java:35)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Long.parseLong(Long.java:601)
	at java.lang.Long.parseLong(Long.java:631)
	at java.text.DigitList.getLong(DigitList.java:195)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
	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 cn.bufanli.time.TimeDemo01.lambda$test01$0(TimeDemo01.java:24)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Wed Nov 02 00:00:00 CST 2016
Wed Nov 02 00:00:00 CST 2016
Mon Nov 02 00:00:00 CST 1970
Tue Nov 02 00:00:00 CST 1

jdk1.7--解决方法

加锁:

package cn.bufanli.time;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author BuShuangLi
 * @date 2019/3/13
 */
public class DateFormaThreadLoca {
     private static final  ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
          @Override
          protected DateFormat initialValue() {
               return new SimpleDateFormat("yyyy-MM-dd");
          }
     };

     public static Date convet(String source) throws ParseException {
          return df.get().parse(source);
     }
}

测试

     @Test
     public void test02()throws Exception{
          Callable<Date> callable = ()-> DateFormaThreadLoca.convet("2016-12-12");
          ExecutorService executorService = Executors.newFixedThreadPool(10);
          List<Future<Date>> futures = new ArrayList<>();
          for (int i = 0; i < 10; i++) {

               futures.add(executorService.submit(callable));
          }
          for (Future<Date> future : futures) {
               System.out.println(future.get());

          }
          executorService.shutdown();
     }

jdk1.8--解决方法

     /**
      * 1.8
      */
     @Test
     public void test03() {
          DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
          //又返回值的线程 lambda表达式
          Callable<LocalDate> callable = () -> LocalDate.parse("2011-12-22", df);
          //创建线程池
          ExecutorService executorService = Executors.newFixedThreadPool(10);

          List< Future<LocalDate>> objects = new ArrayList<>();
          for (int i = 0; i < 10; i++) {
               objects.add(executorService.submit(callable));
          }
          //循环打印集合中的localDate对象
          objects.forEach(x->{
               try {
                    System.out.println(x.get());
               } catch (Exception e) {
                    e.printStackTrace();
               }
          });
     }

新时间日期的API

LocalDate(年月日)、LocalTime(时分秒)、LocalDateTime(年月日时分秒 ) 类的实例是不可变对象,分别表示ISO-8601日历系统的日期、时间、日期和时间.

它们提供了简单的日期或时间,并不包含当前的时间信息.也不包含与时区相关的信息

package cn.bufanli.time;

import org.junit.Test;

import java.time.*;

/**
 * @author BuShuangLi
 * @date 2019/3/13
 */
public class TestLocalDateTime {
     /**
      * 1.LocalDate--> (年月日) LocalTime-->(时分秒) LocalDateTime(年月日时分秒)
      */
     @Test
     public void test01(){
          //获取当前系统时间  控制台: 2019-03-13T15:51:32.969
          System.out.println(LocalDateTime.now());
          //指定年月日分秒 控制台: 2012-12-22T12:33
          LocalDateTime of = LocalDateTime.of(2012, 12, 22, 12, 33);
          System.out.println(of);
          //时间运算  +两年
          LocalDateTime localDateTime = LocalDateTime.now().plusYears(2);
          //输出 2021-03-13T15:56:58.571
          System.out.println(localDateTime);
          //-两个月
          LocalDateTime localDateTime1 = LocalDateTime.now().minusMonths(2);
          //输出 2019-01-13T15:58:58.231
          System.out.println(localDateTime1);
          //单独获取年月日..
          System.out.println(localDateTime1.getYear());
          //月
          System.out.println(localDateTime1.getMonthValue());
          //日
          System.out.println(localDateTime1.getDayOfMonth());
          //小时
          System.out.println(localDateTime1.getHour());

     }

     /**
      * 2.Instant : 时间戳(以Unix 元年 : 1970年1月1日 到某个时间的毫秒值)
      */
     @Test
     public void test02(){
          // 默认获取的是 UTC 时区 输出: 2019-03-13T08:08:18.350Z
          System.out.println(Instant.now());
          //与UTC相差8小时时差
          OffsetDateTime offsetDateTime = Instant.now().atOffset(ZoneOffset.ofHours(8));
          //输出: 2019-03-13T16:10:41.398+08:00
          System.out.println(offsetDateTime);
          //转成毫秒值 1552464779665
          System.out.println(Instant.now().toEpochMilli());

     }
     /**
      * 3.
      *   Duration : 计算两个 时间 之间的间隔的
      *   Period : 计算两个日期之间的间隔
      */
     @Test
     public void test03() throws InterruptedException {
          Instant now1 = Instant.now();
          Thread.sleep(1000);
          Instant now2 = Instant.now();
          //获取毫秒  .toMillis() 其他的都是get..
          System.out.println(Duration.between(now1, now2).toMillis());

          LocalTime now11 = LocalTime.now();
          Thread.sleep(1000);
          LocalTime now22 = LocalTime.now();
          System.out.println(Duration.between(now11, now22).toMillis());


     }
}

日期的操纵

TemporalAdjuster:时间校正器.有时我们需要获取下个周日等操作

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

代码

 /**
      * TemporalAdjuster 时间教正器
      */
     @Test
     public void test04(){
          LocalDateTime now = LocalDateTime.now();
          System.out.println(now);
          //输出
//          2019-03-13T16:28:02.746
//          2019-03-10T16:28:02.746
          LocalDateTime localDateTime = now.withDayOfMonth(10);
          System.out.println(localDateTime);
          //获取下一个周日日期
          LocalDateTime with = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
          System.out.println(with);
          //自定义 下一个工作日是什么时候
          LocalDateTime with1 = now.with((l) -> {
               LocalDateTime localDateTime1 = (LocalDateTime) l;
               //获取周几
               DayOfWeek dayOfWeek = localDateTime1.getDayOfWeek();
               //判断
               if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
                    return localDateTime1.plusDays(3);
               } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
                    return localDateTime1.plusDays(2);
               } else {
                    return localDateTime1.plusDays(1);
               }
          });
          //输出下一个工作日的日期
          System.out.println(with1);

     }

DateTimeFormatter: 格式化时间/日期

 /**
      * DateTimeFormatter: 格式化时间/日期
      */
     @Test
     public void test05(){
          DateTimeFormatter isoLocalDate = DateTimeFormatter.ISO_LOCAL_DATE;
          LocalDateTime now = LocalDateTime.now();
          String format = now.format(isoLocalDate);
          System.out.println(format);
          System.out.println("自定义");
          //自定义
          DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
          //日期解析成字符串
          String format2 = now.format(dateTimeFormatter);

          //字符串解析成日期LocalDateTime.parse(时间字符串,解析格式)
          LocalDateTime parse = LocalDateTime.parse(format2, dateTimeFormatter);
          System.out.println(parse);


     }

 

中文版,平时开发超实用工具。 Java 2 Platform 软件包 java.applet 提供创建 applet 所必需的类和 applet 用来与其 applet 上下文通信的类。 java.awt 包含用于创建用户界面和绘制图形图像的所有类。 java.awt.color 提供用于颜色空间的类。 java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的各类事件的接口和类。 java.awt.font 提供与字体相关的类和接口java.awt.geom 提供用于在与二维几何形状相关的对象上定义和执行操作的 Java 2D 类。 java.awt.im 提供输入方法框架所需的类和接口java.awt.im.spi 提供启用可以与 Java 运行时环境一起使用的输入方法开发的接口java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口java.awt.print 为通用的打印 API 提供类和接口java.beans 包含与开发 beans 有关的类,即基于 JavaBeansTM 架构的组件。 java.beans.beancontext 提供与 bean 上下文有关的类和接口java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 ......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值