ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA中Calendar与Date类型

2022-04-18 01:33:45  阅读:541  来源: 互联网

标签:JAVA int SimpleDateFormat 日期 时间 Date Calendar


1.参考文档:

     Java之Date类和Calendar类的区别

     Java日期处理的十个坑

      SimpleDateFormat线程不安全及解决办法

2.背景:

         《java核心技术1》 中,类库的设计者希望能够将时间点和日期分开:一个是用来表示时间点的Date类,一个是用来表示大家熟悉的日历表示法的GregorianCalendar类,事实上,GregorianCalendar类拓展了一个更加通用的Calendar类,这个类描述了日历的一般属性。

          在JDK1.0中,Date类是唯一的一个代表时间的类,但是由于Date类不便于实现国际化,所以从JDK1.1版本开始,推荐使用Calendar类进行时间和

日期处理 。

主要区别:java.util.Date是个日期数据java.util.Calendar 用于日期相关的计算

3.常用时间函数与注意事项

3.1 Date与Calendar之间的区别与转换   

查看代码
//1. 两个对象之间的不同
        Date date=new Date(); // Sun Apr 17 22:05:46 CST 2022
        Calendar ca=Calendar.getInstance(); //java.util.GregorianCalendar[time=1650204346836,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,
        // lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=3,WEEK_OF_YEAR=17,WEEK_OF_MONTH=4,DAY_OF_MONTH=17,DAY_OF_YEAR=107,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=10,HOUR_OF_DAY=22,MINUTE=5,SECOND=46,MILLISECOND=836,ZONE_OFFSET=28800000,DST_OFFSET=0]
        System.out.println(date);
        System.out.println(ca);
       //2.两者之间的相互转换
        Date caDate=ca.getTime();
        Calendar cb=Calendar.getInstance();
        cb.setTime(date);
        System.out.println(caDate); //Sun Apr 17 22:05:46 CST 2022
        System.out.println(cb); // cb 与ca一致

3.2、Date常用函数

                 Date类常用的构造器:到目前为止,还有两个构造器是推荐使用,其他的构造器已经过时就不在此说明:  

      •  new Date()     分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒Sun Apr 17 22:12:08 CST 2022); 
      •  new Date(long value)     构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。 

                 Date中常用方法

      • after(Date when)    测试此日期是否在指定日期之后,返回值:Boolean
      • before(Date when)  测试此日期是否在指定日期之前,返回值:Boolean
      • CompareTo(Date anotherDate)   比较两个日期的顺序,返回值:int
      • Equals(Object obj): 比较两个日期的相等性,返回值:Boolean
      • Date和String之间互转;   需要借助日期转换类SimpleDateFormat(线程不安全的类)

3.3、Calendar常用函数已经注意事项(在jdk api 1.8中可以查看)

时间概念:Java 8开始,明确了日期时间概念,例如:瞬时(instant)、 长短(duration)、日期、时间、时区和周期。

      • Instant:瞬时实例。
      • LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等。
      • LocalTime:本地时间,不包含日期。
      • LocalDateTime:组合了日期和时间,但不包含时差和时区信息。
      • ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时

                        常用方法汇总: (Date中的方法全部包含此处不在累述): protected Calendar() 由于修饰符是protected,所以无法直接创建对象

      • static Calendar getlnstance() 使用默认时区和区域获取日历
      • void setTime(Date date) 用给定的Date设置此日历的时间。Date-Calendar
      • void set(int year,int month,int date,int hourofday,int minute,int second) 设置日历的年,月,日,时,分,秒。
      • int get(int field) 返回给定日历字段的值,字段比如年,月,日等。
      • Date getTime() 返回一个Date表示此日历的时间。Calendar-Date
      • void add(int field,int amount) 按照日历规则,给指定字段添加或减少时间量
      • long getTimeInMillies() 毫秒为单位返回该日历的时间值
      • int getActualMaximum(int field) 、getActualMinimum 返回日历的最大值与最小值
      •  void   clear()    将此 Calendar 的所日历字段值和时间值(从历元至现在的毫秒偏移量)设置成未定义。
      •  int    getFirstDayOfWeek()  获取一星期的第一天;例如,在美国,这一天是 SUNDAY,而在法国,这一天是 MONDAY。
 其中Calendar 中 field为Calendar类中设置的各个常量
常量 描述
Calendar.YEAR 年份
Calendar.MONTH 月份
Calendar.DATE 日期
Calendar.DAY_OF_MONTH 日期,和上面的字段意义完全相同
Calendar.HOUR 12小时制的小时
Calendar.HOUR_OF_DAY 24小时制的小时
Calendar.MINUTE 分钟
Calendar.SECOND
Calendar.DAY_OF_WEEK 星期几

                 注意事项

                      a.Calendar获取的月份比实际数字少1即(0-11)

                      b.西方星期的开始为周日,中国为周一

                      c. 日期是有大小关系的,时间靠后,时间越大

3.4、时间转换格式

                     a.yyyy与YYYY之间的区分:

        2019年12月31号,就转了一下格式,就变成了2020年12月31号了?因为YYYY是基于周来计算年的,它指向当天所在周属于的年份,一周从周日开始算起,周六结束,只要本周跨年,那么 这一周就算下一年的了。正确姿势是使用yyyy格式。

                      b.hh与HH之间的区分:

                              hh是12制的日期格式,当时间为12点,会处理为0点。正确姿势是使用HH,它才是24小时制。

                       c.dd和DD之间的区分:

                               DD表示的是一年中的第几天,而dd表示的是一月中的第几天,所以应该用的是dd。

                       d.SimleDateFormat的format初始化问题:

        • format格式化日期是,要输入的是一个Date类型的日期,而不是一个整型或者字符串。
        • SimpleDateFormat 可以解析长于/等于它定义的时间精度,但是不能解析小于它定义的时间精度。
        • SimpleDateFormat并发情况下,存在安全性问题

        SimpleDateFormat继承了 DateFormat,DateFormat类中维护了一个全局的Calendar变量,sdf.parse(dateStr)和sdf.format(date),都是由Calendar引用来储存的。如果SimpleDateFormat是static全局共享的,Calendar引用也会被共享。又因为Calendar内部并没有线程安全机制,所以全局共享的SimpleDateFormat不是线性安全的。

解决SimpleDateFormat线性不安全问题的方式:

1、将SimpleDateFormat定义成局部变量。

缺点:每调用一次方法就会创建一个SimpleDateFormat对象,方法结束又要作为垃圾回收。

2、方法加同步锁synchronized,在同一时刻,只有一个线程可以执行类中的某个方法。

缺点:性能较差,每次都要等待锁释放后其他线程才能进入。

3、使用第三方库joda-time,由第三方考虑线程不安全的问题。(可以使用)DateUtils (采用SimpleDateFormat定义成局部变量)

4、使用ThreadLocal:每个线程拥有自己的SimpleDateFormat对象。(推荐使用)

                                        JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替Simpledateformatter,官方给出的解释:simple                                       beautiful strong immutable thread-safe。

                       e.日期本地化问题

                              DateTimeFormatter 这个类默认进行本地化设置,如果默认是中文,解析英文字符串就会报异常。可以传入一个本地化参数(Locale.US)解决这个问题.

String dateStr = "Wed Mar 18 10:00:00 2020";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy",Locale.US);

LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);

System.out.println(dateTime) 

       3.5、时间函数的常用案例

                   1.java Date日期去掉时分秒: 参考(java Date日期去掉时分秒

查看代码
@Test
    public void  DateToDateForYYYYMMDD(){
        //第一种方式: 格式转换SimpleDateFormat
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date dt= sdf.parse(sdf.format(new Date()));
            System.out.println(dt);
        } catch (ParseException e) {
            throw new RuntimeException("时间转换异常", e);
        }
        //第二种方式 直接清除的方式
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date dt2=calendar.getTime();
        //第三种方式
        Long createTime = new Date().getTime();
        Date dt3 =new Date(createTime - ((createTime + 28800000) % (86400000)));

        System.out.println(dt2);
        System.out.println(dt3);
    }

                      执行结果分析:

                               三种方式执行结果是一致的;其中第三种方式中(把毫秒转换为日期:1 天 = 24 × 60 × 60 = 86400 秒  = 86400 x 1000 = 86400000毫秒,28800000是补上                          时区的8小时。

                   2.两个Date值比较年月的大小

                        

                   3.两个Date相差几个月,几天,几年,几个小时,几分钟,几秒问题

                   4.根据字符串赋初值

                           

                   5.时间格式的使用 DateTimeFormatter,SimpleDateFormat

                   6.Calendar 月份与年份相加

 

 

     

标签:JAVA,int,SimpleDateFormat,日期,时间,Date,Calendar
来源: https://www.cnblogs.com/q994321263/p/16153470.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有