Android 万年历日期选择器

Posted R-Pursue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 万年历日期选择器相关的知识,希望对你有一定的参考价值。

先自定义日历视图 CalendarView,直接上代码了

package com.liu.pickerview;

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.R.integer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
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;

/**
 * 日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写)

 * @param 使用方法
 * @param  在xml文件中调用
 * @param 在java代码中      List<Date> markDates = new ArrayList<Date>();
                            calendarView.setMarkDates(markDates);
 *
 * @param 接口 setMarkDates(List<Date>)//设置显示数据
 * @param 接口 setThemeColor(int )//设置主题颜色
 * @param 接口 setCurrentDate(int year ,int month)//设置初始页面年月
 * @param 接口 setOnCalendarViewListener(OnCalendarViewListener())//设置点击监听
 */
public class CalendarView extends LinearLayout implements OnTouchListener,
        AnimationListener, OnGestureListener 
    //顶部 背景 color
    int  color=Color.argb(0xff, 0x0e, 0x6b, 0xc2);
    /**
     * 点击日历
     */
      public interface OnCalendarViewListener 
            void onCalendarItemClick(CalendarView view, Date date);
        
      public interface On
          void setCurrentDate(int year, int month);
      
      public interface color
          void setThemeColor(int color);
      
      public void setThemeColor(int co)
          color=co;
          top.setBackgroundColor(co);
      
    /**
     * 设置当前月份
     */
    public void setCurrentDate(int year,int month)
        UpdateStartDateForMonth(year,month-1);
        generateClaendarGirdView();
    
    /** 顶部控件所占高度 */
    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 RelativeLayout top;
    /** 上一月 */
    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(2012,8);
        // 绘制界面
        setOrientation(LinearLayout.HORIZONTAL);
        mMainLayout = new LinearLayout(mContext);
        LayoutParams main_params = new 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));
        LayoutParams params_br = new LayoutParams(
                LayoutParams.MATCH_PARENT, 3);
        mMainLayout.addView(br, params_br);
    
    /** 生成顶部控件 */

     @SuppressLint("NewApi") 
    private void generateTopView() 
        // 顶部显示上一个下一个,以及当前年月
        top = new RelativeLayout(mContext);
        //顶部栏背景色
        top.setBackgroundColor(color);
        LayoutParams top_params = new LayoutParams(
                LayoutParams.MATCH_PARENT,
                ViewUtil.dip2px(mContext, TOP_HEIGHT));
        top.setLayoutParams(top_params);
        mMainLayout.addView(top);
        // 左方按钮、中间日期显示、右方按钮
        mTitle = new TextView(mContext);
        RelativeLayout.LayoutParams title_params = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                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);
        //添加日期选择
    

    /** 生成中间显示week */
    private void generateWeekGirdView() 
        GridView gridView = new GridView(mContext);
        LayoutParams params = new 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(int year,int month) 
        calStartDate.set(year,month, 1); // 设置成当月第一天
        iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);// 得到当前日历显示的月
        iMonthViewCurrentYear = calStartDate.get(Calendar.YEAR);// 得到当前日历显示的年
        System.out.println("当前月"+iMonthViewCurrentMonth);

        // 星期一是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) 
        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);
        ViewGroup.LayoutParams week_params = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                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 ArrayList<Date> titles;

    private ArrayList<Date> getDates() 

        UpdateStartDateForMonth();

        ArrayList<Date> alArrayList = new ArrayList<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);
        // 显示背景
        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));
        
        /** 设置标注日期颜色 */
        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[]  "子", "丑", "寅", swift 时间选择器第三方。公历转农历,农历转公历。

swift 时间选择器第三方。公历转农历,农历转公历。

swift 时间选择器第三方。公历转农历,农历转公历。

PHP阴历阳历转换

万年历公历农历查询

PHP日期操作类代码-农历-阳历转换闰年计算天数等