JAVA日期1

背景

1、JAVA面世之初,标准库引用了两种处理日期和时间的类。java.util.Date 和java.util.Calendar类。这两种类具有线程不安全风险。JAVASE8中引入java.time包解决了长久依赖的弊端,java.time包基于Joda-Time库组件。

2、目前项目中关于时间的运用场景

目标

1、掌握JAVA8中提供的java.time包中的常用日期类与相关方法

2、从Java.util包下的日期类过渡到java.time包下的日期类

3、掌握JAVA8中的日期与字符串之间的相互转换

老版本API计算问题

 程序员小李出生于1995年12月16日,计算当前它已经出生了多少天?
  步骤思路:
 1、初始化Date对象无参构造(无参构造默认代表的是当前时间)
 2、获取当前时间距离1970年1月1日过了多少毫秒
 3、初始化Calendar对象并设时间为1995年12月16日,并将Calendar转换为Date对象,再转换为1995年12月16日距离1970年1月1日过了多少毫秒

4、将两个毫秒相减,然后将毫秒转换为天数结果

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args){
    Date d = new Date();
    long s1 = d.getTime();
    Calendar c = Calendar.getInstance();
    c.set(1995,11,16);
    Date d2=c.getTime();
    long s2 = d2.getTime();
    Long intevarDay=(s1-s2)/1000/60/60/24;
    System.out.println("1995年距离今天过了"+intevarDay+"天");
    Long day = ChronoUnit.DAYS.between(LocalDate.of(1995,12,16),LocalDate.now());
    System.out.println("1995年距离今天过了"+day+"天");
   }
   
}

 

 线程安全问题

  1、SimpleDateFormat 类是线程不安全的,在多线程的情况下,全局共享一个

  2、SimpleDateFormat 类中的Calendar对象有可能会出现异常

 ?问题:创建10个线程,将字符串“2018-12-12 12:12:12"转换为Date对象打印到控制台上

 final static SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        public static void main(String[ ] args){
  for (int i =0;i<10;i++){

    new Thread(
     new Runnable() {
      @Override
      public void run (){


       try{
          Date date = SIMPLE_DATE_FORMAT.parse("2018-12-12 12:12:12");
          System.out.println(date);

         }  catch(ParseException e) {
         
           e.printStackTrace();
         }
      }
     }


      ).start();
}



}

ALT+7 快捷键:

   dea中查看类中所有方法列表当我们在开发中,或者在读别人代码时,如何能快速定位到想看的方法;我们以activiti中的RepositoryService为例,如下图,RepositoryService接口中定义了许多构造方法或普通方法。直接使用Alt+7快捷键盘,就可以看到左侧的RepositoryService查看当前文件中的所有方法

 由于全局使用的是同一个Calendar对象 ,如果没有线程同步措施的话,那么可能会造成线程安全问题

 final static SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[ ] args){
  for (int i =0;i<10;i++){

    new Thread(
     new Runnable() {
      @Override
      public void run (){


       try{
          synchronized(SIMPLE_DATE_FORMAT ){
          Date date = SIMPLE_DATE_FORMAT.parse("2018-12-12 12:12:12");
           System.out.println(date);
       }
         

         }  catch(ParseException e) {
         
           e.printStackTrace();
         }
      }
     }


      ).start();
}



}

线程安全问题:SimpleDateFormat 类是线程不安全的,在多线程的情况下,全局共享一个

                         SimpleDateFormat类中的Calendar 对象有可能会出现异常

另外一个问题:就是在java.util.Date和java.util.Calendar类之前,枚举类型(ENUM)还没有出现,所以在字段中使用整数常量导致整数常量都是可变的,而不是线程安全的。                      为了处理 实际开发中遇到的问题,标准库随后引入了java.sql.Date作为java.util.Date的子类,但是还是没能彻底解决问题。最终JavaSE 8中引入了java.time包,这种全新的包从根本上解决了长久以来存在的诸多弊端,java.time包基于Joda-Time库构建,是一种免费的开源解决方案,实际上在Java 8没有出现之前,公司中已经广泛使用Joda-Time来解决Java中的日期与时间问题,Joda-Time的设计团队也参与了java.time包的开发。

public class CalendarUnsafeDemo{
  
  //初始化Calendar对象封装日期为2008年8月8日

    public static void main(String[ ] args){

    //初始化Calendar对象 --》getInstance()方法
    Calendar calendar = Calendar.getInstance();
    // 通过set方法设置年/月/日参数 -》开发规范:不允许使用没有定义的魔法数字
    // Calendar.set(2008,8,8)   
    Calendar.set(2008,Calendar.AUGUST,8)
    





  }



}

java.time包->常用类的概述和功能介绍

Instant类

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

Duration类

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

Period类

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

LocalDate类

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

LocalTime类

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

LocalDateTime类

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

ZonedDateTime类

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

now方法在日期/时间类的使用

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

now方法在日期时间类中的应用

now方法在日期时间类中的应用2

不仅仅是以上提供的及各类可以使用now方法,Java8的Time包种还提供了其它几个类可以更精准的获取某些信息。

Year类(表示年)

YearMonth类(表示年月)

MonthDay类(表示月日)

of方法在日期/时间类的应用

指定任意时间节点

of方法可以根据给定的参数生成对应的日期/时间对象,基本上每个基本类都有of方法用于生成的对应的对象,而且重载形式对边,可以根据不同的参数生成对应的数据。

时区信息的获取(拓展)

在学习ZonedDateTime的时候,发现这个对象里面封装的不仅有时间日期,并且还有偏移量+时区,那么时区如何在Java中获取呢?通过提供的一个类ZonedId的getAvailableZoneIds方法可以获取到一个Set集合,集合中封装了600个时区。

添加时区信息与获取其它时区时间

我们可以通过给 LocalDateTimem添加时区信息来查看到不同时区的时间,比如说 LocalDateTime中当前封装的是上海时间,那么想知道此时此刻,纽约的时间是多少,就可以将纽约的时区Id添加进去,就可以查看到了,方式如下:

*    封装时间 LocalDateTime 并添加时区信息。

*    更改时区信息查看对应时间。

Month枚举类的使用

java.time包中引用了Month的枚举类,Month中包含标准日历中的12个月份的常量(从JANUARY到DECEMEBER)也提供了一些方便的方法供我们使用。

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

章节练习

1、创建当前时间(不带时区)

2、创建当前时间(只包含年月日)

3、创建当前时间(包含年月日时分秒且带有时区)

4、创建2012年12月31日7时38分46秒的日期对象,月份用枚举表示

5、创建2012年12月31日的时期对象,月份用枚举表示

6、创建7时38分46秒的时间对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值