真正理解java calendar抽象类来写一个万年历

真正理解java calendar抽象类来写一个万年历,第1张

真正理解java calendar抽象类来写一个万年历

真正理解java calendar抽象类来写一个万年历

真正理解java calendar抽象类来写一个万年历

java自带的calendar类虽然有些蹩脚,但写一个万年历还是可以的。远远没有其他资源的复杂。因为他们根本没有充分使用calendar。全部代码在最后。本文对生成一个万年历需要的calendar字段,方法进行了简单解释。

1.首先导入两个包

import java.util.Calendar;
import java.util.Scanner;

第一个是日历类,第二个扫描类,可以从键盘读入数据。

  1. calendar最基本方法getInstance();函数
    public static Calendar getInstance();使用默认时区和语言环境获得一个日历。返回的 Calendar 基于当前时间,使用了默认时区和默认语言环境。
Calendar calendar = Calendar.getInstance();

返回:一个 Calendar。
calendar是一个抽象类,它的字段有当前日历的各种字段,比如年YEAR,月MONTH,日DAY_OF_MONTH。这些都属于基本使用。
我们可以打印一下这个日历的字符串形式,看一下。

System.out.println(calendar.toString());

结果:
java.util.GregorianCalendar[time=1634728544294,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=“Asia/Shanghai”,offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,
YEAR=2021,
MonTH=9,
WEEK_OF_YEAR=43,WEEK_OF_MonTH=4,
DAY_OF_MonTH=20,
DAY_OF_YEAR=293,
DAY_OF_WEEK=4,
DAY_OF_WEEK_IN_MonTH=3,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=15,SECOND=44,MILLISECOND=294,ZONE_OFFSET=28800000,DST_OFFSET=0]
将几个重要的字段。DAY_OF_WEEK就这一天是这一周的第几天,周日是第一天。

  1. Calendar重要函数
    这里摘出最重要的几个函数get,set, add,roll。
    get:
    函数代码:
    public int get(int field)
    解释:field参数就是日历的字段,通过这个函数你就可以获得日历某一字段的值。示例:
System.out.println(calendar.get(Calendar.YEAR));

结果:2021
set:
函数代码:
public void set(int field,int value)
解释:这个函数可以给日历设定你想要的值,为什么说java的Calendar蹩脚呢,就是在这个函数上,它可以设立但并不会相应地改变日历字段的其他值,比如你改变本月的日期,DAY_OF_WEEK值不会改变,仍然显示之前日历的值。示例:

		System.out.println(calendar.toString());
		calendar.set(Calendar.DAY_OF_MONTH,21);
		System.out.println(calendar.toString());	

运行结果:

可以看到,日期已经变了,但DAY_OF_WEEK字段并没有变。
add:
函数代码:
public abstract void add(int field, int amount)
roll:
函数代码:
public abstract void roll(int field,boolean up)
这两个函数要对比着讲,add函数会增加或者减少日历的某一字段,而其它字段会受它的影响,比如3月最后一天,在DAY_OF_MONTH,减少一天,它的月份就会变为2月,日期是最后一天。而roll也会影响比它小的字段,而不会影响比它大的字段,比如还是3月最后一天,roll减一天,就会变为3月的第一天。这两个函数影响其他字段的意思就是,根据这两个函数修改的日历会相应的修改DAY_OF_WEEK等其他字段。
使用细节:add实现日期减,就是amount值用负数。roll,后面的布尔值为true,字段加一,false,字段减一。
为什么老提DAY_OF_WEEK这个字段呢?因为我们要做万年历最重要的一点就是知道这个月第一天是周几。
4. 万年历实现思路
首先用scanner读取年份,月份。用set函数设置一个这一年这一月1号的日历。这里有个小细节,日历存月份是从0-11。示例:

calendar.set(year,mon - 1,18,1,1,1);

然后设置当前时间的日历,用getInstance函数。
然后用add函数讲当前日历滚到设置的日历,这里先年份循环,再月份循环,再日循环。
通过roll减一,读取WEEK_OF_MONTH字段,获取本月有几周。
最后格式化输出。
5. 完整代码

package sdu.java.exam.fourth;

import java.util.Calendar;
import java.util.Scanner;
public class CalendarText {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Calendar cal = Calendar.getInstance();
		Calendar rightnow = Calendar.getInstance();
		
		Scanner input=new Scanner(System.in);
		System.out.println("请输入年份:");
		int year = input.nextInt();	
		System.out.println("请输入月份:");
		int mon = input.nextInt();
		input.close();
		
		cal.set(year,mon - 1,1,1,1,1);
		
		//跳转到指定年份
		if(year > rightnow.get(Calendar.YEAR)) {
			do {
				rightnow.add(Calendar.YEAR, 1);
			}while(year > rightnow.get(Calendar.YEAR));
			
		}
		else if(year < rightnow.get(Calendar.YEAR)) {
				do {
					rightnow.add(Calendar.YEAR, -1);
			}while(year < rightnow.get(Calendar.YEAR));
		}
		
		//跳转到指定月份
		if(mon - 1 > rightnow.get(Calendar.MONTH)) {
			do {
				rightnow.add(Calendar.MONTH, 1);
			}while(mon - 1 > rightnow.get(Calendar.MONTH));
		}
		else if (mon - 1 < rightnow.get(Calendar.MONTH)) {
			do {
				rightnow.add(Calendar.MONTH, -1);
			}while(mon - 1 < rightnow.get(Calendar.MONTH));
		}
		
		//跳转到1号
		if(rightnow.get(Calendar.DAY_OF_MONTH) != 1) {
			do {
				rightnow.add(Calendar.DAY_OF_MONTH, -1);
			}while(rightnow.get(Calendar.DAY_OF_MONTH) != 1);
		}
		
		//System.out.println(rightnow.toString());
		
		//获得该月的周数
		rightnow.roll(Calendar.DAY_OF_MONTH, false);
		int week = rightnow.get(Calendar.WEEK_OF_MONTH);
		rightnow.roll(Calendar.DAY_OF_MONTH, true);

		//开始格式输出日历
		System.out.println("		------" + cal.get(Calendar.YEAR) + "年" + (cal.get(Calendar.MONTH)+1) + "月------");
		System.out.println("");
		System.out.println("日	 一	二	三	四	五	六");
		int firstDay = rightnow.get(Calendar.DAY_OF_WEEK);
		rightnow.add(Calendar.DAY_OF_MONTH, -(firstDay - 1));
		
		for(int i = 0; i < week; i++) {
			for(int j = 0; j < 7; j++) {
				System.out.print(rightnow.get(Calendar.DAY_OF_MONTH) + "	");
				rightnow.add(Calendar.DAY_OF_MONTH, 1);
			}
			System.out.println();
		}
		
	}

}

运行结果:

小细节:调间距用Tab键。

补充:

set函数可以有多种设立日期的方式,自己可以去看API。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4013947.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-22
下一篇 2022-10-22

发表评论

登录后才能评论

评论列表(0条)

保存