前面的文章提到,Date是Java最早的日期工具,估计当时的设计师是个技术宅男,未经过充分调研就拍脑袋写下了Date的源码,造成该工具存在先天不足,比如getYear方法返回的不是纯正的公元纪年、getHours方法无法区分12小时制和24小时制等等,这很不利于Java语言的国际化。故而从JDK1.1开始,Java又提供了一个日历工具Calendar,官方建议采用Calendar替代Date,并且Date的相关get方法都被标记为Deprecated(意思是已废弃)。接下来就来看看这个全新的Calendar该当如何使用。
首先,创建日历实例调用的是getInstance方法,而非new关键字,日历实例的获取代码如下所示:

		// 创建一个日历实例
Calendar calendar = Calendar.getInstance();

其次,调用日历实例的get方法,获得指定时间单位的具体数值,例如类型Calendar.YEAR对应的是公元年份,类型Calendar.MONTH对应的是月份序号等等,以年份为例,具体的获取代码如下所示:

		// 获取日历实例中的年份
int year = calendar.get(Calendar.YEAR);
System.out.println("year="+year);

从以上代码可见,此时得到的年份数值无需额外加上1900,果然比Date省事多了。不过通过Calendar获取其它时间单位仍有两点需要注意:
1、Calendar的月份依然从0开始计数,也就是说,日历工具获取的一月份数值为0,十二月份的数值为11,于是获取月份的代码需要记得加一:

		// 获取日历实例中的月份
int month = calendar.get(Calendar.MONTH)+1;
System.out.println("month="+month);

2、原来Date的星期几从0开始计数,现在Calendar的星期几改为从1开始计数,可谓一大进步,不料它的星期仍旧以星期日打头、以星期六结尾。也就是说,日历工具获取的星期日数值为1,星期一数值为2,这样一来只好由程序员手工调整,按照国人习惯把星期一对应的数值改为1、把星期日对应的数值改为7等等。修改后的星期获取代码示例如下:

		// 获取日历实例中的星期几
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
dayOfWeek = dayOfWeek==1 ? 7 : dayOfWeek-1;
System.out.println("dayOfWeek="+dayOfWeek);

其它的时间单位中规中矩,无需额外的处理,与Date相比,Calendar新增了类型Calendar.DAY_OF_YEAR(从年初开始数的日子),以及Calendar.MILLISECOND(秒钟后面的毫秒),另外把时钟区分为Calendar.HOUR(十二小时制的时钟数值)和Calendar.HOUR_OF_DAY(二十四小时制的时钟数值)两种类型。这些普通时间单位的获取代码如下所示:

		// 获取日历实例中的日子
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println("dayOfMonth="+dayOfMonth);
// 获取日历实例中从年初开始数的日子
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
System.out.println("dayOfYear="+dayOfYear);
// 获取日历实例中的时钟(12小时制)
int hour = calendar.get(Calendar.HOUR);
System.out.println("hour="+hour);
// 获取日历实例中的时钟(24小时制)
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);
System.out.println("hourOfDay="+hourOfDay);
// 获取日历实例中的分钟
int minute = calendar.get(Calendar.MINUTE);
System.out.println("minute="+minute);
// 获取日历实例中的秒钟
int second = calendar.get(Calendar.SECOND);
System.out.println("second="+second);
// 获取日历实例中的毫秒
int milliSecond = calendar.get(Calendar.MILLISECOND);
System.out.println("milliSecond="+milliSecond);

再次,Calendar提供了set方法用于设置时间数值,并且重载了参数个数不同的多种set方法,其中带三个参数的set方法支持同时设置年月日,带六个参数的set方法支持同时设置年月日、时分秒。这两种set方法的调用代码示例如下:

		Calendar calendar = Calendar.getInstance();
// 调用带三个参数的set方法同时设置日历实例的年、月、日
calendar.set(2018, 11, 27);
// 调用带六个参数的set方法同时设置日历实例的年、月、日、时、分、秒
calendar.set(2018, 11, 27, 12, 30, 40);

如果只想修改某个时间单位,则可调用带两个参数的set方法,第一个参数为单位类型包括Calendar.YEAR、Calendar.MONTH等等,第二个参数为具体的时间数值。比如以下的代码表示把某个日期改为当月1号:

		// 带两个参数的set方法允许把某个时间单位改为指定数值
calendar.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("end set dayOfMonth="+calendar.get(Calendar.DAY_OF_MONTH));

注意到以上代码设置的日期是绝对值,有时候可能需要在当前日期上增增减减,也就是设置日期的相对值,此时可以联合使用get和set方法,先通过get方法获得当前的时间数值,对当前数值增减之后再传给set方法。下面的代码便演示了设置时间相对值的实现过程:

		// 联合使用get和set方法,可对某个时间单位进行增减
int dayResult = calendar.get(Calendar.HOUR_OF_DAY) + 1; // 给当前日期加上一天
calendar.set(Calendar.HOUR_OF_DAY, dayResult);
System.out.println("end set hourOfDay="+calendar.get(Calendar.HOUR_OF_DAY));

联合使用get和set方法固然实现了相对时间的修改,可是简简单单的功能还得两个步骤稍显繁琐,因此Calendar另外提供了add方法,利用add方法允许直接设置相对数值,就像下列代码示范的那样:

		// 调用add方法,直接在当前时间的基础上增加若干数值
calendar.add(Calendar.MINUTE, 10); // 给当前时间加上10分钟
System.out.println("end add minute="+calendar.get(Calendar.MINUTE));

日历工具Calendar就像它的前辈Date一样,仍然保留了与时间校验相关的几个方法,包括equals、before、after、compareTo方法等,并且它们的用法与Date类型的同名方法保持一致,这里不再赘述,还是直接看下面的时间比较代码好了:

	// 比较两个日历时间的先后关系
private static void compareCalendar() {
Calendar calendarOld = Calendar.getInstance();
Calendar calendarNew = Calendar.getInstance();
// 给calendarNew加上一秒
calendarNew.add(Calendar.SECOND, 1);
// 比较两个时间是否相等
boolean equals = calendarOld.equals(calendarNew);
System.out.println("equals="+equals);
// 比较A时间是否在B时间之前
boolean before = calendarOld.before(calendarNew);
System.out.println("before="+before);
// 比较A时间是否在B时间之后
boolean after = calendarOld.after(calendarNew);
System.out.println("after="+after);
// 比较A时间与B时间的先后关系。返回-1表示A时间较早,返回0表示两个时间相等,返回1表示B时间较早
int compareResult = calendarOld.compareTo(calendarNew);
System.out.println("compareResult="+compareResult);
}

  

更多Java技术文章参见《Java开发笔记(序)章节目录

Java开发笔记(四十一)日历工具Calendar的更多相关文章

  1. Java开发学习(四十一)----MyBatisPlus标准数据层(增删查改分页)开发

    一.标准CRUD使用 对于标准的CRUD功能都有哪些以及MyBatisPlus都提供了哪些方法可以使用呢? 我们先来看张图: 1.1 环境准备 这里用的环境就是Java开发学习(四十)----MyBa ...

  2. Java开发笔记(十一)常见的数学函数

    前面介绍了Java编程的四则运算,虽然提供了基础的加减乘除符号,但是数学上还有其它运算符号,包括四舍五入用到的约等号≍.求绝对值的“| |”.开平方的“√ ̄”,这些运算符形态各异,而且并非ASCII码 ...

  3. Java开发笔记(序)章节目录

    现将本博客的Java学习文章整理成以下笔记目录,方便查阅. 第一章 初识JavaJava开发笔记(一)第一个Java程序Java开发笔记(二)Java工程的帝国区划Java开发笔记(三)Java帝国的 ...

  4. Java开发笔记(四十二)日历工具的常见应用

    前面介绍了日历工具Calendar的基本用法,乍看起来Calendar与Date两个半斤八两,似乎没有多大区别,那又何苦庸人自扰鼓捣一个新玩意呢?显然这样小瞧了Calendar,其实它的作用大着呢,接 ...

  5. Java开发笔记(七十一)容器工具Collections

    清单作为一组数据的有序队列,它在组织形式上与数组有着某些异曲同工之处,数组有专门的数组工具Arrays来进行加工操作,照理清单也应该配备对应的清单工具.当然容器这个大家族确实拥有自己的容器工具Coll ...

  6. Java开发笔记(八十一)如何使用系统自带的注解

    之前介绍继承的时候,提到对于子类而言,父类的普通方法可以重写也可以不重写,但是父类的抽象方法是必须重写的,如果不重写,编译器就直接在子类名称那里显示红叉报错.例如,以前演示抽象类用法之时,曾经把Chi ...

  7. Java开发笔记(四十三)更好用的本地日期时间

    话说Java一连设计了两套时间工具,分别是日期类型Date,以及日历类型Calendar,按理说用在编码开发中绰绰有余了.然而随着Java的日益广泛使用,人们还是发现了它们的种种弊端.且不说先天不良的 ...

  8. Java开发笔记(二十三)数组工具Arrays

    数组作为一种组合形式的数据类型,必然要求提供一些处理数组的简便办法,包括数组比较.数组复制.数组排序等等.为此Java专门设计了Arrays工具,该工具包含了几个常用方法,方便程序员对数组进行加工操作 ...

  9. Java开发笔记(四十四)本地日期时间与字符串的互相转换

    之前介绍Calendar的时候,提到日历实例无法直接输出格式化后的时间字符串,必须先把Calendar类型转换成Date类型,再通过格式化工具SimpleDateFormat获得字符串.而日期时间的格 ...

随机推荐

  1. ES 6 proimse &&iterator &&Generator函数 &&async

    1.proimse 异步调用function getData(){ let promise =new Promise((resolve,reject)); let xmlHttp =new XMLHt ...

  2. linux操作命令之帮助命令

    一.man命令的帮助: man 命令名 获取指定命令的帮助 例如man ls 查看ls的帮助 man man可以看到man有8个级别的man帮助命令使用场景 1.查看命令的帮助 2.查看可被内核调用的 ...

  3. Excel大批量数据导出

    package com.tebon.ams.util; import lombok.extern.slf4j.Slf4j;import org.apache.poi.openxml4j.excepti ...

  4. PHP_DOC php文档结构及注解浏览

    项目中的PHP文件比较多,为了方便查看,使用PHP写了个小工具,可查看PHP文件的所有类.函数 和特定注释. 显示PHP文件的 Class 和 Function 显示 /// 开头的注解 显示 /// ...

  5. #Java学习之路——基础阶段(第八篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  6. [Swift]LeetCode343. 整数拆分 | Integer Break

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  7. [Swift]LeetCode358. 按距离为k隔离重排字符串 $ Rearrange String k Distance Apart

    Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...

  8. Unable to preventDefault inside passive event listener due to target being treated as passive

    Unable to preventDefault inside passive event listener due to target being treated as passive 今天在做项目 ...

  9. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  10. android 缩放平移自定义View 显示图片

    1.背景 现在app中,图片预览功能肯定是少不了的,用户基本已经形成条件反射,看到小图,点击看大图,看到大图两个手指开始进行放大,放大后,开始移动到指定部位~~~ 我相信看图的整个步骤,大家或者说用户 ...