当前位置: 首页 > news >正文

Java线程安全的时间类

1、原先的Date对象和Calendar对象的缺点:

(1)在多线程环境下,存在线程不安全的情况,这也是最本质的缺点。
(2)我们查看一下Date类,会发现该类中的很多方法都已经被废弃。
(3)关于Date和Calendar存在对日期的计算困难问题。

2、关于Date-Time API中的基本类的使用:

Date-Time API中的所有类均生成不可变实例,它们是线程安全的,并且这些类不提供公共构造函数,也就是说没办法通过new的方式直接创建,需要采用工厂方法加以实例化。

在最新版本的java.time包下面我们在实际开发中经常要遇到的几个类:

Instant类

Instant类对时间轴上的单一瞬时点建模,可以用于记录应用程序中的事件时间戳,之后学习的类型转换中,均可以使用Instant类作为中间类完成转换。(国际标准时间)

Duration类

Duration类表示秒或纳秒时间间隔,适合处理较短的时间,需要更高的精确性。

Period类

Period类表示一段时间的年、月、日。

LocalDate类

LocalDate是一个不可变的日期时间对象,表示日期,通常被视为**年月日**。

LocalTime类

LocalTime是一个不可变的日期时间对象,代表一个时间,通常被看作是小时-秒,时间表示为纳秒精度。

LocalDateTime类

LocalDateTime类是一个不可变的日期时间对象,代表日期时间,通常被视为年-月-日=时-分-秒。

ZonedDateTime类

ZonedDateTime是具有时区的日期时间的不可变表示,此类存储所有日期和时间字段,精度为纳秒,时区为区域偏移量,用于处理模糊的本地日期时间。

(1)我们可以采用now方法创建当前日期或者时间的实例。
在这里插入图片描述

package com.day20221012;

import java.time.*;

public class DateDemo01 {
    public static void main(String[] args) {
        //利用now()方法创建Instance的实例对象
        Instant now = Instant.now();
        System.out.println("利用now()方法创建Instance的实例对象"+now);
        LocalDate now1 = LocalDate.now();
        System.out.println("利用now()方法创建LocalDate的实例对象"+now1);
        LocalTime now2 = LocalTime.now();
        System.out.println("利用now()方法创建LocalTime的实例对象"+now2);
        LocalDateTime now3 = LocalDateTime.now();
        System.out.println("利用now()方法创建LocalDateTime的实例对象"+now3);
        ZonedDateTime now4 = ZonedDateTime.now();
        System.out.println("利用now()方法创建ZonedDateTime的实例对象"+now4);


    }
}

在这里插入图片描述

  //进行时间的拼装
        String time = now1.toString() +" "+ now2.toString();
        System.out.println("时间的拼装"+time);

在这里插入图片描述

Java8的Time包种还提供了其它几个类可以更精准的获取某些信息。

Year类(表示年)

YearMonth类(表示年月)

MonthDay类(表示月日)

        System.out.println("Year:"+now5);
        System.out.println("YearMonth:"+now6);
        System.out.println("MonthDay:"+now7);

在这里插入图片描述

(2)如何指定时间呢?

  LocalDate date = LocalDate.of(2017, 9, 01);
        System.out.println("指定日期"+date);
        LocalTime time = LocalTime.of(14, 28, 00);
        System.out.println("指定时间"+time);

        LocalDateTime localDateTime = LocalDateTime.of(date, time);
        System.out.println("指定日期时间"+localDateTime);

在这里插入图片描述
(3)时区信息的获取

在这里主要应用于苹果系统的闹钟的时间会有各个国家的时间,在这里就可以通过这个来进行转换,但是因为我感觉仅仅了解即可,因为在实际开发中应该很少遇到吧,除非你是外企一类的。

在这里插入图片描述

在这里插入图片描述

(4)Month枚举类的应用:

在这里简单来说就是:
推荐在初始化LocalDate和LocalDateTime对象的时候,月份的参数使用枚举的方式传入,这样更简单易懂而且不易出错,因为如果是老的思维,Calendar传入0的话,那么会出现异常。

在这里插入图片描述

3、根据现有的实例创建日期和时间对象。

plus()和minus()

(1)对于修改现有的日期对象时,我们可以使用plus和minus方法来进行修改。补充当然,除了添加年月日之外亦可以添加时分秒,大家可以自己在网上搜一下。

应用场景:比如用户充值了会员,可以帮助我们快速的确定会员到期的时间。

        LocalDate date = LocalDate.of(2017, 9, 1);
        System.out.println("指定的时间为"+date);
        //两天后的时间
        LocalDate date1 = date.plusDays(2);
        //4周后的时间
        LocalDate date3 = date.plusWeeks(4);
        //3个月后的时间
        LocalDate date2 = date.plusMonths(3);
        //4年后的时间
        LocalDate date4 = date.plusYears(4);
        System.out.println("两天后的时间"+date1);
        System.out.println("4周后的时间"+date3);
        System.out.println("3个月后的时间"+date2);
        System.out.println("4年后的时间"+date4);

在这里插入图片描述
(2)利用plus方法+period对象参数帮助我们更加高效的封装事件对象。
在这里插入图片描述(3)利用with()方法实现日期的直接修改

如果我们对原有时间的基础上无法进行增减操作的话,name我们就要借助于with方法了。
如果不需要对日期进行加减而是要直接修改日期的话,那么可以使用with方法,with方法提供了很多种修改时间的方式。

LocalDateTime withNano(int i) 修改纳秒

LocalDateTime withSecond(int i) 修改秒

LocalDateTime withMinute(int i) 修改分支

LocalDateTime withHour(int i) 修改小时

LocalDateTime withDayOfMonth(int i) 修改日

LocalDateTime withMonth(int i) 修改月

LocalDateTime withYear(int i) 修改年

在这里插入图片描述
(4)with(TemporalField field, long newValue)

temporalField是一个接口,通过查看体系结构,可以使用它的子类

ChronoField,ChronoField中封装了一些日期时间中的组成成分,可以直接选择之后传入第二个参数进行修改。

例如:with(ChronoField.DAY_OFMONTH,1);将日期中的月份中的天数改为1

例如:with(ChronoField.YEAR,2021);将日期中的年份改为2021。

在这里插入图片描述

重点:我们将Date或者Calendar转换成java,time中的各种对象。

4、Date类转换方式

(1)java.util.Date类的转换方式:

Java8中的java.time中并没有提供太多的内置方式来转换java.util包中用预处理标准日期和时间的类,我们可以使用Instant类作为中介,也可以使用java.sql.Date和java.sql.TimeStamp类提供的方法进行转换。

(a)使用Instant类进行转换:

package com.day20221012;

import java.time.*;
import java.util.Date;

public class DateDemo04 {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date);
        Instant is = date.toInstant();
        //因为date对象只包含日期和时间,不包含时区的相关信息。
        ZonedDateTime zonedDateTime = is.atZone(ZoneId.systemDefault());

        LocalDate date1 = zonedDateTime.toLocalDate();
        LocalTime date2 = zonedDateTime.toLocalTime();

        LocalDateTime date3 = zonedDateTime.toLocalDateTime();

        System.out.println("转换之前"+date);
        System.out.println("转换之后"+date1);
        System.out.println("转换之后"+date2);
        System.out.println("转换之后"+date3);


    }
}

在这里插入图片描述

(b)java.sql.Date类提供了转换为LocalDate的方法,那么可以将java.util.Date先转换为java.sql.Date。通过java.sql.Date的构造方法直接传入一个毫秒值可以构造一个java.sql.Date对象,毫秒值可以通过java.util.Date对象的getTime()方法获取到。
在这里插入图片描述

(2)首先注意(1)和(2)的区别,因为(1)是java.util.date类,而(2)是java.sql.date类中的,这两点时最本质的区别。

java.sql.Date类中提供直接转换为LocalDate的方法,toLocalDate()

java.sql.Timestamp类是时间戳对象,通过传入一个毫秒值对象进行初始化

package com.day20221012;

import java.sql.Date;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;

public class DateDemo05 {
    public static void main(String[] args) {
        //初始化java.sql.Date对象
        //java.sql.date与java.util.date的区别
        Date date1 = new Date(System.currentTimeMillis());
        LocalDate date = date1.toLocalDate();

        System.out.println("转换之前"+date);
        System.out.println("转换之后"+date1);

        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        LocalDateTime localDateTime = timestamp.toLocalDateTime();

        System.out.println("转换之前"+timestamp);
        System.out.println("转换之后"+localDateTime);


    }
}

在这里插入图片描述

(3)Calendar的转换方式:

(a)Calendar对象字Java1.1开始提供了一个方法获取时区对象的方法,getTimeZone()。
要将Calendar对象转换为ZonedDateTime需要先获取到时区对象。从Java1.8开始TimeZone类提供了一个方法可以获取到ZonedId。获取到ZonedId之后就可以初始化ZOnedDateTime对象了,ZonedDateTime类有一个ofInstant()方法,可以将一个Instant对象和ZonedId对象作为参数传入构造一个ZonedDateTime对象。
在这里插入图片描述
(b)Calendar转换为LocalDateTime

java.util.Calendar类转换为java.time.LocalDateTime类

Calendar对象可以获取到年月日时分秒的信息,这些信息可以作为LocalDateTime构造方法的参数

在这里插入图片描述

重点:SimpleDateFormat类在刚开始的时候讲过了是线程不安全的,所以Java8提供了新的格式化类 DateTimeFormatter

dateTimeFormatter类提供了大量预定义格式化器,包括常量(如ISO_LOCAL_DATE),模式字母(如yyyy-MM-dd)以及本地化样式。

与SimpleDateFormat不同的是,新版本的日期/时间API的格式化与解析不需要再创建转换器对象了,通过时间日期对象的parse/format方法可以直接进行转换.

(4)LocalDate类定义的parse和format方法

在这里插入图片描述
(5)ofLocalizedDate方法

Full:全显示(年月日+星期) Long:全显示(年月日) Medium:缩略显示(没有年月日汉字) SHORT:精简显示(精简年+月日)
在这里插入图片描述

(6)自定义格式化器

除了系统自带的方式之外,也可以通过DateTimeFormatter类提供的ofPattern方式创建自定时格式化器,格式化的写法与之前使用SimpleDateFormat相同。

在这里插入图片描述
在这里插入图片描述

给大家推荐两篇完整版博客:

https://www.jianshu.com/p/20bfae706882

https://www.jianshu.com/p/7a1b367ae95f

java.sql.date与java.util.date的区别和联系?

可以参考这篇博客:

https://blog.csdn.net/lilshork/article/details/126113464

问题,如果我们这样转存数据的话那么后台数据怎么办?前台数据怎么办?

其实和之前的一样只不过是换了一种类来表示,和之前没什么区别,只不过加了一步转换的方法。。

相关文章:

  • python基础——正则表达式
  • FFmpeg常用结构体、关键函数、ffplay.c分析
  • 本地缓存数据存入文件中
  • SCP收容物121~130
  • 解释PostgreSQL中的MVCC(多版本并发控制)机制是如何工作的?
  • 面试算法十问(中英文)
  • sql | leecode 1147 |即时事务配送II | sql 优化
  • 数据分析案例-社交媒体情绪数据集可视化分析(文末送书)
  • 坚持刷题|二叉树展开为链表
  • RK3568平台 RTC时间框架
  • [云原生] 二进制安装K8S(上)搭建单机matser、etcd集群和node节点
  • windows 使用ffmpeg .a静态库:读取Wav音频并保存PCM
  • 驱动开发:内核枚举IoTimer定时器
  • sumo的简单使用
  • 【C++】C++入门
  • Docker精通:微服务
  • HCIA-LTE学习总结03~04
  • Python Apex Legends 武器自动识别与压枪 全过程记录
  • 『Android』Toolbar+DrawerLayout+NavigationView实现类似QQ侧边栏效果
  • 10.13面试整理
  • 下一代 IDE 工具 JetBrains Fleet 正式公测
  • Node.js3---nodejs的内置模块之url模块
  • 什么样的小程序才能留住客户?
  • EXCEL表格-系统时间及进度自动记录工具制作
  • 走进元宇宙--手势交互技术详解
  • Zookeeper集群安装部署
  • 机器学习笔记 - 在Vehicles数据集上训练 YOLOv5 目标检测器
  • flutter系列之:把box布局用出花来
  • 计算机毕业设计JAVA旧物置换网站mybatis+源码+调试部署+系统+数据库+lw
  • GridView使用详情
  • springboot(四)
  • 基于腾讯云Docker部署PXC搭建MySQL集群