JDK1.8新特性--新时间与日期API

Linux系统下JDK1.8的安装与配置 Java作为一种通用编程语言,自1995年发布以来,凭借其跨平台特性、对象导向的编程模型和强大的标准库,迅速在全球范围内获得了广泛的使用。历经多个版本的迭代,Java已经成为企业级应用、移动应用和Web应用开发的主流选择之一。Java集成开发环境(IDE)是Java开发者的得力助手,它提供了一系列工具以简化编码、构建和调试过程。一些流行的Java IDE包括IntelliJ IDEA、Eclipse、NetBeans等。 阅读详情

一、传统的时间与日期API

传统的时间与日期API最大的缺点就是线程不安全
看如下代码:

public class TestSimpleDateformat {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<Date>> futureList =new ArrayList<>();
        Callable<Date> task = new MyCallable();
        for (int i = 0; i < 10; i++) {
            futureList.add(executorService.submit(task));
        }
        futureList.forEach((f)-> {
            try {
                System.out.println(f.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
        executorService.shutdown();
    }
}
class MyCallable implements Callable<Date>{
    private static  final SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd");
    @Override
    public Date call() throws Exception {
        return  sdf.parse("2020-2-1");
    }
}

在这里插入图片描述
我看可以看到出现会出现错误,SimpleDateFormat继承了DateFormat,在DateFormat中定义了一个protected属性的 Calendar类的对象:calendar。只是因为Calendar累的概念复杂,牵扯到时区与本地化等等,Jdk的实现中使用了成员变量来传递参数,这就造成在多线程的时候会出现错误。
传统最常用的解决办法就是使用ThreadLocal线程局部变量来解决
如下代码:

public class TestSimpleDateformat {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<Date>> futureList =new ArrayList<>();
        Callable<Date> task = new MyCallable();
        for (int i = 0; i < 10; i++) {
            futureList.add(executorService.submit(task));
        }
        futureList.forEach((f)-> {
            try {
                System.out.println(f.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
        executorService.shutdown();
    }
}
class MyCallable implements Callable<Date>{
    private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    @Override
    public Date call() throws Exception {
        return  threadLocal.get().parse("2020-2-1");
    }
}

在这里插入图片描述
程序输出结果正确。

二、新时间与日期API

public class TestSimpleDateformat {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<LocalDate>> futureList =new ArrayList<>();
        Callable<LocalDate> task = new MyCallable();
        for (int i = 0; i < 10; i++) {
            futureList.add(executorService.submit(task));
        }
        futureList.forEach((f)-> {
            try {
                System.out.println(f.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
        executorService.shutdown();
    }
}
class MyCallable implements Callable<LocalDate>{
    private static final DateTimeFormatter dtf =DateTimeFormatter.ISO_LOCAL_DATE;

    @Override
    public LocalDate call() throws Exception {
        return  LocalDate.parse("2020-02-01",dtf);
    }
}

程序结果:
在这里插入图片描述
可以看到无论有多少个线程在执行,都创建了一个新的LocalDate实例,所有线程安全。

三、本地时间与时间戳

使用LocalDate、LocalTime、LocalDateTime
LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。

public class TestLocalDateTime {
    /*
     * 1.LocalDate 本地日期
     * 2.LocalTime 本地时间
     * 3.LocalDateTime 本地日期与时间
     *
     * 本测试是使用LocalDateTime为例,另外两个和这个一样
     */
    @Test
    public void test01(){
        //获取当前时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        //指定本地时间
        LocalDateTime time = LocalDateTime.of(2020, 2, 1, 15, 33, 16);
        System.out.println(time);

        //日期运算
        //在当前的日期上加8年
        LocalDateTime nowPlus = now.plusYears(8);
        System.out.println(nowPlus);
        //在当前的日期上减8天
        LocalDateTime nowMinus = now.minusDays(8);
        System.out.println(nowMinus);

        //获取时间
        //获取年份
        System.out.println(now.getYear());
        /*
         *获取月份,注意得到月份有两个方法,一个是getMonth(),得到Month这个
         *枚举类,你可以用这个类的getValue()方法得到月份,而getMonthValue()
         *可以直接得到月份
         */
        System.out.println(now.getMonthValue());
        System.out.println(now.getMonth().getValue());
        //得到天数
        System.out.println(now.getDayOfMonth());
        //得到小时
        System.out.println(now.getHour());
        //得到分钟
        System.out.println(now.getMinute());
        //得到秒
        System.out.println(now.getSecond());
    }

    /*
     * Instant:时间戳(以Unix元年:1970年1月1日00:00:00到某个时间之间的毫秒值)
     * 计算机读到的时间
     */
    @Test
    public void test02(){
        /*
         * 笔者当前的时间为2020-02-01T16:01:07.753,而输出结果是2020-02-01T08:01:7.753Z
         * 那为什么会出现这种情况呢?默认获取UTC时区的时间,不知道的读者可以去百度,美国就是使用
         * 的UTC时区,美国与我国时差相差8个小时,那么在2020-02-01T08:01:7.753Z时间上加8个小时
         * 就对于2020-02-01T16:01:07.753
         */
        Instant now = Instant.now();
        System.out.println(now);
        //做偏移量运算检验以下,结果是完全正确的
        OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);

        //转为毫秒值
        System.out.println(now.toEpochMilli());

        //结果1970-01-01T00:01:00Z
        Instant instant = Instant.ofEpochSecond(60);
        System.out.println(instant);
    }

    /*
     * Duration:计算两个“时间”之间的间隔
     * period:计算两个“日期”之间的间隔
     */
    @Test
    public void test03(){
        Instant instant1 = Instant.now();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Instant instant2 = Instant.now();
        Duration between = Duration.between(instant1, instant2);
        //得到两个时间之间相差多少秒
        System.out.println(between.getSeconds());
    }

    /*
     *
     * period:计算两个“日期”之间的间隔
     */
    @Test
    public void test04(){
        LocalDate localDate1 = LocalDate.of(2020,1,1);
        LocalDate localDate2 = LocalDate.now();
        Period between = Period.between(localDate1, localDate2);
        System.out.println(between.getMonths());
    }
}

四、时间校正器

TemporalAdjuster:时间校正器。有时我们可以需要获取例如:将时间调整到“下个周末”等操作。
TemporalAdjusters:该类通过静态方法提供了大量的常用TemporalAdjuster的实现。

public class TestTemporalAdjuster {
    /*
     * TemporalAdjuster:时间校正器
     */
    @Test
    public void test05(){
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        //把当前时间的天数改为8,如2020-02-01T16:36:46.533改为2020-02-08T16:36:46.533
        LocalDateTime localDateTime = now.withDayOfMonth(8);
        System.out.println(localDateTime);
        //把当前时间调整为下周六
        LocalDateTime with = now.with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
        System.out.println(with);
        //自定义:下一个结婚纪念日,今天当作纪念日,再过12*30天就是下一个结婚纪念日
        LocalDateTime time = now.with((t) -> {
            LocalDateTime marryTime = (LocalDateTime) t;
            LocalDateTime nextMarryTime = marryTime.plusDays(12*30);
            return nextMarryTime;
        });
        System.out.println(time);
    }
}

五:时间日期格式化与时区的处理

public class TestDateTimeFormatter {
    /*
     * DateTimeFormatter:格式化时间/日期
     */
    @Test
    public void test01(){
        //使用默认的格式化
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now.format(formatter));
        //使用自定义的
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println(now.format(formatter1));
        LocalDateTime parse = LocalDateTime.parse(now.format(formatter1), formatter1);
        System.out.println(parse);
    }
    /*
     * java8中加入了对时区的支持,带时区的时间分别为:
     * ZonedDate、ZonedTime、ZonedDateTime
     * 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式
     * 例如:Asia/Shanghai等
     * ZoneId:该类中包含了所有的时区信息
     *        getAvailableZonelds():可以获取所有时区信息
     *        of(id):用指定的时区信息获取ZoneId对象
     */
    @Test
    public void test02(){
        //有多少可以支持的时区
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        availableZoneIds.forEach(System.out::println);
    }
    @Test
    public void test03(){
        //指定一个时区构建时间
        LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Rangoon"));
        System.out.println(now);
        //构建带时区的时间
        ZonedDateTime zonedDateTime = now.atZone(ZoneId.of("Asia/Rangoon"));
        System.out.println(zonedDateTime);
    }
}
JDK 1.8安装与环境配置完整指南 Java开发者工具包(JDK)版本8,简称JDK 1.8,是Java历史上一个非常重要的里程碑版本,它不仅引入了诸多新特性,而且对于整个Java生态系统产生了深远影响。本章将带领读者回顾JDK 1.8的诞生背景,概览它所包含的关键组件,以及这些组件如何帮助开发者简化代码、提高效率,并增强程序的性能和功能性。我们将从JDK 1.8的整体概况出发,为读者打下坚实的基础,进而深入探讨后续章节中的新特性和细节。Lambda表达式在函数式编程语言中一直是一个核心概念。 阅读详情

相关推荐

从零到一:KUKA机械臂与ROS的工业级通讯协议深度解析

本文深度解析KUKA机械臂与ROS的工业级通讯协议,重点对比EKI与RSI两种核心接口的技术特点与应用场景。详细介绍了网络架构设计、数据包解析机制及ROS-I集成方法,并提供实时性能优化与故障排除策略,为工程师实现高可靠性工业自动化集成提供完整解决方案。

2a4s6d8f0g的博客 296

两种时间格式2017-03-15T16:52:38.186+0800和2017-03-15T16:52:38.186Z的区别

一开始误以为2017-03-15T16:52:38.186+0800和2017-03-15T16:52:38.186Z其实是相同的时间,最后拿着2017-03-15T16:52:38.186Z格式去es中查数据时,结果总是不对。 后来网上搜了一下,2017-03-15T08:52:38.186Z = 2017-03-15T16:52:38.186+800,记录一下这个无知的错误。。。

mgxcool的专栏 2355

Android dex, odex, oat, vdex, art文件介绍

下图可以简化将Java源转换为OAT的过程: .dex Dalvik虚拟机字节码文件 .vdex 其中包含APK的未压缩DEX代码,以及一些旨在加快验证速度的元数据 .odex .oat // JIT,Just-in-time,即时编译,边运行边编译; // AOT,Ahead Of Time,提前编译,指运行前编译。 其中包含APK中已经过AOT编译的方法代码。 原始DEX文件(例如classes.dex)被转换为另一个包含本机代码的文件。这个新文件通常具有.odex。.oat扩展名,并由ELF格式

he980725866的博客 3621

day27(1)-JDK8新特性-日期时间API

JDK1.8 新增的日期时间API LocalDate、 LocalTime、 LocalDateTime类的实例是不可变的对象, 分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。 它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。 注: ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法 这些新增的日期时间API都在 java....

UesugiSakuyad的博客 446

QCC308x/3095收发一体:TX/RX双模一拖二与多编码广播实战解析

本文深度解析高通QCC308x/3095蓝牙音频芯片的TX/RX双模功能与广播应用。芯片支持发射和接收模式下的“一拖二”连接,并能实现LE Audio多设备广播,显著提升多设备音频切换体验与商业广播能力,适用于健身、导览等丰富场景。

g9h0i1的博客 1008

Palabos 并行计算与多物理场模拟实战指南

本文详细介绍了Palabos在并行计算与多物理场模拟中的实战应用。作为基于C++和LBM的开源CFD工具,Palabos通过MPI实现高效并行计算,特别适合处理复杂流体模拟问题。文章涵盖从基础安装、多物理场耦合技巧到性能优化策略,并分享工业级应用案例与调试经验,帮助开发者快速掌握这一强大工具。

4k5l6j7h8的博客 245

Java JDK 1.8 新特性 时间与日期API

LocalData LocalTime LocalDateTime DateTimeFormatter Duration Period TemporalAdjuster

qq_43623492的博客 389

VScode搭建Opencv(C++开发环境)

VScode配置Opencv一、准备软件二 、下载软件1、MinGw下载2、 Cmake下载3、Opencv下载三、编译1、cmake-gui2、make3、install四、 VScode配置1、launch.json2、c_cpp_properties.json3、tasks.json五、测试 用了半天事件,看了各种的博客终于配置成功了,在这里记录并分享一下,让更多的人少走弯路。 本次环境是Win 10. 一、准备软件 我们本次用到的3个软件,(建议读者文件路径,文件版本 尽量都和我相同,这样不容易出错

河旬的博客 8万+

JDK1.8新特性---新时间日期API

JDK1.8新特性---新时间日期API

Mr.Cui的Java学习之路 2586

Netapp FAS2750热备盘替换失败问题分析与解决

本文深入分析了Netapp FAS2750存储系统中热备盘替换失败的故障现象,揭示了磁盘分区属主不匹配导致数据同步无法启动的根本原因。通过详细的排查步骤和解决方案,帮助运维人员快速恢复aggr状态,并提供了长期预防措施和最佳实践建议,确保存储系统的高可用性。

weixin_33737774的博客 401

Claude Code 100个真实案例 - 用AI搭建LangChain多工具Agent(自主搜索+查询)

本案例展示如何使用 Claude Code 搭建一个 LangChain 多工具 Agent 系统。Agent 能够自主决定调用搜索引擎、数据库查询、天气查询、计算器等工具,像人类助手一样拆解问题并逐步解决。

yueyeguzhuo的专栏 560

JDK1.8新特性之时间函数API详解

JDK1.8提供的新时间API都在java.time包下所有类都是线程安全的 日期、时间及对比相关的对象创建完均不可修改 可并发解析与格式化日期与时间 支持设置不同的时区与历法。LocalDate,LocalTime,LocalDateTime ,Instant,Duration,Period,ZoneID,ZonedDateTime,DateTimeFormatter. ...

eviano的博客 1746

使用 Simulink 和 Simscape Electrical 工具箱设计一个 Buck 转换器系统

Buck 转换器(降压转换器)是一种常用的 DC-DC 转换器,用于将较高的输入电压转换为较低的输出电压。为了评估其抗干扰能力,我们可以在模型中引入不同的干扰源,并观察系统的响应情况。电网电压波动:输入电压的变化。负载突变:负载电阻或电感的变化。电磁干扰:高频噪声或脉冲干扰。通过模拟这些干扰,我们可以分析系统的动态响应特性,并采取相应的措施来提高系统的抗干扰能力。

xiaoheshang_123的博客 378

新时间日期API(jdk1.8新特性)

jdk1.8之前日期API存在线程安全问题 在之前传统解决方式可以利用线程隔离可以避免线程安全 jdk1.8后完全都是不可变的,解决了这一套多线程安全问题 没有多线程安全问题了,因为不管怎样改变都产生了一个全新的实例 (传统时间API与新时间API最大的差别) ...

m0_56379670的博客 158

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

java8(jdk1.8、jdk8)新特性,Lambda表达式、函数式接口、方法引用与构造器引用、Stream API、新时间日期API

JAVA 8(又名jdk 1.8或者jdk8)是oracle公司2014年3月份发布的。众所周知,jdk8可以看成是jdk5发布以来最具有革命性的一代,其新增了很多新特性,为我们的编程带来了极大的便捷,现在很多公司开发都是使用的java 8。java8 之前,往接口里新加一个方法,那么所有的实现类都需要变动,都需要同步实现这个方法。java8 给接口新增了两个关键字:default和static,使得可以往接口里添加默认方法,子类可以无需变动。

sunzixiao的博客 4274

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

JDK1.8 新特性

JDK1.8 新特性 本文主要介绍了JDK1.8版本中的一些新特性,仅供参考。 jdk1.8新特性知识点: Lambda表达式 函数式接口 *方法引用和构造器调用 Stream API 接口中的默认方法和静态方法 新时间日期API 在jdk1.8中对hashMap等map集合的数据结构优化。hashMap数据结构的优化 原来的hashMap采用的数据结构是哈希表(数组+链表),hashMap默认大小是16,一个0-15索引的数组,如何往里面存储元素,首先调用元素的hashcode 方法..

小猪跑得快 378

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java8(JDK1.8)新特性

1、速度快;2、代码少、简介(新增特性:lamdba表达式);3、强大的Stream API;4、使用并行流和串行流;5、最大化较少空指针异常Optional;其中最为核心的是Lambda表达式和Stream APILambda是一个匿名函数,我们可以将Lambda表达式理解为一段可以传递的代码(将代码像数据一样传递)。使用它可以写出简洁、灵活的代码。作为一种更紧凑的代码风格,使java语言表达能力得到提升。...

weixin_40294256的博客 5万+

新时间和日期 API-时间格式化与时区的处理(jdk1.8新特性)

m0_56379670的博客 156

JDK1.8新特性

作为参数传递 Lambda 表达式:为了将 Lambda 表达式作为参数传递,接 收Lambda 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口 的类型。流(Stream) 到底是什么呢?是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算!注意:①Stream 自己不会存储元素。②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。③Stream 操作是延迟执行的。

qq_41860765的博客 658

JDK8 的新特性

本文主要介绍了JDK1.8版本中的一些新特性,乃作者视频观后笔记,仅供参考。 jdk1.8新特性知识点: Lambda表达式 函数式接口 *方法引用和构造器调用 Stream API 接口中的默认方法和静态方法 新时间日期API 在jdk1.8中对hashMap等map集合的数据结构优化。hashMap数据结构的优化 原来的hashMap采用的数据结构是哈希...

supper_me的博客 352

JDK1.8 新特性(全)

https://blog.csdn.net/qq_29411737/article/details/80835658 JDK1.8 新特性(全) 2018年06月27日 22:01:54 qq_29411737 阅读数:6952 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29411737/article/details/80835...

u013452335的博客 639

JDK1.8新特性(三)使用详情

继JDK1.8新特性(一),JDK1.8新特性(二)后继续学习JDK1.8新特性。 【7】Optional 类 final修饰的Optional&amp;amp;amp;amp;amp;amp;lt;T&amp;amp;amp;amp;amp;amp;gt; 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用null 表示一个值不存在,现在Optional 可以更好的表达这个概念。并且可以避免空指针异常。 常用方法: Optional.of(T t)

小小默:进无止境 1958

JDK1.8新增的日期时间API

weixin_45127932的博客 113

JDK1.8新特性(3)接口新定义与日期

一、接口定义 在接口中可以使用default和static关键字来修饰接口中定义的普通方法 public interface Interface { default String getName(){ return "zhangsan"; } static String getName2(){ return "zhangsan"; } } 在JDK1.8中很多接口会新增方法,为了保证1.8向下兼容,1.7版本中的接口实现类不用每个都重新实

清茶与浊酒 293

java1.8新特性_JDK1.8 新特性(全)

原文链接:https://blog.csdn.net/qq_29411737/article/details/80835658jdk1.8新特性知识点:Lambda表达式注:当一个接口中存在多个抽象方法时,如果使用lambda表达式,并不能智能匹配对应的抽象方法,因此引入了函数式接口的概念函数式接口什么是函数式接口?简单来说就是只定义了一个抽象方法的接口(Object类的public方法除外),...

weixin_36158842的博客 651
上一篇: JDK1.8新特性---接口中的默认方法与静态方法
下一篇: JDK1.8新特性--重复注解
suixinghero
博客等级 码龄7年 10粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值