欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-01-14 07:56:36
话说Java一连设计了两套时间工具,分别是日期类型Date,以及日历类型Calendar,按理说用在编码开发中绰绰有余了。然而随着Java的日益广泛使用,人们还是发现了它们的种种弊端。且不说先天不良的Date类型,单说后起之秀的Calendar类型,这个日历工具在实际开发中仍然存在以下毛病:1、日历 ......

话说java一连设计了两套时间工具,分别是日期类型date,以及日历类型calendar,按理说用在编码开发中绰绰有余了。然而随着java的日益广泛使用,人们还是发现了它们的种种弊端。且不说先天不良的date类型,单说后起之秀的calendar类型,这个日历工具在实际开发中仍然存在以下毛病:
1、日历工具获取当前月份的时候,与date一样都是从0开始计数,比如通过get方法获得的一月份数值为0;
2、日历工具获取当天是星期几的时候,星期日是排在最前面的,通过get方法获得的星期日数值为1,而星期一数值居然是2!
3、日历工具能够表达的最小时间单位是毫秒,使得时间精度不够高,难以用在更加精密的科学运算场合。
4、日历工具没有提供闰年的判断方法。
5、日历工具缺乏自己的格式化工具,居然还得借助于date类型那边的格式化工具simpledateformat,方能将日期时间按照指定格式输出为字符串。
总而言之,不管是date还是calendar,在解决复杂问题之时的编码都很别扭,故而每个java工程基本要重新编写一个日期处理工具dateutil,在新工具内部封装常见的日期处理操作,这样才能满足实际业务的开发要求。于是date和calendar两个难兄难弟从jdk1.1开始并肩作战,一路走到java5、java6乃至java7,后来估摸着无可救药了,干爹oracle一不做、二不休,终于在java8推出了全新的日期时间类型,意图通过新类型一劳永逸治好date和calendar的沉疴宿疾。
全新的日期时间类型不单单是一个类型,而是一个家族,它的成员主要有localdate、localtime、localdatetime等等,接下来分别介绍这几个日期时间类型:

1、本地日期类型localdate
获取本地日期的实例很简单,调用该类型的now方法即可,并且顾名思义得到的是当前日期。通过本地日期获取年月日的数值,就是日常生活中的习惯数字,例如一月份对应的数值是1,十二月份对应的数值是12,星期一对应的数值是1,星期日对应的数值是7等等。此外,本地日期额外提供了几个常用的统计方法,包括:该日期所在的年份一共有多少天、该日期所在的月份一共有多少天、该日期所在的年份是否为闰年等。下面的代码便演示了如何从本地日期获取各种数值的例子:

		// 获得本地日期的实例
		localdate date = localdate.now();
		system.out.println("date=" + date.tostring());
		// 获得该日期所在的年份
		int year = date.getyear();
		system.out.println("year=" + year);
		// 获得该日期所在的月份。注意getmonthvalue方法返回的是数字月份,而getmonth方法返回的是英文月份
		int month = date.getmonthvalue();
		system.out.println("month=" + month + ", english month=" + date.getmonth());
		// 获得该日期所在的日子
		int dayofmonth = date.getdayofmonth();
		system.out.println("dayofmonth=" + dayofmonth);
		// 获得该日期在一年当中的序号
		int dayofyear = date.getdayofyear();
		system.out.println("dayofyear=" + dayofyear);
		// 获得该日期是星期几。注意getdayofweek方法返回的是英文的星期几,后面跟着的getvalue方法才返回数字的星期几
		int dayofweek = date.getdayofweek().getvalue();
		system.out.println("dayofweek=" + dayofweek + ", english weekday=" + date.getdayofweek());
		// 获得该日期所在的年份一共有多少天
		int lengthofyear = date.lengthofyear();
		system.out.println("lengthofyear=" + lengthofyear);
		// 获得该日期所在的月份一共有多少天
		int lengthofmonth = date.lengthofmonth();
		system.out.println("lengthofmonth=" + lengthofmonth);
		// 判断该日期所在的年份是否为闰年
		boolean isleapyear = date.isleapyear();
		system.out.println("isleapyear=" + isleapyear);

 

除了创建处于当前日期的本地实例,localdate还支持创建指定日期的本地实例,就像以下代码示范的那样:

		// 构造一个指定年月日的日期实例
		localdate datemanual = localdate.of(2018, 11, 22);
		system.out.println("datemanual=" + datemanual.tostring());

 

至于针对某个单位的数值,localdate也提供了专门的修改方法,例如以plus打头的系列方法用来增加日期数值,以minus打头的系列方法用来减少日期数值,以with打头的系列方法用来设置日期数值,这些日期修改的具体用法示例如下:

		datemanual = datemanual.plusyears(0); // 增加若干年份
		datemanual = datemanual.plusmonths(0); // 增加若干月份
		datemanual = datemanual.plusdays(0); // 增加若干日子
		datemanual = datemanual.plusweeks(0); // 增加若干星期
		datemanual = datemanual.minusyears(0); // 减少若干年份
		datemanual = datemanual.minusmonths(0); // 减少若干月份
		datemanual = datemanual.minusdays(0); // 减少若干日子
		datemanual = datemanual.minusweeks(0); // 减少若干星期
		datemanual = datemanual.withyear(2000); // 设置指定的年份
		datemanual = datemanual.withmonth(12); // 设置指定的月份
		datemanual = datemanual.withdayofyear(1); // 设置当年的日子
		datemanual = datemanual.withdayofmonth(1); // 设置当月的日子

 

此外,作为一种日期类型,localdate一如既往地支持判断两个日期实例的早晚关系,比如equals方法用于判断两个日期是否相等,isbefore方法用于判断a日期是否在b日期之前,isafter方法用于判断a日期是否在b日期之后等。具体的本地日期校验代码如下所示:

		// 判断两个日期是否相等
		boolean equalsdate = date.equals(datemanual);
		system.out.println("equalsdate=" + equalsdate);
		// 判断a日期是否在b日期之前
		boolean isbeforedate = date.isbefore(datemanual);
		system.out.println("isbeforedate=" + isbeforedate);
		// 判断a日期是否在b日期之后
		boolean isafterdate = date.isafter(datemanual);
		system.out.println("isafterdate=" + isafterdate);
		// 判断a日期是否与b日期相等
		boolean isequaldate = date.isequal(datemanual);
		system.out.println("isequaldate=" + isequaldate);

  

2、本地时间类型localtime
前面介绍的localdate只能操作年月日,若要操作时分秒则需通过本地时间类型localtime。获取本地时间的实例依然要调用该类型的now方法,接着就能通过该实例分别获取对应的时分秒乃至纳秒(一秒的十亿分之一),下面便演示了如何调用localtime的基本方法:

		// 获得本地时间的实例
		localtime time = localtime.now();
		system.out.println("time=" + time.tostring());
		// 获得该时间所在的时钟
		int hour = time.gethour();
		system.out.println("hour=" + hour);
		// 获得该时间所在的分钟
		int minute = time.getminute();
		system.out.println("minute=" + minute);
		// 获得该时间所在的秒钟
		int second = time.getsecond();
		system.out.println("second=" + second);
		// 获得该时间秒钟后面的纳秒单位。一秒等于一千毫秒,一毫秒等于一千微秒,一微秒等于一千纳秒,算下来一秒等于十亿纳秒
		int nano = time.getnano();
		system.out.println("nano=" + nano);

 

如同本地日期localdate那样,localtime也允许创建指定时分秒的时间实例,还支持单独修改时钟、分钟、秒钟和纳秒。当然修改时间的途径包括plus系列方法、minus系列方法、with系列方法等等,它们的调用方式示例如下:

		// 构造一个指定时分秒的时间实例
		localtime timemanual = localtime.of(14, 30, 25);
		system.out.println("timemanual=" + timemanual.tostring());
		timemanual = timemanual.plushours(0); // 增加若干时钟
		timemanual = timemanual.plusminutes(0); // 增加若干分钟
		timemanual = timemanual.plusseconds(0); // 增加若干秒钟
		timemanual = timemanual.plusnanos(0); // 增加若干纳秒
		timemanual = timemanual.minushours(0); // 减少若干时钟
		timemanual = timemanual.minusminutes(0); // 减少若干分钟
		timemanual = timemanual.minusseconds(0); // 减少若干秒钟
		timemanual = timemanual.minusnanos(0); // 减少若干纳秒
		timemanual = timemanual.withhour(0); // 设置指定的时钟
		timemanual = timemanual.withminute(0); // 设置指定的分钟
		timemanual = timemanual.withsecond(0); // 设置指定的秒钟
		timemanual = timemanual.withnano(0); // 设置指定的纳秒

 

另外,localtime依然提供了equals、isbefore、isafter等方法用于判断两个时间的先后关系,具体的方法调用如下所示:

		// 判断两个时间是否相等
		boolean equalstime = time.equals(timemanual);
		system.out.println("equalstime=" + equalstime);
		// 判断a时间是否在b时间之前
		boolean isbeforetime = time.isbefore(timemanual);
		system.out.println("isbeforetime=" + isbeforetime);
		// 判断a时间是否在b时间之后
		boolean isaftertime = time.isafter(timemanual);
		system.out.println("isaftertime=" + isaftertime);

  

3、本地日期时间类型localdatetime
现在有了localdate专门处理年月日,又有了localtime专门处理时分秒,还需要一种类型能够同时处理年月日和时分秒,它就是本地日期时间类型localdatetime。localdatetime基本等价于localdatetime与localtime的合集,它同时拥有二者的绝大部分方法,故这里不再赘述。下面是创建该类型实例的代码片段,读者可参考之前localdatetime与localtime的调用代码,尝试补齐localdatetime的方法调用过程。

	// 演示localdatetime的各种方法
	private static void showlocaldatetime() {
		// 获得本地日期时间的实例
		localdatetime datetime = localdatetime.now();
		system.out.println("datetime=" + datetime.tostring());
		// localdatetime的方法是localdate与localtime的合集,
		// 也就是说localdate与localtime的大部分方法可以直接拿来给localdatetime使用,
		// 因而下面不再演示localdatetime的详细方法如何调用了。
		// 注意localdatetime不提供lengthofyear、lengthofmonth、isleapyear这三个方法。
	}

  


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