Java 时间类-Calendar、Date、LocalDate/LocalTime

1、Date 类

java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,如果你只想用java.util.Date存储日期,或者只存储时间,那么,只有你知道哪些部分的数据是有用的,哪些部分的数据是不能用的。

  1.1 Date的构造方法

  Date 是我们使用的最多的一个日期类,Date提供的构造方法在官方API中有一下几种:

  Date 类提供了多种构造方法,但是目前有很多方法都已经不建议使用

public Date() {
        this(System.currentTimeMillis());
    }

 public Date(long date) {
        fastTime = date;
    }

 @Deprecated
    public Date(int year, int month, int date) {
        this(year, month, date, 0, 0, 0);
    }

@Deprecated
    public Date(int year, int month, int date, int hrs, int min) {
        this(year, month, date, hrs, min, 0);
    }

  @Deprecated
    public Date(int year, int month, int date, int hrs, int min, int sec)

 @Deprecated
    public Date(String s) {
        this(parse(s));
    }

  目前我们可以通过使用:

Date date0 = new Date();
Date date1 = new Date(time);

  这两种方法创建对象的不同主要是通过指定的时间戳不同,通过设置Date 中的  fastTime 进行设置Date 对象的时间。

除了使用构造方法获取实例,Date 还可以通过 Instant 来创建一个Date 实例:

Instant instant = Instant.now();
Date date = Date.from(instant);

   Instant 是Java 8 提供的新特性:

  1.2 Date的常用方法

     Date 类中,提供了常用的获取:年,月,日,时,分,秒等方法:

        Date date = new Date();
        int dates = date.getDate();

        int year = date.getYear();
        int month = date.getMonth();
        int day = date.getDay();

        int hours = date.getHours();
        int min = date.getMinutes();
        int second = date.getSeconds();

        long time = date.getTime();
        int times = date.getTimezoneOffset();

    输出结果:

dates: 14
year: 116
month: 11
day: 3
hours: 15
min: 8
second: 29
time: 1481699309422
times: -480

     读者可能会发现,这里的年份并不是我们想要的,这里主要是因为代码方法实现:

            我们可以看到,这里的getYear 并不是获取当前年份,而是获取到和1900年的差值,这里主要是因为JDK老版本遗留下来的问题,对于Date 中获取年月日的方法,现在已经不建议使用了。

Date类中也提供了一些设置日期的方法:

      与上面的get方法是一一对应的,但是现在也同样不建议使用了。

1.3 Date的总结

    经过我们上述的分析,我们发现,Date 类如今很多方法已经没有什么用处了,确实,如今时间的处理并不直接在Date 类中进行,而是通过Calendar,或者LocalDate 来进行,我们再日常使用中,更多的是要来做一个记录日期的实例。

2、Calendar 类

  介绍一下Date 与 Calendar 的区别

Date用于记录某一个含日期的、精确到毫秒的时间。重点在代表一刹那的时间本身。   Calendar用于将某一日期放到历法中的互动——时间和年、月、日、星期、上午、下午、夏令时等这些历法规定互相作用关系和互动。Calendar本身代表公历的一个简化缩水版,姑且叫“计算机历”。

  完整的公历是格里高利历,Java SE中以GregorianCalendar类来提供相关的历法功能。

2.1 Calendar 的构造方法

    我们可以看到,Calendar 中的构造方法被封装在包中,我们无法直接通过构造方法来创建一个新的实例对象,我们只能通过调用 Calendar中的静态方法 Calendar.getInstance()方法获取一个实例对象。

    我们看一下官方API 中提供了哪些方法获取Calendar 对象:

    这是官方文档给出的获取去对象实例的方法,我们可以看到,我们可以通过指定TimeZoneLocale 来获取特定的 Calendar 对象,这也却分了每个地区的时间日历,方便开发者使用

    除了通过getInstance() 方法获取实例以外,Java 1.8 提供了一个内部类:

    我们可以通过创建一个Builder 的实体,然后通过调用Build 方法获取一个 Calendar 实例。

    在Builder 中,Builder 类提供了设置年月日的方法,可以通过设置时间,来获取特定的Calendar 对象。

Calendar.Builder builder =new Calendar.Builder();
Calendar calendar1 = builder.build();
Date date = calendar.getTime();

这里总结一下:

        Calendar 提供的获取实例的方法主要有两种途径:

          1、调用Calendar.getInstance()方法

            2、创建内部类Builder 的实例,通过调用其 build()方法创建 Calendar 实例

      对于第一种方法,只能先获取当前时间的Calendar,然后再通过调用相应的set 方法设置年月日等,而如果使用内部类Builder 方法,可以通过setInstant 方法设置我们所期望的时间。

2.2 Calendar 的常用方法

    我们最常用的方法有:

Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();

    通过Calendar 方法获取一个Date 的实例。

    Calendar 方法获取年月日的方法:

        int year =calendar.get(Calendar.YEAR);

        int month=calendar.get(Calendar.MONTH)+1;

        int day =calendar.get(Calendar.DAY_OF_MONTH);

        int hour =calendar.get(Calendar.HOUR_OF_DAY);

        int minute =calendar.get(Calendar.MINUTE);

        int seconds =calendar.get(Calendar.SECOND);    

        我们可以看到Calendar 里面获取年月日不像上面 Date 类中的通过访问各个方法来获取。

    Calendar 在初始化的时候,就已经将年月日划分好,并且存入fields 变量中。我们只需要传入每个位置编号,就可以获取我们需要的信息

    除了获取以外,Calendar 也提供了相应的set 方法:

    通过重新传入参数,设置Calendar 的时间

    Calendar 获取当前月份,当前星期的最大\小天数

        System.out.println(calendar.getActualMaximum(Calendar.DAY_OF_WEEK));
        System.out.println(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        System.out.println(calendar.getActualMinimum(Calendar.DAY_OF_WEEK));
        System.out.println(calendar.getActualMinimum(Calendar.DAY_OF_MONTH));   

    提供了Before 和After 两个方法,用于判断当前时间与对比时间先后:

    提供了add 方法进行日期的加减

calendar.add(10,10);

2.3 Calendar 的总结

          从上面的分析我们可以看到,Calendar 类 主要是用于作为日历的对象,可以铜鼓哦设置地区时间,区分每个地区的日期,Calendar 提供的方法也没有很多对时间进行的一些操作。

3、LocalDate/LocalTime 类

      Java 8新增了LocalDateLocalTime接口,为什么要搞一套全新的处理日期和时间的API?因为旧的java.util.Date实在是太难用了。

      java.util.Date月份从0开始,一月是0,十二月是11,变态吧!java.time.LocalDate月份和星期都改成了enum,就不可能再用错了。

      java.util.DateSimpleDateFormatter都不是线程安全的,而LocalDateLocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。

3.1 LocalDate/LocalTime 的构造方法

3.1.1 LocalDate 的构造方法:

        LocalDate 并没有提供公开的构造方法,只提供了一个封装的构造方法供内部使用。

    private LocalDate(int year, int month, int dayOfMonth) {
        this.year = year;
        this.month = (short) month;
        this.day = (short) dayOfMonth;
    }

      LocalDate 提供了三种创建实例的方法:

        //获取当前时间的LocalDate
        LocalDate localDate = LocalDate.now();
        //获取指定年、月、日 的 LocalDate
        LocalDate ofDate = LocalDate.of(2016,12,31);
        //通过解析字符串获取 LocalDate,如果格式不对会抛出 DateTimeParseException
        LocalDate parseDate = LocalDate.parse("2016-12-31-");

      3.1.2 LocalTime 的构造方法:

        LocalTime 与LcoalDate 一样,提供了一个封装的构造方法:

    private LocalTime(int hour, int minute, int second, int nanoOfSecond) {
        this.hour = (byte) hour;
        this.minute = (byte) minute;
        this.second = (byte) second;
        this.nano = nanoOfSecond;
    }

        LocalTime 提供了三种创建方法:

        LocalTime localTime = LocalTime.now().withNano(0);
        LocalTime ofTime = LocalTime.of(16,30,25);
        LocalTime parseTime = LocalTime.parse("12:00:01");

3.2 LocalDate/LocalTime 的常用方法

获取当天的起始时间:atStartOfDay()

    LocalDate localDate = LocalDate.now();
        LocalDateTime date = localDate.atStartOfDay();

    输出:
    2016-12-14T00:00

      设置当前日期的时间:atTime()

        LocalDate localDate = LocalDate.now();
        LocalDateTime date = localDate.atTime(16,25,30);
    
        输出:
            2016-12-14T16:25:30

      格式转换:format()

      常用的获取年、月、日 等方法

        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        int day = localDate.getDayOfMonth();

      获取改变月份的LocalDate :withMonth()

        LocalDate localDate = LocalDate.now();
        LocalDate d = localDate.withMonth(10);

      其他常用的日期转换:

// 取本月第1天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2014-12-01
// 取本月第2天:
LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2014-12-02
// 取本月最后一天,再也不用计算是28,29,30还是31:
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2014-12-31
// 取下一天:
LocalDate firstDayOf2015 = lastDayOfThisMonth.plusDays(1); // 变成了2015-01-01
// 取2015年1月第一个周一,这个计算用Calendar要死掉很多脑细胞:
LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2015-01-05

3.3 LocalDate/LocalTime 的总结

      在新的Java 8中,日期和时间被明确划分为LocalDateLocalTimeLocalDate无法包含时间,LocalTime无法包含日期。当然,LocalDateTime才能同时包含日期和时间。

      新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从流域到海域

《Java程序设计基础》 第8章手记Part 1

本章主要内容 Part 1 - 子类的创建 - 在子类中访问父类的成员 - 覆盖父类的方法 - …… 本章主要讲继承、抽象类和接口,这...

1865
来自专栏微信公众号:Java团长

Java中的十个"单行代码编程"(One Liner)

本文列举了十个使用一行代码即可独立完成(不依赖其他代码)的业务逻辑,主要依赖的是Java8中的Lambda和Stream等新特性以及try-with-resou...

822
来自专栏小灰灰

Java 反射简单实例

反射 什么是反射,反射有什么用,反射该怎么用? 一些概念性的东西,这里就不细说了,下面主要给出一个非常简单的反射的调用工具类; 后续会提供一个基于Spring...

1945
来自专栏用户2442861的专栏

JAVA注解

      http://blog.csdn.net/rj042/article/details/6399965

892
来自专栏java思维导图

【一分钟知识】HashSet和TreeSet,HashMap与HashTable

java思维导图 xmind导图配合精美文章,可视化学习,让java不再难懂。 ? ? HashSet和TreeSet HashSet 哈希表实现的,HashS...

3357
来自专栏小灰灰

JDK容器学习之TreeMap (一) : 底层数据结构

TreeMap 在日常的工作中,相比较与HashMap而言,TreeMap的使用会少很多,即使在某些场景,需要使用到排序的Map时,也更多的是选择 Linke...

1839
来自专栏Create Sun

基础拾遗------接口详解

  接口定义了所有类继承接口时应遵循的契约。接口定义了 "要什么" ,派生类定义了 "怎么给" 。  引用CLR VIA C#(类和接口继承)   在Mi...

3468
来自专栏zhisheng

SimpleDateFormat 如何安全的使用?

看到这条我立马就想起了我实习的时候有个项目里面就犯了这个错误,记得当时是这样写的:

611
来自专栏Java编程

Java习惯用法总结

在Java编程中,有些知识 并不能仅通过语言规范或者标准API文档就能学到的。在本文中,我会尽量收集一些最常用的习惯用法,特别是很难猜到的用法。(Joshua ...

1K3
来自专栏10km的专栏

fastjson:javabean按字段(field)序列化存储为Map并反序列化

大部分json工具对java对象整体序列化都提供了简单的调用方式,以fastjson为例: Model model = new Model(); String ...

2575

扫码关注云+社区