这里的万年历制作主要用到了Calendar类和GregorianCalendar类,我们先来回顾一下基础知识:
基础部分
一、Calendar类。1,主要字段:
YEAR(年份)、MONTH(月份从0开始)、DATE(一月的某天)、HOUR(指示上午或下午的小时)、HOUR_F_DAY(指示一天中的小时。)、DAY_OF_WEEK (一个星期中的某天)、DAY_OF_MONTH(一个月中的某天)、DAY_OF_YEAR(一年中的某天)、DAY_OF_WEEK _IN_MONTH(一个月中的第几个星期)、WEEK_OF_MONTH (指示当前月中的星期数)、WEEK_OF_YEAR(指示当前年中的星期数)
2,得Calendar类对象。
//通过 Calendar类的静态方法getInstance获得。
Calendar ca = Calendar.getInstance();
3,主要方法
void set(int field,int value)//field日历类的参数,比如YEAR MONTH DATE 等...
void set(int year,int month,int date)//设置年月日。
void set(int year, int month, int date, int hourOfDay, int minute)//设置年月日时分
void set(int year, int month, int date, int hourOfDay, int minute, int second)//设置年月日时分秒
void setTime(Date date);//使用给定的 Date 设置此 Calendar 的时间。
int get(int field)//返回给定日历字段的值。如:int month = acobj.get(Calendar.MONTH);
Date getTime()//返回一个表示此 Calendar 时间值的 Date 对象。
long getTimeInMillis()//返回从1970.1.1 00:00:00到该日历的毫秒数。
void add(int field,amont);//根据日历的规则,为给定的日历字段添加或减去指定的时间量。可加减。如:caobj.add(Calendar.MONTH,1)下一个月。
二、GregorianCalendar类。1,获得该类对象
Calendar ca = new GregorianCalendar()//默认当前的时刻。
Calendar ca = new GregorianCanlendar(int year,int month,int dayOfMonth)//初始具有指定年月日的公历类对象。
Calendar ca = new GregorianCanlendar(int year,int month,int dayOfMonth,int hourOfDay,int minute)初始具有指定年月日的公历类对象。
Calendar ca = new GregorianCanlendar(int year,int month,int dayOfMonth,int hourOfDay,int minute,int second)//初始具有指定年月日的公历类对象。
上边的都是获得默认的语言环境,和默认的时区 对象。
2,用法
用法主要继承去父类Calendar。
实例部分三、万年历代码
package com.via.mce.monthcalendar.utils;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
/**
* 农历日历。
* 将农历从1901年到2100年之间各年、月的大小以及历年节气保存,然后基于这些数据进行计算。
*
* 新增了几个用于农历的常量属性字段,可以使用get()方法获取日历对应的值;
* 农历年、月、日还可以使用set()/add()/roll()方法设置,其他农历属性自动计算;
* 另外,还提供了getChinese(int field)方法用于获得农历的中文文字(仅适用于农历属性和星期)。
*
*
CHINESE_YEAR - 农历年*
CHINESE_MONTH - 农历月*
CHINESE_DATE - 农历日*
CHINESE_SECTIONAL_TERM - 当月的节气*
CHINESE_PRINCIPLE_TERM - 当月的中气*
CHINESE_HEAVENLY_STEM - 农历年的天干*
CHINESE_EARTHLY_BRANCH - 农历年的地支*
CHINESE_ZODIAC - 农历年的属相*
CHINESE_TERM_OR_DATE - 如果当天存在一个节气则指示节气,否则如果当天是初一则指示农历月,否则指示农历日*
* 注意:
* 由于Calendar类的设定,公历月份从0起始。所有方法都遵循了这一约定。
* 但所有的农历属性从1起始。即使是在Calendar提供的方法中,农历月也是从1起始的,并以负数表示闰月。
* clear()方法在某些情况下会导致农历和公历日期不对应或是不能达到预期的重置效果,应尽量避免使用。
* 使用getSimpleDateString()获得公历日期字符串时,公历月已经修正;
* 使用getSimpleChineseDateString()获得农历日期字符串时,农历闰月以*表示。
*
* @version 0.12 2011-9-5
*
修复一个当使用农历正月日期初始化日历时陷入死循环的问题。
* @version 0.11 2009-12-27
*
修复了获取中文农历时未计算农历日期的问题;* 加入一个字段CHINESE_TERM_OR_DATE用于模仿台历的显示方式:如果当天有节气则指示节气,如果是初一指示农历月,
* 否则指示农历日。
* @version 0.10 2009-12-22
*/
public final class ChineseCalendar extends GregorianCalendar {
private static final long serialVersionUID = 8L;
/** 农历年 */
public static final int CHINESE_YEAR = 801;
/** 农历月 */
public static final int CHINESE_MONTH = 802;
/** 农历日 */
public static final int CHINESE_DATE = 803;
/** 当月的节气对应的公历日(前一个节气) */
public static final int CHINESE_SECTIONAL_TERM = 804;
/** 当月的中气对应的公历日(后一个节气) */
public static final int CHINESE_PRINCIPLE_TERM = 805;
/** 天干 */
public static final int CHINESE_HEAVENLY_STEM = 806;
/** 地支 */
public static final int CHINESE_EARTHLY_BRANCH = 807;
/** 农历年的属相(生肖) */
public static final int CHINESE_ZODIAC = 808;
/** 节气或者农历日 */
public static final int CHINESE_TERM_OR_DATE = 888;
// add by skywang
/** 农历节日 */
public static final int LUNAR_FESTIVAL = 809;
/** 阳历节日 */
public static final int SOLAR_FESTIVAL = 810;
/** 节气 */
public static final int CHINESE_TERM = 811;
/** 月或者农历日 */
public static final int CHINESE_MONTH_OR_DATE = 812;
/** 节日 或 节气 或 农历日 */
public static final int FESTIVAL_OR_TERM_OR_DATE = 813;
private int chineseYear;
private int chineseMonth; // 1起始,负数表示闰月
private int chineseDate;
private int sectionalTerm; // 当月节气的公历日
private int principleTerm; // 当月中气的公历日
private boolean areChineseFieldsComputed; // 农历日期是否已经经过计算确认
private boolean areSolarTermsComputed; // 节气是否已经经过计算确认
private boolean lastSetChinese; // 最后设置的是不是农历属性
/** 使用当前时间构造一个实例。 */
public ChineseCalendar() {
super();
}
/** 使用指定时间构造一个实例。 */
public ChineseCalendar(Date d) {
super.setTime(d);
}
/** 使用指定时间构造一个实例。 */
public ChineseCalendar(Calendar c) {
this(c.getTime());
}
/** 使用指定公历日期构造一个实例。 */
public ChineseCalendar(int y, int m, int d) {
super(y, m, d);
}
/**
* 使用指定日期构造一个实例。
*
* @param isChinese
* 是否为农历日期
* @param y
* @param m
* @param d
*/
public ChineseCalendar(boolean isChinese, int y, int m, int d) {
if (isChinese) {
set(CHINESE_YEAR, y);
set(CHINESE_MONTH, m);
set(CHINESE_DATE, d);
} else {
set(y, m, d);
}
}
public void set(int field, int value) {
computeIfNeed(field);
if (isChineseField(field)) {
// 农历属性
switch (field) {
case CHINESE_YEAR:
chineseYear = value;
break;
case CHINESE_MONTH:
chineseMonth = value;
break;
case CHINESE_DATE:
chineseDate = value;
break;
default:
throw new IllegalArgumentException("不支持的field设置:" + field);
}
lastSetChinese = true;
} else {
// 非农历属性
super.set(field, value);
lastSetChinese = false;
}
areFieldsSet = false;
areChineseFieldsComputed = false;
areSolarTermsComputed = false;
}
public int get(int field) {
computeIfNeed(field);
if (!isChineseField(field)) {
return super.get(field);
}
switch (field) {
case CHINESE_YEAR:
return chineseYear;
case CHINESE_MONTH:
return chineseMonth;
case CHINESE_DATE:
return chineseDate;
case CHINESE_SECTIONAL_TERM:
return sectionalTerm;
case CHINESE_PRINCIPLE_TERM:
return principleTerm;
case CHINESE_HEAVENLY_STEM:
return (chineseYear - 4) % 10 + 1;
case CHINESE_EARTHLY_BRANCH:
case CHINESE_ZODIAC:
return (chineseYear - 4) % 12 + 1;
case CHINESE_MONTH_OR_DATE:<