Android实现自定义日历
程序员文章站
2023-11-18 12:16:46
自定义日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写)
注:将下面的四张资源图片拷贝到所建包的下一个image目录中,如calendar.jav...
自定义日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写)
注:将下面的四张资源图片拷贝到所建包的下一个image目录中,如calendar.java 所在包为
cc.util.android.view,则需要再创建一个包cc.util.android.view.image 然后将图片拷贝进去
/****************从此出开始将代码拷贝到一个文件中*******************/ package cc.util.android.view; import java.text.parseexception; import java.text.simpledateformat; import java.util.arraylist; import java.util.calendar; import java.util.date; import java.util.list; import java.util.locale; import android.annotation.suppresslint; import android.content.context; import android.graphics.bitmapfactory; import android.graphics.color; import android.graphics.drawable.bitmapdrawable; import android.graphics.drawable.drawable; import android.graphics.drawable.statelistdrawable; import android.text.textutils.truncateat; import android.util.attributeset; import android.view.gesturedetector; import android.view.gesturedetector.ongesturelistener; import android.view.gravity; import android.view.motionevent; import android.view.view; import android.view.viewgroup; import android.view.view.ontouchlistener; import android.view.animation.animation; import android.view.animation.animation.animationlistener; import android.view.animation.translateanimation; import android.widget.baseadapter; import android.widget.gridview; import android.widget.imagebutton; import android.widget.linearlayout; import android.widget.relativelayout; import android.widget.textview; import android.widget.viewflipper; import android.widget.abslistview.layoutparams; /** * 日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写) * * @author wangcccong * @version 1.406 create at: mon, 03 sep. 2014 * <br>update at: mon, 23 sep. 2014 * 新增日期标注和点击操作 */ public class calendarview extends linearlayout implements ontouchlistener, animationlistener, ongesturelistener { /** * 点击日历 */ public interface oncalendarviewlistener { void oncalendaritemclick(calendarview view, date date); } /** 顶部控件所占高度 */ private final static int top_height = 40; /** 日历item中默认id从0xff0000开始 */ private final static int default_id = 0xff0000; // 判断手势用 private static final int swipe_min_distance = 120; private static final int swipe_max_off_path = 250; private static final int swipe_threshold_velocity = 200; // 屏幕宽度和高度 private int screenwidth; // 动画 private animation slideleftin; private animation slideleftout; private animation sliderightin; private animation sliderightout; private viewflipper viewflipper; private gesturedetector mgesture = null; /** 上一月 */ private gridview gview1; /** 当月 */ private gridview gview2; /** 下一月 */ private gridview gview3; boolean bisselection = false;// 是否是选择事件发生 private calendar calstartdate = calendar.getinstance();// 当前显示的日历 private calendar calselected = calendar.getinstance(); // 选择的日历 private calendargridviewadapter gadapter; private calendargridviewadapter gadapter1; private calendargridviewadapter gadapter3; private linearlayout mmainlayout; private textview mtitle; // 显示年月 private int imonthviewcurrentmonth = 0; // 当前视图月 private int imonthviewcurrentyear = 0; // 当前视图年 private static final int caltitlelayoutid = 66; // title布局id private static final int callayoutid = 55; // 日历布局id private context mcontext; /** 标注日期 */ private final list<date> markdates; private oncalendarviewlistener mlistener; public calendarview(context context) { this(context, null); } public calendarview(context context, attributeset attrs) { super(context, attrs); // todo auto-generated constructor stub mcontext = context; markdates = new arraylist<date>(); init(); } // 初始化相关工作 protected void init() { // 得到屏幕的宽度 screenwidth = mcontext.getresources().getdisplaymetrics().widthpixels; // 滑动的动画 slideleftin = new translateanimation(screenwidth, 0, 0, 0); slideleftin.setduration(400); slideleftin.setanimationlistener(this); slideleftout = new translateanimation(0, -screenwidth, 0, 0); slideleftout.setduration(400); slideleftout.setanimationlistener(this); sliderightin = new translateanimation(-screenwidth, 0, 0, 0); sliderightin.setduration(400); sliderightin.setanimationlistener(this); sliderightout = new translateanimation(0, screenwidth, 0, 0); sliderightout.setduration(400); sliderightout.setanimationlistener(this); // 手势操作 mgesture = new gesturedetector(mcontext, this); // 获取到当前日期 updatestartdateformonth(); // 绘制界面 setorientation(linearlayout.horizontal); mmainlayout = new linearlayout(mcontext); linearlayout.layoutparams main_params = new linearlayout.layoutparams( layoutparams.match_parent, layoutparams.wrap_content); mmainlayout.setlayoutparams(main_params); mmainlayout.setgravity(gravity.center_horizontal); mmainlayout.setorientation(linearlayout.vertical); addview(mmainlayout); // 顶部控件 generatetopview(); // 中间显示星期 generateweekgirdview(); // 底部显示日历 viewflipper = new viewflipper(mcontext); relativelayout.layoutparams fliper_params = new relativelayout.layoutparams( layoutparams.match_parent, layoutparams.wrap_content); fliper_params.addrule(relativelayout.below, caltitlelayoutid); mmainlayout.addview(viewflipper, fliper_params); generateclaendargirdview(); // 最下方的一条线条 linearlayout br = new linearlayout(mcontext); br.setbackgroundcolor(color.argb(0xff, 0xe3, 0xee, 0xf4)); linearlayout.layoutparams params_br = new linearlayout.layoutparams( layoutparams.match_parent, 3); mmainlayout.addview(br, params_br); } /** 生成顶部控件 */ @suppresswarnings("deprecation") private void generatetopview() { // 顶部显示上一个下一个,以及当前年月 relativelayout top = new relativelayout(mcontext); top.setbackgroundcolor(color.argb(0xff, 0x0e, 0x6b, 0xc2)); linearlayout.layoutparams top_params = new linearlayout.layoutparams( layoutparams.match_parent, viewutil.dip2px(mcontext, top_height)); top.setlayoutparams(top_params); mmainlayout.addview(top); // 左方按钮、中间日期显示、右方按钮 mtitle = new textview(mcontext); android.widget.relativelayout.layoutparams title_params = new android.widget.relativelayout.layoutparams( android.widget.relativelayout.layoutparams.match_parent, android.widget.relativelayout.layoutparams.match_parent); mtitle.setlayoutparams(title_params); mtitle.settextcolor(color.white); mtitle.settextsize(18); mtitle.setfocusableintouchmode(true); mtitle.setmarqueerepeatlimit(-1); mtitle.setellipsize(truncateat.marquee); mtitle.setsingleline(true); mtitle.setgravity(gravity.center); mtitle.sethorizontallyscrolling(true); mtitle.settext("2014年9月"); top.addview(mtitle); // 左方按钮 imagebutton mleftview = new imagebutton(mcontext); statelistdrawable statelistdrawablel = new statelistdrawable(); drawable ldrawablenor = new bitmapdrawable(mcontext.getresources(), bitmapfactory.decodestream(calendarview.class .getresourceasstream("image/left_arrow.png"))); drawable ldrawablepre = new bitmapdrawable(mcontext.getresources(), bitmapfactory.decodestream(calendarview.class .getresourceasstream("image/left_arrow_pre.png"))); statelistdrawablel.addstate( new int[] { -android.r.attr.state_pressed }, ldrawablenor); statelistdrawablel.addstate(new int[] { android.r.attr.state_pressed }, ldrawablepre); mleftview.setbackgrounddrawable(statelistdrawablel); android.widget.relativelayout.layoutparams leftpp = new android.widget.relativelayout.layoutparams( viewutil.dip2px(mcontext, 25), viewutil.dip2px(mcontext, 22)); leftpp.addrule(relativelayout.align_parent_left); leftpp.addrule(relativelayout.center_vertical, relativelayout.true); leftpp.setmargins(20, 0, 0, 0); mleftview.setlayoutparams(leftpp); mleftview.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub viewflipper.setinanimation(sliderightin); viewflipper.setoutanimation(sliderightout); viewflipper.showprevious(); setprevviewitem(); } }); top.addview(mleftview); // 右方按钮 imagebutton mrightview = new imagebutton(mcontext); statelistdrawable statelistdrawable = new statelistdrawable(); drawable rdrawablenor = new bitmapdrawable(mcontext.getresources(), bitmapfactory.decodestream(calendarview.class .getresourceasstream("image/right_arrow.png"))); drawable rdrawablepre = new bitmapdrawable(mcontext.getresources(), bitmapfactory.decodestream(calendarview.class .getresourceasstream("image/right_arrow_pre.png"))); statelistdrawable.addstate(new int[] { -android.r.attr.state_pressed }, rdrawablenor); statelistdrawable.addstate(new int[] { android.r.attr.state_pressed }, rdrawablepre); mrightview.setbackgrounddrawable(statelistdrawable); android.widget.relativelayout.layoutparams rightpp = new android.widget.relativelayout.layoutparams( viewutil.dip2px(mcontext, 25), viewutil.dip2px(mcontext, 22)); rightpp.addrule(relativelayout.align_parent_right); rightpp.addrule(relativelayout.center_vertical, relativelayout.true); rightpp.setmargins(0, 0, 20, 0); mrightview.setlayoutparams(rightpp); mrightview.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub viewflipper.setinanimation(slideleftin); viewflipper.setoutanimation(slideleftout); viewflipper.shownext(); setnextviewitem(); } }); top.addview(mrightview); } /** 生成中间显示week */ private void generateweekgirdview() { gridview gridview = new gridview(mcontext); linearlayout.layoutparams params = new linearlayout.layoutparams( layoutparams.match_parent, layoutparams.wrap_content); gridview.setlayoutparams(params); gridview.setnumcolumns(7);// 设置每行列数 gridview.setgravity(gravity.center_vertical);// 位置居中 gridview.setverticalspacing(1);// 垂直间隔 gridview.sethorizontalspacing(1);// 水平间隔 gridview.setbackgroundcolor(color.argb(0xff, 0xe3, 0xee, 0xf4)); int i = screenwidth / 7; int j = screenwidth - (i * 7); int x = j / 2; gridview.setpadding(x, 0, 0, 0);// 居中 weekgridadapter weekadapter = new weekgridadapter(mcontext); gridview.setadapter(weekadapter);// 设置菜单adapter mmainlayout.addview(gridview); } /** 生成底部日历 */ private void generateclaendargirdview() { calendar tempselected1 = calendar.getinstance(); // 临时 calendar tempselected2 = calendar.getinstance(); // 临时 calendar tempselected3 = calendar.getinstance(); // 临时 tempselected1.settime(calstartdate.gettime()); tempselected2.settime(calstartdate.gettime()); tempselected3.settime(calstartdate.gettime()); gview1 = new calendargridview(mcontext); tempselected1.add(calendar.month, -1); gadapter1 = new calendargridviewadapter(mcontext, tempselected1, markdates); gview1.setadapter(gadapter1);// 设置菜单adapter gview1.setid(callayoutid); gview2 = new calendargridview(mcontext); gadapter = new calendargridviewadapter(mcontext, tempselected2, markdates); gview2.setadapter(gadapter);// 设置菜单adapter gview2.setid(callayoutid); gview3 = new calendargridview(mcontext); tempselected3.add(calendar.month, 1); gadapter3 = new calendargridviewadapter(mcontext, tempselected3, markdates); gview3.setadapter(gadapter3);// 设置菜单adapter gview3.setid(callayoutid); gview2.setontouchlistener(this); gview1.setontouchlistener(this); gview3.setontouchlistener(this); if (viewflipper.getchildcount() != 0) { viewflipper.removeallviews(); } viewflipper.addview(gview2); viewflipper.addview(gview3); viewflipper.addview(gview1); string title = calstartdate.get(calendar.year) + "年" + numberhelper.leftpad_tow_zero(calstartdate .get(calendar.month) + 1) + "月"; mtitle.settext(title); } // 上一个月 private void setprevviewitem() { imonthviewcurrentmonth--;// 当前选择月-- // 如果当前月为负数的话显示上一年 if (imonthviewcurrentmonth == -1) { imonthviewcurrentmonth = 11; imonthviewcurrentyear--; } calstartdate.set(calendar.day_of_month, 1); // 设置日为当月1日 calstartdate.set(calendar.month, imonthviewcurrentmonth); // 设置月 calstartdate.set(calendar.year, imonthviewcurrentyear); // 设置年 } // 下一个月 private void setnextviewitem() { imonthviewcurrentmonth++; if (imonthviewcurrentmonth == 12) { imonthviewcurrentmonth = 0; imonthviewcurrentyear++; } calstartdate.set(calendar.day_of_month, 1); calstartdate.set(calendar.month, imonthviewcurrentmonth); calstartdate.set(calendar.year, imonthviewcurrentyear); } // 根据改变的日期更新日历 // 填充日历控件用 private void updatestartdateformonth() { calstartdate.set(calendar.date, 1); // 设置成当月第一天 imonthviewcurrentmonth = calstartdate.get(calendar.month);// 得到当前日历显示的月 imonthviewcurrentyear = calstartdate.get(calendar.year);// 得到当前日历显示的年 // 星期一是2 星期天是1 填充剩余天数 int iday = 0; int ifirstdayofweek = calendar.monday; int istartday = ifirstdayofweek; if (istartday == calendar.monday) { iday = calstartdate.get(calendar.day_of_week) - calendar.monday; if (iday < 0) iday = 6; } if (istartday == calendar.sunday) { iday = calstartdate.get(calendar.day_of_week) - calendar.sunday; if (iday < 0) iday = 6; } calstartdate.add(calendar.day_of_week, -iday); } /** * 设置标注的日期 * * @param markdates */ public void setmarkdates(list<date> markdates) { this.markdates.clear(); this.markdates.addall(markdates); gadapter.notifydatasetchanged(); gadapter1.notifydatasetchanged(); gadapter3.notifydatasetchanged(); } /** * 设置点击日历监听 * * @param listener */ public void setoncalendarviewlistener(oncalendarviewlistener listener) { this.mlistener = listener; } @override public boolean ondown(motionevent e) { // todo auto-generated method stub return false; } @suppresslint("clickableviewaccessibility") @override public boolean ontouch(view v, motionevent event) { return mgesture.ontouchevent(event); } @override public boolean onfling(motionevent e1, motionevent e2, float velocityx, float velocityy) { // todo auto-generated method stub try { if (math.abs(e1.gety() - e2.gety()) > swipe_max_off_path) return false; // right to left swipe if (e1.getx() - e2.getx() > swipe_min_distance && math.abs(velocityx) > swipe_threshold_velocity) { viewflipper.setinanimation(slideleftin); viewflipper.setoutanimation(slideleftout); viewflipper.shownext(); setnextviewitem(); return true; } else if (e2.getx() - e1.getx() > swipe_min_distance && math.abs(velocityx) > swipe_threshold_velocity) { viewflipper.setinanimation(sliderightin); viewflipper.setoutanimation(sliderightout); viewflipper.showprevious(); setprevviewitem(); return true; } } catch (exception e) { // nothing } return false; } @override public void onlongpress(motionevent e) { // todo auto-generated method stub } @override public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey) { // todo auto-generated method stub return false; } @override public void onshowpress(motionevent e) { // todo auto-generated method stub } @override public boolean onsingletapup(motionevent e) { // todo auto-generated method stub // 得到当前选中的是第几个单元格 int pos = gview2.pointtoposition((int) e.getx(), (int) e.gety()); linearlayout txtday = (linearlayout) gview2.findviewbyid(pos + default_id); if (txtday != null) { if (txtday.gettag() != null) { date date = (date) txtday.gettag(); calselected.settime(date); gadapter.setselecteddate(calselected); gadapter.notifydatasetchanged(); gadapter1.setselecteddate(calselected); gadapter1.notifydatasetchanged(); gadapter3.setselecteddate(calselected); gadapter3.notifydatasetchanged(); if (mlistener != null) mlistener.oncalendaritemclick(this, date); } } return false; } @override public void onanimationend(animation animation) { // todo auto-generated method stub generateclaendargirdview(); } @override public void onanimationrepeat(animation animation) { // todo auto-generated method stub } @override public void onanimationstart(animation animation) { // todo auto-generated method stub } } /** * 显示week的布局adapter * */ class weekgridadapter extends baseadapter { final string[] titles = new string[] { "日", "一", "二", "三", "四", "五", "六" }; private context mcontext; public weekgridadapter(context context) { this.mcontext = context; } @override public int getcount() { return titles.length; } @override public object getitem(int position) { return titles[position]; } @override public long getitemid(int position) { return position; } @override public view getview(int position, view convertview, viewgroup parent) { textview week = new textview(mcontext); android.view.viewgroup.layoutparams week_params = new layoutparams( android.view.viewgroup.layoutparams.match_parent, android.view.viewgroup.layoutparams.match_parent); week.setlayoutparams(week_params); week.setpadding(0, 0, 0, 0); week.setgravity(gravity.center); week.setfocusable(false); week.setbackgroundcolor(color.transparent); if (position == 6) { // 周六 week.setbackgroundcolor(color.argb(0xff, 0x52, 0x9b, 0xd0)); week.settextcolor(color.white); } else if (position == 0) { // 周日 week.setbackgroundcolor(color.argb(0xff, 0xbc, 0x44, 0x45)); week.settextcolor(color.white); } else { week.settextcolor(color.black); } week.settext(getitem(position) + ""); return week; } } /** * 显示日期的adapter */ class calendargridviewadapter extends baseadapter { /** 日历item中默认id从0xff0000开始 */ private final static int default_id = 0xff0000; private calendar calstartdate = calendar.getinstance();// 当前显示的日历 private calendar calselected = calendar.getinstance(); // 选择的日历 /** 标注的日期 */ private list<date> markdates; private context mcontext; private calendar caltoday = calendar.getinstance(); // 今日 private arraylist<java.util.date> titles; private arraylist<java.util.date> getdates() { updatestartdateformonth(); arraylist<java.util.date> alarraylist = new arraylist<java.util.date>(); for (int i = 1; i <= 42; i++) { alarraylist.add(calstartdate.gettime()); calstartdate.add(calendar.day_of_month, 1); } return alarraylist; } // construct public calendargridviewadapter(context context, calendar cal, list<date> dates) { calstartdate = cal; this.mcontext = context; titles = getdates(); this.markdates = dates; } public calendargridviewadapter(context context) { this.mcontext = context; } @override public int getcount() { return titles.size(); } @override public object getitem(int position) { return titles.get(position); } @override public long getitemid(int position) { return position; } @suppresswarnings("deprecation") @override public view getview(int position, view convertview, viewgroup parent) { // 整个item linearlayout itemlayout = new linearlayout(mcontext); itemlayout.setid(position + default_id); itemlayout.setgravity(gravity.center); itemlayout.setorientation(1); itemlayout.setbackgroundcolor(color.white); date mydate = (date) getitem(position); itemlayout.settag(mydate); calendar calcalendar = calendar.getinstance(); calcalendar.settime(mydate); // 显示日期day textview textday = new textview(mcontext);// 日期 linearlayout.layoutparams text_params = new linearlayout.layoutparams( layoutparams.match_parent, layoutparams.wrap_content); textday.setgravity(gravity.center_horizontal); int day = mydate.getdate(); // 日期 textday.settext(string.valueof(day)); textday.setid(position + default_id); itemlayout.addview(textday, text_params); // 显示公历 textview chineseday = new textview(mcontext); linearlayout.layoutparams chinese_params = new linearlayout.layoutparams( layoutparams.match_parent, layoutparams.wrap_content); chineseday.setgravity(gravity.center_horizontal); chineseday.settextsize(9); calendarutil calendarutil = new calendarutil(calcalendar); chineseday.settext(calendarutil.tostring()); itemlayout.addview(chineseday, chinese_params); // 如果是当前日期则显示不同颜色 if (equalsdate(caltoday.gettime(), mydate)) { itemlayout.setbackgroundcolor(color.argb(0xff, 0x6d, 0xd6, 0x97)); } // 这里用于比对是不是比当前日期小,如果比当前日期小则显示浅灰色 if (!calendarutil.compare(mydate, caltoday.gettime())) { itemlayout.setbackgroundcolor(color.argb(0xff, 0xee, 0xee, 0xee)); textday.settextcolor(color.argb(0xff, 0xc0, 0xc0, 0xc0)); chineseday.settextcolor(color.argb(0xff, 0xc0, 0xc0, 0xc0)); } else { chineseday.settextcolor(color.argb(0xff, 0xc2, 0xa5, 0x3d)); chineseday.settextcolor(color.argb(0xff, 0x60, 0x3b, 0x07)); // 设置背景颜色 if (equalsdate(calselected.gettime(), mydate)) { // 选择的 itemlayout.setbackgroundcolor(color.argb(0xff, 0xdc, 0xe2, 0xff)); } else { if (equalsdate(caltoday.gettime(), mydate)) { // 当前日期faedda itemlayout.setbackgroundcolor(color.argb(0xff, 0xfa, 0xed, 0xda)); } } } /** 设置标注日期颜色 */ if (markdates != null) { final simpledateformat format = new simpledateformat("yyyy-mm-dd", locale.china); for (date date : markdates) { if (format.format(mydate).equals(format.format(date))) { itemlayout.setbackgroundcolor(color.argb(0xff, 0xd3, 0x3a, 0x3a)); break; } } } return itemlayout; } @override public void notifydatasetchanged() { super.notifydatasetchanged(); } @suppresswarnings("deprecation") private boolean equalsdate(date date1, date date2) { if (date1.getyear() == date2.getyear() && date1.getmonth() == date2.getmonth() && date1.getdate() == date2.getdate()) { return true; } else { return false; } } // 根据改变的日期更新日历 // 填充日历控件用 private void updatestartdateformonth() { calstartdate.set(calendar.date, 1); // 设置成当月第一天 // 星期一是2 星期天是1 填充剩余天数 int iday = 0; int ifirstdayofweek = calendar.monday; int istartday = ifirstdayofweek; if (istartday == calendar.monday) { iday = calstartdate.get(calendar.day_of_week) - calendar.monday; if (iday < 0) iday = 6; } if (istartday == calendar.sunday) { iday = calstartdate.get(calendar.day_of_week) - calendar.sunday; if (iday < 0) iday = 6; } calstartdate.add(calendar.day_of_week, -iday); calstartdate.add(calendar.day_of_month, -1);// 周日第一位 } public void setselecteddate(calendar cal) { calselected = cal; } } /** * 用于生成日历展示的gridview布局 */ class calendargridview extends gridview { /** * 当前操作的上下文对象 */ private context mcontext; /** * calendargridview 构造器 * * @param context * 当前操作的上下文对象 */ public calendargridview(context context) { super(context); mcontext = context; initgirdview(); } /** * 初始化gridview 控件的布局 */ private void initgirdview() { linearlayout.layoutparams params = new linearlayout.layoutparams( layoutparams.match_parent, layoutparams.wrap_content); setlayoutparams(params); setnumcolumns(7);// 设置每行列数 setgravity(gravity.center_vertical);// 位置居中 setverticalspacing(1);// 垂直间隔 sethorizontalspacing(1);// 水平间隔 setbackgroundcolor(color.argb(0xff, 0xe3, 0xee, 0xf4)); int i = mcontext.getresources().getdisplaymetrics().widthpixels / 7; int j = mcontext.getresources().getdisplaymetrics().widthpixels - (i * 7); int x = j / 2; setpadding(x, 0, 0, 0);// 居中 } } /** * 把公历时间处理成农历时间 * */ class calendarutil { /** * 用于保存中文的月份 */ private final static string chinese_number[] = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" }; /** * 用于保存展示周几使用 */ private final static string week_number[] = { "日", "一", "二", "三", "四", "五", "六" }; private final static long[] lunar_info = new long[] { 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 }; /** * 转换为2012年11月22日格式 */ private static simpledateformat chinesedateformat = new simpledateformat( "yyyy年mm月dd日"); /** * 转换为2012-11-22格式 */ private static simpledateformat simpledateformat = new simpledateformat( "yyyy-mm-dd"); /** * 计算得到农历的年份 */ private int mluchyear; /** * 计算得到农历的月份 */ private int mluchmonth; /** * 计算得到农历的日期 */ private int mluchday; /** * 用于标识是事为闰年 */ private boolean isloap; /** * 用于记录当前处理的时间 */ private calendar mcurrencalendar; /** * 传回农历 year年的总天数 * * @param year * 将要计算的年份 * @return 返回传入年份的总天数 */ private static int yeardays(int year) { int i, sum = 348; for (i = 0x8000; i > 0x8; i >>= 1) { if ((lunar_info[year - 1900] & i) != 0) sum += 1; } return (sum + leapdays(year)); } /** * 传回农历 year年闰月的天数 * * @param year * 将要计算的年份 * @return 返回 农历 year年闰月的天数 */ private static int leapdays(int year) { if (leapmonth(year) != 0) { if ((lunar_info[year - 1900] & 0x10000) != 0) return 30; else return 29; } else return 0; } /** * 传回农历 year年闰哪个月 1-12 , 没闰传回 0 * * @param year * 将要计算的年份 * @return 传回农历 year年闰哪个月 1-12 , 没闰传回 0 */ private static int leapmonth(int year) { return (int) (lunar_info[year - 1900] & 0xf); } /** * 传回农历 year年month月的总天数 * * @param year * 将要计算的年份 * @param month * 将要计算的月份 * @return 传回农历 year年month月的总天数 */ private static int monthdays(int year, int month) { if ((lunar_info[year - 1900] & (0x10000 >> month)) == 0) return 29; else return 30; } /** * 传回农历 y年的生肖 * * @return 传回农历 y年的生肖 */ public string animalsyear() { final string[] animals = new string[] { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; return animals[(mluchyear - 4) % 12]; } // ====== 传入 月日的offset 传回干支, 0=甲子 private static string cyclicalm(int num) { final string[] gan = new string[] { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }; final string[] zhi = new string[] { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }; return (gan[num % 10] + zhi[num % 12]); } // ====== 传入 offset 传回干支, 0=甲子 public string cyclical() { int num = mluchyear - 1900 + 36; return (cyclicalm(num)); } /** * 传出y年m月d日对应的农历. yearcyl3:农历年与1864的相差数 ? moncyl4:从1900年1月31日以来,闰月数 * daycyl5:与1900年1月31日相差的天数,再加40 ? * * @param cal * @return */ public calendarutil(calendar cal) { mcurrencalendar = cal; int leapmonth = 0; date basedate = null; try { basedate = chinesedateformat.parse("1900年1月31日"); } catch (parseexception e) { e.printstacktrace(); // to change body of catch statement use // options | file templates. } // 求出和1900年1月31日相差的天数 int offset = (int) ((cal.gettime().gettime() - basedate.gettime()) / 86400000l); // 用offset减去每农历年的天数 // 计算当天是农历第几天 // i最终结果是农历的年份 // offset是当年的第几天 int iyear, daysofyear = 0; for (iyear = 1900; iyear < 2050 && offset > 0; iyear++) { daysofyear = yeardays(iyear); offset -= daysofyear; } if (offset < 0) { offset += daysofyear; iyear--; } // 农历年份 mluchyear = iyear; leapmonth = leapmonth(iyear); // 闰哪个月,1-12 isloap = false; // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天 int imonth, daysofmonth = 0; for (imonth = 1; imonth < 13 && offset > 0; imonth++) { // 闰月 if (leapmonth > 0 && imonth == (leapmonth + 1) && !isloap) { --imonth; isloap = true; daysofmonth = leapdays(mluchyear); } else daysofmonth = monthdays(mluchyear, imonth); offset -= daysofmonth; // 解除闰月 if (isloap && imonth == (leapmonth + 1)) isloap = false; if (!isloap) { } } // offset为0时,并且刚才计算的月份是闰月,要校正 if (offset == 0 && leapmonth > 0 && imonth == leapmonth + 1) { if (isloap) { isloap = false; } else { isloap = true; --imonth; } } // offset小于0时,也要校正 if (offset < 0) { offset += daysofmonth; --imonth; } mluchmonth = imonth; mluchday = offset + 1; } /** * 返化成中文格式 * * @param day * @return */ public static string getchinadaystring(int day) { string chineseten[] = { "初", "十", "廿", "卅" }; int n = day % 10 == 0 ? 9 : day % 10 - 1; if (day > 30) return ""; if (day == 10) return "初十"; else return chineseten[day / 10] + chinese_number[n]; } /** * 用于显示农历的初几这种格式 * * @return 农历的日期 */ public string tostring() { string message = ""; // int n = mluchday % 10 == 0 ? 9 : mluchday % 10 - 1; message = getchinacalendarmsg(mluchyear, mluchmonth, mluchday); if (stringutil.isnullorempty(message)) { string solarmsg = new solartermsutil(mcurrencalendar) .getsolartermsmsg(); // 判断当前日期是否为节气 if (!stringutil.isnullorempty(solarmsg)) { message = solarmsg; } else { /** * 判断当前日期是否为公历节日 */ string gremessage = new gregorianutil(mcurrencalendar) .getgremessage(); if (!stringutil.isnullorempty(gremessage)) { message = gremessage; } else if (mluchday == 1) { message = chinese_number[mluchmonth - 1] + "月"; } else { message = getchinadaystring(mluchday); } } } return message; } /** * 返回农历的年月日 * * @return 农历的年月日格式 */ public string getday() { return (isloap ? "闰" : "") + chinese_number[mluchmonth - 1] + "月" + getchinadaystring(mluchday); } /** * 把calendar转化为当前年月日 * * @param calendar * calendar * @return 返回成转换好的 年月日格式 */ public static string getday(calendar calendar) { return simpledateformat.format(calendar.gettime()); } /** * 用于比对二个日期的大小 * * @param comparedate * 将要比对的时间 * @param currentdate * 当前时间 * @return true 表示大于当前时间 false 表示小于当前时间 */ public static boolean compare(date comparedate, date currentdate) { return chinesedateformat.format(comparedate).compareto( chinesedateformat.format(currentdate)) >= 0; } /** * 获取当前周几 * * @param calendar * @return */ public static string getweek(calendar calendar) { return "周" + week_number[calendar.get(calendar.day_of_week) - 1] + ""; } /** * 将当前时间转换成要展示的形式 * * @param calendar * @return */ public static string getcurrentday(calendar calendar) { return getday(calendar) + " 农历" + new calendarutil(calendar).getday() + " " + getweek(calendar); } /** * 用于获取中国的传统节日 * * @param month * 农历的月 * @param day * 农历日 * @return 中国传统节日 */ private string getchinacalendarmsg(int year, int month, int day) { string message = ""; if (((month) == 1) && day == 1) { message = "春节"; } else if (((month) == 1) && day == 15) { message = "元宵"; } else if (((month) == 5) && day == 5) { message = "端午"; } else if ((month == 7) && day == 7) { message = "七夕"; } else if (((month) == 8) && day == 15) { message = "中秋"; } else if ((month == 9) && day == 9) { message = "重阳"; } else if ((month == 12) && day == 8) { message = "腊八"; } else { if (month == 12) { if ((((monthdays(year, month) == 29) && day == 29)) || ((((monthdays(year, month) == 30) && day == 30)))) { message = "除夕"; } } } return message; } } /** * 字符串的处理类 */ class stringutil { /** * 判断是否为null或空值 * * @param str * string * @return true or false */ public static boolean isnullorempty(string str) { return str == null || str.trim().length() == 0; } /** * 判断str1和str2是否相同 * * @param str1 * str1 * @param str2 * str2 * @return true or false */ public static boolean equals(string str1, string str2) { return str1 == str2 || str1 != null && str1.equals(str2); } /** * 判断str1和str2是否相同(不区分大小写) * * @param str1 * str1 * @param str2 * str2 * @return true or false */ public static boolean equalsignorecase(string str1, string str2) { return str1 != null && str1.equalsignorecase(str2); } /** * 判断字符串str1是否包含字符串str2 * * @param str1 * 源字符串 * @param str2 * 指定字符串 * @return true源字符串包含指定字符串,false源字符串不包含指定字符串 */ public static boolean contains(string str1, string str2) { return str1 != null && str1.contains(str2); } /** * 判断字符串是否为空,为空则返回一个空值,不为空则返回原字符串 * * @param str * 待判断字符串 * @return 判断后的字符串 */ public static string getstring(string str) { return str == null ? "" : str; } } /** * 主要用于把公历日期处理成24节气 */ class solartermsutil { /** * 计算得到公历的年份 */ private int gregorianyear; /** * 计算得到公历的月份 */ private int gregorianmonth; /** * 用于计算得到公历的日期 */ private int gregoriandate; private int chineseyear; private int chinesemonth; private int chinesedate; // 初始日,公历农历对应日期: // 公历 1901 年 1 月 1 日,对应农历 4598 年 11 月 11 日 private static int baseyear = 1901; private static int basemonth = 1; private static int basedate = 1; private static int baseindex = 0; private static int basechineseyear = 4598 - 1; private static int basechinesemonth = 11; private static int basechinesedate = 11; private static char[] daysingregorianmonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; private int sectionalterm; private int principleterm; private static char[][] sectionaltermmap = { { 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5 }, { 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3, 3, 4, 4, 3, 3, 3 }, { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 }, { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 5, 4, 4, 4, 4, 5 }, { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 }, { 6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 }, { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 6, 6, 6, 7, 7 }, { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7 }, { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 7 }, { 9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 8 }, { 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7 }, { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 6, 6, 6, 7, 7 } }; private static char[][] sectionaltermyear = { { 13, 49, 85, 117, 149, 185, 201, 250, 250 }, { 13, 45, 81, 117, 149, 185, 201, 250, 250 }, { 13, 48, 84, 112, 148, 184, 200, 201, 250 }, { 13, 45, 76, 108, 140, 172, 200, 201, 250 }, { 13, 44, 72, 104, 132, 168, 200, 201, 250 }, { 5, 33, 68, 96, 124, 152, 188, 200, 201 }, { 29, 57, 85, 120, 148, 176, 200, 201, 250 }, { 13, 48, 76, 104, 132, 168, 196, 200, 201 }, { 25, 60, 88, 120, 148, 184, 200, 201, 250 }, { 16, 44, 76, 108, 144, 172, 200, 201, 250 }, { 28, 60, 92, 124, 160, 192, 200, 201, 250 }, { 17, 53, 85, 124, 156, 188, 200, 201, 250 } }; private static char[][] principletermmap = { { 21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20 }, { 20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19, 19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18 }, { 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20 }, { 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20 }, { 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21 }, { 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21 }, { 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23 }, { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 }, { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 }, { 24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23 }, { 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22 }, { 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22 } }; private static char[][] principletermyear = { { 13, 45, 81, 113, 149, 185, 201 }, { 21, 57, 93, 125, 161, 193, 201 }, { 21, 56, 88, 120, 152, 188, 200, 201 }, { 21, 49, 81, 116, 144, 176, 200, 201 }, { 17, 49, 77, 112, 140, 168, 200, 201 }, { 28, 60, 88, 116, 148, 180, 200, 201 }, { 25, 53, 84, 112, 144, 172, 200, 201 }, { 29, 57, 89, 120, 148, 180, 200, 201 }, { 17, 45, 73, 108, 140, 168, 200, 201 }, { 28, 60, 92, 124, 160, 192, 200, 201 }, { 16, 44, 80, 112, 148, 180, 200, 201 }, { 17, 53, 88, 120, 156, 188, 200, 201 } }; private static char[] chinesemonths = { // 农历月份大小压缩表,两个字节表示一年。两个字节共十六个二进制位数, // 前四个位数表示闰月月份,后十二个位数表示十二个农历月份的大小。 0x00, 0x04, 0xad, 0x08, 0x5a, 0x01, 0xd5, 0x54, 0xb4, 0x09, 0x64, 0x05, 0x59, 0x45, 0x95, 0x0a, 0xa6, 0x04, 0x55, 0x24, 0xad, 0x08, 0x5a, 0x62, 0xda, 0x04, 0xb4, 0x05, 0xb4, 0x55, 0x52, 0x0d, 0x94, 0x0a, 0x4a, 0x2a, 0x56, 0x02, 0x6d, 0x71, 0x6d, 0x01, 0xda, 0x02, 0xd2, 0x52, 0xa9, 0x05, 0x49, 0x0d, 0x2a, 0x45, 0x2b, 0x09, 0x56, 0x01, 0xb5, 0x20, 0x6d, 0x01, 0x59, 0x69, 0xd4, 0x0a, 0xa8, 0x05, 0xa9, 0x56, 0xa5, 0x04, 0x2b, 0x09, 0x9e, 0x38, 0xb6, 0x08, 0xec, 0x74, 0x6c, 0x05, 0xd4, 0x0a, 0xe4, 0x6a, 0x52, 0x05, 0x95, 0x0a, 0x5a, 0x42, 0x5b, 0x04, 0xb6, 0x04, 0xb4, 0x22, 0x6a, 0x05, 0x52, 0x75, 0xc9, 0x0a, 0x52, 0x05, 0x35, 0x55, 0x4d, 0x0a, 0x5a, 0x02, 0x5d, 0x31, 0xb5, 0x02, 0x6a, 0x8a, 0x68, 0x05, 0xa9, 0x0a, 0x8a, 0x6a, 0x2a, 0x05, 0x2d, 0x09, 0xaa, 0x48, 0x5a, 0x01, 0xb5, 0x09, 0xb0, 0x39, 0x64, 0x05, 0x25, 0x75, 0x95, 0x0a, 0x96, 0x04, 0x4d, 0x54, 0xad, 0x04, 0xda, 0x04, 0xd4, 0x44, 0xb4, 0x05, 0x54, 0x85, 0x52, 0x0d, 0x92, 0x0a, 0x56, 0x6a, 0x56, 0x02, 0x6d, 0x02, 0x6a, 0x41, 0xda, 0x02, 0xb2, 0xa1, 0xa9, 0x05, 0x49, 0x0d, 0x0a, 0x6d, 0x2a, 0x09, 0x56, 0x01, 0xad, 0x50, 0x6d, 0x01, 0xd9, 0x02, 0xd1, 0x3a, 0xa8, 0x05, 0x29, 0x85, 0xa5, 0x0c, 0x2a, 0x09, 0x96, 0x54, 0xb6, 0x08, 0x6c, 0x09, 0x64, 0x45, 0xd4, 0x0a, 0xa4, 0x05, 0x51, 0x25, 0x95, 0x0a, 0x2a, 0x72, 0x5b, 0x04, 0xb6, 0x04, 0xac, 0x52, 0x6a, 0x05, 0xd2, 0x0a, 0xa2, 0x4a, 0x4a, 0x05, 0x55, 0x94, 0x2d, 0x0a, 0x5a, 0x02, 0x75, 0x61, 0xb5, 0x02, 0x6a, 0x03, 0x61, 0x45, 0xa9, 0x0a, 0x4a, 0x05, 0x25, 0x25, 0x2d, 0x09, 0x9a, 0x68, 0xda, 0x08, 0xb4, 0x09, 0xa8, 0x59, 0x54, 0x03, 0xa5, 0x0a, 0x91, 0x3a, 0x96, 0x04, 0xad, 0xb0, 0xad, 0x04, 0xda, 0x04, 0xf4, 0x62, 0xb4, 0x05, 0x54, 0x0b, 0x44, 0x5d, 0x52, 0x0a, 0x95, 0x04, 0x55, 0x22, 0x6d, 0x02, 0x5a, 0x71, 0xda, 0x02, 0xaa, 0x05, 0xb2, 0x55, 0x49, 0x0b, 0x4a, 0x0a, 0x2d, 0x39, 0x36, 0x01, 0x6d, 0x80, 0x6d, 0x01, 0xd9, 0x02, 0xe9, 0x6a, 0xa8, 0x05, 0x29, 0x0b, 0x9a, 0x4c, 0xaa, 0x08, 0xb6, 0x08, 0xb4, 0x38, 0x6c, 0x09, 0x54, 0x75, 0xd4, 0x0a, 0xa4, 0x05, 0x45, 0x55, 0x95, 0x0a, 0x9a, 0x04, 0x55, 0x44, 0xb5, 0x04, 0x6a, 0x82, 0x6a, 0x05, 0xd2, 0x0a, 0x92, 0x6a, 0x4a, 0x05, 0x55, 0x0a, 0x2a, 0x4a, 0x5a, 0x02, 0xb5, 0x02, 0xb2, 0x31, 0x69, 0x03, 0x31, 0x73, 0xa9, 0x0a, 0x4a, 0x05, 0x2d, 0x55, 0x2d, 0x09, 0x5a, 0x01, 0xd5, 0x48, 0xb4, 0x09, 0x68, 0x89, 0x54, 0x0b, 0xa4, 0x0a, 0xa5, 0x6a, 0x95, 0x04, 0xad, 0x08, 0x6a, 0x44, 0xda, 0x04, 0x74, 0x05, 0xb0, 0x25, 0x54, 0x03 }; /** * 用于保存24节气 */ private static string[] principletermnames = { "大寒", "雨水", "春分", "谷雨", "小满", "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至" }; /** * 用于保存24节气 */ private static string[] sectionaltermnames = { "小寒", "立春", "惊蛰", "清明", "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪" }; public solartermsutil(calendar calendar) { gregorianyear = calendar.get(calendar.year); gregorianmonth = calendar.get(calendar.month) + 1; gregoriandate = calendar.get(calendar.date); computechinesefields(); computesolarterms(); } public int computechinesefields() { if (gregorianyear < 1901 || gregorianyear > 2100) return 1; int startyear = baseyear; int startmonth = basemonth; int startdate = basedate; chineseyear = basechineseyear; chinesemonth = basechinesemonth; chinesedate = basechinesedate; // 第二个对应日,用以提高计算效率 // 公历 2000 年 1 月 1 日,对应农历 4697 年 11 月 25 日 if (gregorianyear >= 2000) { startyear = baseyear + 99; startmonth = 1; startdate = 1; chineseyear = basechineseyear + 99; chinesemonth = 11; chinesedate = 25; } int daysdiff = 0; for (int i = startyear; i < gregorianyear; i++) { daysdiff += 365; if (isgregorianleapyear(i)) daysdiff += 1; // leap year } for (int i = startmonth; i < gregorianmonth; i++) { daysdiff += daysingregorianmonth(gregorianyear, i); } daysdiff += gregoriandate - startdate; chinesedate += daysdiff; int lastdate = daysinchinesemonth(chineseyear, chinesemonth); int nextmonth = nextchinesemonth(chineseyear, chinesemonth); while (chinesedate > lastdate) { if (math.abs(nextmonth) < math.abs(chinesemonth)) chineseyear++; chinesemonth = nextmonth; chinesedate -= lastdate; lastdate = daysinchinesemonth(chineseyear, chinesemonth); nextmonth = nextchinesemonth(chineseyear, chinesemonth); } return 0; } public int computesolarterms() { if (gregorianyear < 1901 || gregorianyear > 2100) return 1; sectionalterm = sectionalterm(gregorianyear, gregorianmonth); principleterm = principleterm(gregorianyear, gregorianmonth); return 0; } public static int sectionalterm(int y, int m) { if (y < 1901 || y > 2100) return 0; int index = 0; int ry = y - baseyear + 1; while (ry >= sectionaltermyear[m - 1][index]) index++; int term = sectionaltermmap[m - 1][4 * index + ry % 4]; if ((ry == 121) && (m == 4)) term = 5; if ((ry == 132) && (m == 4)) term = 5; if ((ry == 194) && (m == 6)) term = 6; return term; } public static int principleterm(int y, int m) { if (y < 1901 || y > 2100) return 0; int index = 0; int ry = y - baseyear + 1; while (ry >= principletermyear[m - 1][index]) index++; int term = principletermmap[m - 1][4 * index + ry % 4]; if ((ry == 171) && (m == 3)) term = 21; if ((ry == 181) && (m == 5)) term = 21; return term; } /** * 用于判断输入的年份是否为闰年 * * @param year * 输入的年份 * @return true 表示闰年 */ public static boolean isgregorianleapyear(int year) { boolean isleap = false; if (year % 4 == 0) isleap = true; if (year % 100 == 0) isleap = false; if (year % 400 == 0) isleap = true; return isleap; } public static int daysingregorianmonth(int y, int m) { int d = daysingregorianmonth[m - 1]; if (m == 2 && isgregorianleapyear(y)) d++; // 公历闰年二月多一天 return d; } public static int daysinchinesemonth(int y, int m) { // 注意:闰月 m < 0 int index = y - basechineseyear + baseindex; int v = 0; int l = 0; int d = 30; if (1 <= m && m <= 8) { v = chinesemonths[2 * index]; l = m - 1; if (((v >> l) & 0x01) == 1) d = 29; } else if (9 <= m && m <= 12) { v = chinesemonths[2 * index + 1]; l = m - 9; if (((v >> l) & 0x01) == 1) d = 29; } else { v = chinesemonths[2 * index + 1]; v = (v >> 4) & 0x0f; if (v != math.abs(m)) { d = 0; } else { d = 29; for (int i = 0; i < bigleapmonthyears.length; i++) { if (bigleapmonthyears[i] == index) { d = 30; break; } } } } return d; } public static int nextchinesemonth(int y, int m) { int n = math.abs(m) + 1; if (m > 0) { int index = y - basechineseyear + baseindex; int v = chinesemonths[2 * index + 1]; v = (v >> 4) & 0x0f; if (v == m) n = -m; } if (n == 13) n = 1; return n; } // 大闰月的闰年年份 private static int[] bigleapmonthyears = { 6, 14, 19, 25, 33, 36, 38, 41, 44, 52, 55, 79, 117, 136, 147, 150, 155, 158, 185, 193 }; /** * 用于获取24节气的值 * * @return 24节气的值 */ public string getsolartermsmsg() { string str = ""; string gm = string.valueof(gregorianmonth); if (gm.length() == 1) gm = ' ' + gm; string cm = string.valueof(math.abs(chinesemonth)); if (cm.length() == 1) cm = ' ' + cm; string gd = string.valueof(gregoriandate); if (gd.length() == 1) gd = ' ' + gd; string cd = string.valueof(chinesedate); if (cd.length() == 1) cd = ' ' + cd; if (gregoriandate == sectionalterm) { str = " " + sectionaltermnames[gregorianmonth - 1]; } else if (gregoriandate == principleterm) { str = " " + principletermnames[gregorianmonth - 1]; } return str; } } /** * 对公历日期的处理类 */ class gregorianutil { private final static string[][] gre_festvial = { // 一月 { "元旦", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 二月 { "", "", "", "", "", "", "", "", "", "", "", "", "", "情人", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 三月 { "", "", "", "", "", "", "", "妇女", "", "", "", "植树", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 四月 { "愚人", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 五月 { "劳动", "", "", "青年", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 六月 { "儿童", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 七月 { "建党", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 八月 { "建军", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 九月 { "", "", "", "", "", "", "", "", "", "教师", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 十月 { "国庆", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 十一月 { "", "", "", "", "", "", "", "", "", "", "光棍", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, // 十二月 { "艾滋病", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "圣诞", "", "", "", "", "", "" }, }; private int mmonth; private int mday; public gregorianutil(calendar calendar) { mmonth = calendar.get(calendar.month); mday = calendar.get(calendar.date); } public string getgremessage() { return gre_festvial[mmonth][mday - 1]; } } class numberhelper { public static string leftpad_tow_zero(int str) { java.text.decimalformat format = new java.text.decimalformat("00"); return format.format(str); } } /*****************将代码拷贝到一个文件中(end)***********************/ //辅助类 package cc.util.android.view; import android.content.context; import android.content.res.resources; import android.view.view; import android.view.viewgroup; import android.view.viewgroup.marginlayoutparams; import android.widget.abslistview; import android.widget.gridview; import android.widget.listadapter; import android.widget.listview; /** * @author wangcccong * @version 1.140122 * create at:2014-02-26 */ public class viewutil { /** * 获取屏幕的宽度 * @param context * @return */ public int getscreenwidth(context context) { resources res = context.getresources(); return res.getdisplaymetrics().widthpixels; } /** * 获取屏幕高度 * @param context * @return */ public int getscreenheight(context context) { resources res = context.getresources(); return res.getdisplaymetrics().heightpixels; } /** * 描述:根据分辨率获得字体大小. * * @param screenwidth the screen width * @param screenheight the screen height * @param textsize the text size * @return the int */ public static int resizetextsize(int screenwidth,int screenheight,int textsize){ float ratio = 1; try { float ratiowidth = (float)screenwidth / 480; float ratioheight = (float)screenheight / 800; ratio = math.min(ratiowidth, ratioheight); } catch (exception e) { } return math.round(textsize * ratio); } /** * * 描述:dip转换为px * @param context * @param dipvalue * @return * @throws */ public static int dip2px(context context, float dipvalue) { final float scale = context.getresources().getdisplaymetrics().density; return math.round(dipvalue * scale); } /** * * 描述:px转换为dip * @param context * @param pxvalue * @return * @throws */ public static int px2dip(context context, float pxvalue) { final float scale = context.getresources().getdisplaymetrics().density; return math.round(pxvalue / scale); } /** * * 描述:px转换为sp * @param context * @param pxvalue * @return * @throws */ public static int px2sp(context context, float pxvalue) { final float scale = context.getresources().getdisplaymetrics().scaleddensity; return math.round(pxvalue / scale); } /** * * 描述:sp转换为px * @param context * @param spvalue * @return * @throws */ public static int sp2px(context context, float spvalue) { final float scale = context.getresources().getdisplaymetrics().scaleddensity; return math.round(spvalue * scale); } } //使用方法 //在xml中添加控件 <cc.util.android.view.calendarview android:id="@+id/calendar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white"/> //在代码中 calendarview calendarview = (calendarview) findviewbyid(r.id.calendar); //设置标注日期 list<date> markdates = new arraylist<date>(); markdates.add(new date()); calendarview.setmarkdates(markdates); //设置点击操作 calendarview.setoncalendarviewlistener(new oncalendarviewlistener() { @override public void oncalendaritemclick(calendarview view, date date) { // todo auto-generated method stub final simpledateformat format = new simpledateformat("yyyy年mm月dd日", locale.china); toast.maketext(mainactivity.this, format.format(date), toast.length_short).show(); } });
所需图片:
以上所述就是本文的全部内容了,希望大家能够喜欢。