jdk8获取当前时间|时间加减|java8时间格式化|时间处理工具|时间比较|线程安全的时间处理方法

简介: jdk8获取当前时间|时间加减|java8时间格式化|时间处理工具|时间比较|线程安全的时间处理方法

前言

在很久之前,我总结了一些jdk7版本之前的关于时间处理的一些公共方法,日期转换成字符串、指定时间加上指定天数后的日期、获取上周周一时间 等等;具体的可以戳链接查看完整的:https://blog.csdn.net/qq_27471405/article/details/79523556


但是这些是非线程安全的,不建议采用,举个例子


在一个类中,有以下代码:

private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public String getDate(Date date){

return sdf.format(date);

}


上面这串代码在并发的时候,是线程不安全的,具体的如何不安全,大家可以搜一下,这里不多讲了


那么今天给大家分享的是jdk8之后的一些时间处理的公共方法,是线程安全的,理应大家以后应该用下面这些方法


一、jdk8与jdk7以及之前的日期和时间处理类的不同:

1. Java的java.util.Date和java.util.Calendar类易用性差,不支持时区,并且是可变的,也就意味着他们都不是线程安全的;

2. 用于格式化日期的类DateFormat被放在java.text包中,它是一个抽象类,所以我们需要实例化一个SimpleDateFormat对象来处理日期格式化,并且DateFormat也是非线程安全,这意味着如果你在多线程程序中调用同一个DateFormat对象,会得到意想不到的结果。

3. 对日期的计算方式繁琐,而且容易出错,因为月份是从0开始的,这意味着从Calendar中获取的月份需要加一才能表示当前月份

由于以上这些问题,出现了一些三方的日期处理框架,例如Joda-Time,data4j等开源项目


二、Java 8日期/时间类

Java 8的日期和时间类包含LocalDate、LocalTime、Instant、Duration以及Period,这些类都包含在java.time包中。


Instant:瞬时实例。


LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等。


LocalTime:本地时间,不包含日期。


LocalDateTime:组合了日期和时间,但不包含时差和时区信息。


ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差。


新API还引入了 ZoneOffSet 和 ZoneId 类,使得解决时区问题更为简便。解析、格式化时间的 DateTimeFormatter 类也全部重新设计。


三:日期和时间主要类的关系(待更新)

1 、LocalDate的关系图:

2、 LocalTime:

3 、LocalDateTime:

4 、OffsetTime:

5 、OffsetDateTime:

6、 ZonedDateTime:

7 、Instant:

 

四:日期操作和处理

 

获取当前日期(只能精确到年月日)

/**
     * 获取当前日期(只能精确到年月日)
     * @param formatStr
     */
    public static void getNowDate(String formatStr){
        if (StringUtils.isBlank(formatStr)){
            formatStr = "yyyy-MM-dd";
        }
        LocalDate now = LocalDate.now();
        System.out.println("当前日期: " + now + " " + now.getDayOfWeek());
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);                        // * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023   * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
        String nowFormat = now.format(dateTimeFormatter);
        System.out.println("格式化后的当前日期:"+nowFormat);
    }

如果传格式化到天小时秒的话,会报异常:Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay

获取当前时间(可以精确到毫秒)

 /**
     * 获取当前时间(可以精确到毫秒)
     * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
     * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
     * @param formatStr
     */
    public static void getNowTime(String formatStr){
        if (StringUtils.isBlank(formatStr)){
            formatStr = "yyyy-MM-dd";
        }
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前日期: " + now + " " + now.getDayOfWeek());
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);                      // * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023    * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
        String nowFormat = now.format(dateTimeFormatter);
        System.out.println("格式化后的当前日期:"+nowFormat);
    }

 

获取上周周一的日期

/**
     * 获取上周周一的日期
     * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
     * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
     */
    public static void getLastMonday(){
        LocalDate now = LocalDate.now();
        System.out.println("当前日期: " + now + " " + now.getDayOfWeek());
        LocalDate todayOfLastWeek = now.minusDays(7);
        LocalDate last_monday = todayOfLastWeek.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(1); // * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023   * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
        System.out.println("上周周一日期:"+last_monday); 
    }

 

获取具体年、月、日、小时、分钟、秒

/**
     * 获取具体年、月、日、小时、分钟、秒
     * @param formatStr
     */
    public static void getDetailTime(String formatStr){
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前日期: " + now + " " + now.getDayOfWeek());
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);
        String nowFormat = now.format(dateTimeFormatter);
        System.out.println("格式化后的当前日期:"+nowFormat);
        int year = now.getYear();
        int month = now.getMonthValue();
        int day = now.getDayOfMonth();
        int hour = now.getHour();
        int minute = now.getMinute();
        int second = now.getSecond();
        int nano = now.getNano();
        System.out.printf("年 : %d  月 : %d  日 : %d  小时:%d 分钟:%d 秒:%d  毫秒:%d %n", year, month, day,hour,minute,second,nano);  // * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023   * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
    }

 

指定日期、时间

/**
     * 指定日期、时间
     * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
     * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
     * @param formatStr
     */
    public static void createTime(String formatStr){
        LocalDate date = LocalDate.of(2020, 04, 27);
        System.out.println("指定日期: " + date);
        LocalDateTime time = LocalDateTime.of(2020, 04, 27,06,10,50);
        System.out.println("指定时间: " + time);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);
        String nowFormat = time.format(dateTimeFormatter);
        System.out.println("格式化后的指定时间:"+nowFormat);
    }

 

判断两个日期是否相等

/**
     * 判断两个日期是否相等、之前、之后
     * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
     * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
     */
    public static void compareDate(){
        LocalDate now = LocalDate.now();
        System.out.println("当前时间: " + now + " " + now.getDayOfWeek());
        LocalDate date1 = LocalDate.of(2020, 04, 27);
        LocalDate date2 = LocalDate.of(2020, 04, 27);
        LocalDate date3 = LocalDate.of(2020, 04, 28);
        boolean equal = now.isEqual(date1);
        System.out.printf("是否是同一时间:%s ", date1.equals(now));
        System.out.printf("是否是同一时间:%s ", now.isEqual(date1));
        System.out.println();
        System.out.printf("是否是同一时间:%s ", date1.equals(date2));
        System.out.printf("是否是同一时间:%s ", date1.isEqual(date2));
        System.out.println();
        System.out.println("data2(2020.4.27)是否比data3(2020.4.28)小: "+date2.isBefore(date3));             * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023   * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
        System.out.println("data2(2020.4.27)是否比data3(2020.4.28)大: "+date2.isAfter(date3));
    }

 

计算几年后(前)、几月后(前)、几天后(前)等的日期

/**
     * 计算几年后(前)、几月后(前)、几天后(前)等的日期
     * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
     * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
     * @param formatStr
     */
    public static void calculateTime(String formatStr){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime newTime = now.plusHours(6);
        System.out.println("当前时间: " + now + " " + now.getDayOfWeek());
        System.out.println("6小时后的时间: " +  newTime);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);
        String nowFormat = now.format(dateTimeFormatter);
        String newFormat = newTime.format(dateTimeFormatter);
        System.out.println("格式化后的当前时间:"+nowFormat);
        System.out.println("格式化后的6小时后的时间:"+newFormat);
        LocalDateTime twoYearsLater = now.plusYears(2);
        String twoYearsFormat = twoYearsLater.format(dateTimeFormatter);
        System.out.println("2年后的时间:"+twoYearsFormat);
        LocalDateTime twoMonthsLater = now.plusMonths(2);
        String twoMonthsFormat = twoMonthsLater.format(dateTimeFormatter);
        System.out.println("2个月后的时间:"+twoMonthsFormat);
        LocalDateTime twoWeeksLater = now.plusWeeks(2);
        String twoWeeksFormat = twoWeeksLater.format(dateTimeFormatter);
        System.out.println("2周后的时间:"+twoWeeksFormat);
        LocalDateTime twoDaysLater = now.plusDays(2);
        String twoDaysFormat = twoDaysLater.format(dateTimeFormatter);
        System.out.println("2天后的时间:"+twoDaysFormat);
        LocalDateTime twoMinutesLater = now.plusMinutes(2);
        String twoMinutesFormat = twoMinutesLater.format(dateTimeFormatter);
        System.out.println("2分钟后的时间:"+twoMinutesFormat);
        LocalDateTime twoMinutesBefore = now.plusMinutes(-2);
        String twoMinutesBeforeFormat = twoMinutesBefore.format(dateTimeFormatter);
        System.out.println("2分钟前的时间:"+twoMinutesBeforeFormat);
        //原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
        //其他均为盗版,公众号:灵儿的笔记(zygxsq)
        //还可以直接通过plus方法计算 几年(月周天)后
        LocalDateTime twoYearsPlusLater = now.plus(2, ChronoUnit.YEARS);
        String twoYearsPlusLaterFormat = twoYearsPlusLater.format(dateTimeFormatter);
        System.out.println("2年后的时间:"+twoYearsPlusLaterFormat);
        //负号表示 之前
        LocalDateTime twoDaysPlusBefore = now.plus(-2, ChronoUnit.DAYS);
        String twoDaysPlusBeforeFormat = twoDaysPlusBefore.format(dateTimeFormatter);
        System.out.println("2天前的时间:"+twoDaysPlusBeforeFormat);
        //也可以用minus,也表示之前
        LocalDateTime twoDaysMinusBefore = now.minus(2, ChronoUnit.DAYS);
        String twoDaysMinusBeforeFormat = twoDaysMinusBefore.format(dateTimeFormatter);
        System.out.println("2天前的时间:"+twoDaysMinusBeforeFormat);
    }

 

判断指定月份有多少天

 /**
     * 判断指定月份有多少天
     */
    public static void getMonthDays(){
        YearMonth currentYearMonth = YearMonth.now();
        System.out.println("当前时间:"+currentYearMonth);
        System.out.println("当前月份有多少天:"+currentYearMonth.lengthOfMonth());
        YearMonth february = YearMonth.of(2020, Month.FEBRUARY);
        System.out.println("指定时间的月份2月:"+february);
        System.out.println("指定时间的月份2月有多少天:"+february.lengthOfMonth());
    }

 

计算两个日期之间相差月数、天数、分钟数

/**
     * 计算两个日期之间相差月数、天数、分钟数
     * 原文章链接:https://blog.csdn.net/qq_27471405/article/details/106824023
     * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
     */
    public static void getDaysBetweenTwoDate(){
        LocalDate startDate = LocalDate.of(2020, 04, 27);
        LocalDate endDate = LocalDate.of(2020, 07, 2);
        long months = startDate.until(endDate, ChronoUnit.MONTHS);
        long days = startDate.until(endDate, ChronoUnit.DAYS);
        System.out.println("startDate(2020.04.27)和endDate(2020.07.02)相差月数:"+months);
        System.out.println("startDate(2020.04.27)和endDate(2020.07.02)相差天数:"+days);
        LocalDateTime startTime = LocalDateTime.of(2020, 04, 27,18,20,10);
        LocalDateTime endTime = LocalDateTime.of(2020, 04, 27,18,30,12);
        long minutes = startTime.until(endTime, ChronoUnit.MINUTES);
        System.out.println("startTime(2020.04.27 18:20:10)和endTime(2020.04.27 18:30:20)相差分钟数:"+minutes); // * 原文章链接https://blog.csdn.net/qq_27471405/article/details/106824023 * 其他均为盗版,公众号:灵儿的笔记(zygxsq)
    }

相关文章
|
7月前
|
设计模式 缓存 安全
【JUC】(6)带你了解共享模型之 享元和不可变 模型并初步带你了解并发工具 线程池Pool,文章内还有饥饿问题、设计模式之工作线程的解决于实现
JUC专栏第六篇,本文带你了解两个共享模型:享元和不可变 模型,并初步带你了解并发工具 线程池Pool,文章中还有解决饥饿问题、设计模式之工作线程的实现
456 2
|
7月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
362 1
|
7月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
345 1
|
7月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
916 4
|
8月前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
3031 8
|
8月前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
3114 1
|
8月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
337 0
|
8月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
513 16
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
371 1