Android-PickerView
Android-PickerView copied to clipboard
农历支持setRangDate
贴一个农历支持setRang的代码,有此需求的可以参考一下,修改了三个文件WheelTime.java 、ChinaDate.java、LunarCalendar.java,主要逻辑就是修改年月日的adapter 和 selectedItem.测试了1901-2099年是没问题的
public class WheelTime {
public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private View view;
private WheelView wv_year;
private WheelView wv_month;
private WheelView wv_day;
private WheelView wv_hours;
private WheelView wv_minutes;
private WheelView wv_seconds;
private int gravity;
private boolean[] type;
private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100;
private static final int DEFAULT_START_MONTH = 1;
private static final int DEFAULT_END_MONTH = 12;
private static final int DEFAULT_START_DAY = 1;
private static final int DEFAULT_END_DAY = 31;
private int startYear = DEFAULT_START_YEAR;
private int endYear = DEFAULT_END_YEAR;
private int startMonth = DEFAULT_START_MONTH;
private int endMonth = DEFAULT_END_MONTH;
private int startDay = DEFAULT_START_DAY;
private int endDay = DEFAULT_END_DAY; //表示31天的
private int currentYear;
private int lunarStartYear;
private int lunarEndYear;
private int lunarStartMonth;
private int lunarEndMonth;
private boolean lunarStartMonthIsLeap;
private boolean lunarEndMonthIsLeap;
private int lunarStartDay;
private int lunarEndDay;
private int textSize;
private boolean isLunarCalendar = false;
private ISelectTimeCallback mSelectChangeCallback;
public WheelTime(View view, boolean[] type, int gravity, int textSize) {
super();
this.view = view;
this.type = type;
this.gravity = gravity;
this.textSize = textSize;
}
public void setLunarMode(boolean isLunarCalendar) {
this.isLunarCalendar = isLunarCalendar;
}
public boolean isLunarMode() {
return isLunarCalendar;
}
public void setPicker(int year, int month, int day) {
this.setPicker(year, month, day, 0, 0, 0);
}
public void setPicker(int year, final int month, int day, int h, int m, int s) {
if (isLunarCalendar) {
int[] lunar = LunarCalendar.solarToLunar(year, month + 1, day);
setLunar(lunar[0], lunar[1] - 1, lunar[2], lunar[3] == 1, h, m, s);
} else {
setSolar(year, month, day, h, m, s);
}
}
/**
* 设置农历
*
* @param year
* @param month
* @param day
* @param h
* @param m 0-11
* @param s
*/
private void setLunar(int year, final int month, int day, boolean isLeap, int h, int m, int s) {
// 年
wv_year = (WheelView) view.findViewById(R.id.year);
wv_year.setAdapter(new ArrayWheelAdapter(ChinaDate.getYears(lunarStartYear, lunarEndYear + 1)));// 设置"年"的显示数据
wv_year.setLabel("");// 添加文字
wv_year.setCurrentItem(year - lunarStartYear);// 初始化时显示的数据
wv_year.setGravity(gravity);
// 月
wv_month = (WheelView) view.findViewById(R.id.month);
setLunarMonthAdapter(year);
wv_month.setLabel("");
setLunarMonthSelect(year, month, isLeap);
wv_month.setGravity(gravity);
// 日
wv_day = (WheelView) view.findViewById(R.id.day);
setLunarDayAdapter(year, month, isLeap);
wv_day.setLabel("");
setLunarDaySelect(year, month, day, isLeap);
wv_day.setGravity(gravity);
wv_hours = (WheelView) view.findViewById(R.id.hour);
wv_hours.setAdapter(new NumericWheelAdapter(0, 23));
//wv_hours.setLabel(context.getString(R.string.pickerview_hours));// 添加文字
wv_hours.setCurrentItem(h);
wv_hours.setGravity(gravity);
wv_minutes = (WheelView) view.findViewById(R.id.min);
wv_minutes.setAdapter(new NumericWheelAdapter(0, 59));
//wv_minutes.setLabel(context.getString(R.string.pickerview_minutes));// 添加文字
wv_minutes.setCurrentItem(m);
wv_minutes.setGravity(gravity);
wv_seconds = (WheelView) view.findViewById(R.id.second);
wv_seconds.setAdapter(new NumericWheelAdapter(0, 59));
//wv_seconds.setLabel(context.getString(R.string.pickerview_minutes));// 添加文字
wv_seconds.setCurrentItem(m);
wv_seconds.setGravity(gravity);
// 添加"年"监听
wv_year.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int year_num = index + lunarStartYear;
// 判断是不是闰年,来确定月和日的选择
setLunarMonthAdapter(year_num);
if (ChinaDate.leapMonth(year_num) != 0 && wv_month.getCurrentItem() > ChinaDate.leapMonth(year_num) - 1) {
wv_month.setCurrentItem(wv_month.getCurrentItem() + 1);
} else {
wv_month.setCurrentItem(wv_month.getCurrentItem());
}
int currentIndex = wv_day.getCurrentItem();
int maxItem = 29;
int[] selectedMonth = getLunarSelectedMonth();
maxItem = getLunarMonthMaxDay(year_num, selectedMonth[0] - 1, selectedMonth[1] == 1);
setLunarDayAdapter(year_num, selectedMonth[0] - 1, selectedMonth[1] == 1);
if (currentIndex > maxItem - 1) {
wv_day.setCurrentItem(maxItem - 1);
}
if (mSelectChangeCallback != null) {
mSelectChangeCallback.onTimeSelectChanged();
}
}
});
// 添加"月"监听
wv_month.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int year_num = wv_year.getCurrentItem() + lunarStartYear;
int currentIndex = wv_day.getCurrentItem();
int maxItem = 29;
int[] selectedMonth = getLunarSelectedMonth();
maxItem = getLunarMonthMaxDay(year_num, selectedMonth[0] - 1, selectedMonth[1] == 1);
setLunarDayAdapter(year_num, selectedMonth[0] - 1, selectedMonth[1] == 1);
if (currentIndex > maxItem - 1) {
wv_day.setCurrentItem(maxItem - 1);
}
if (mSelectChangeCallback != null) {
mSelectChangeCallback.onTimeSelectChanged();
}
}
});
setChangedListener(wv_day);
setChangedListener(wv_hours);
setChangedListener(wv_minutes);
setChangedListener(wv_seconds);
if (type.length != 6) {
throw new RuntimeException("type[] length is not 6");
}
wv_year.setVisibility(type[0] ? View.VISIBLE : View.GONE);
wv_month.setVisibility(type[1] ? View.VISIBLE : View.GONE);
wv_day.setVisibility(type[2] ? View.VISIBLE : View.GONE);
wv_hours.setVisibility(type[3] ? View.VISIBLE : View.GONE);
wv_minutes.setVisibility(type[4] ? View.VISIBLE : View.GONE);
wv_seconds.setVisibility(type[5] ? View.VISIBLE : View.GONE);
setContentTextSize();
}
private void setLunarMonthAdapter(int year) {
if (year == lunarStartYear && year == lunarEndYear){
wv_month.setAdapter(new ArrayWheelAdapter(ChinaDate.getMonths(year, lunarStartMonth, lunarStartMonthIsLeap, lunarEndMonth, lunarEndMonthIsLeap)));
}else if (year == lunarStartYear) {
wv_month.setAdapter(new ArrayWheelAdapter(ChinaDate.getMonths(year, lunarStartMonth, lunarStartMonthIsLeap, 12, true)));
} else if (year == lunarEndYear) {
wv_month.setAdapter(new ArrayWheelAdapter(ChinaDate.getMonths(year, 1, false, lunarEndMonth, lunarEndMonthIsLeap)));
} else {
wv_month.setAdapter(new ArrayWheelAdapter(ChinaDate.getMonths(year, 1, false, 12, true)));
}
}
/**
* @param year
* @param month 0-11
* @param isLeap
*/
private void setLunarMonthSelect(int year, int month, boolean isLeap) {
int leapMonth = ChinaDate.leapMonth(year);
if (year == lunarStartYear) {
if (leapMonth != 0 && leapMonth >= lunarStartMonth) {//闰月在开始范围之后
if ((month + 1 > leapMonth || isLeap) && !lunarStartMonthIsLeap) { //选中月是闰月或大于闰月 并 首月不为闰月
wv_month.setCurrentItem(month + 1 - lunarStartMonth + 1);
} else {
wv_month.setCurrentItem(month + 1 - lunarStartMonth);
}
} else {
wv_month.setCurrentItem(month + 1 - lunarStartMonth);
}
} else {
if (leapMonth != 0 && (month + 1 > leapMonth || isLeap)) { //选中月是闰月或大于闰月
wv_month.setCurrentItem(month + 1);
} else {
wv_month.setCurrentItem(month);
}
}
}
/**
* @param year
* @param month 0-11
* @param isLeap
*/
private void setLunarDayAdapter(int year, int month, boolean isLeap) {
if (year == lunarStartYear && month + 1 == lunarStartMonth && isLeap == lunarStartMonthIsLeap) {
wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(lunarStartDay, getLunarMonthMaxDay(year, month, isLeap))));
} else if (year == lunarEndYear && month + 1 == lunarEndMonth) {
wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(1, getLunarMonthMaxDay(year, month, isLeap))));
} else {
wv_day.setAdapter(new ArrayWheelAdapter(ChinaDate.getLunarDays(1,getLunarMonthMaxDay(year, month, isLeap))));
}
}
/**
* 获取year.month的最大天数
* @param year
* @param month 0-11
* @param isLeap
* @return
*/
private int getLunarMonthMaxDay(int year, int month, boolean isLeap) {
if (year == lunarEndYear && month + 1 == lunarEndMonth && isLeap == lunarEndMonthIsLeap) {
return lunarEndDay;
} else {
if (month + 1 == ChinaDate.leapMonth(year) && isLeap) {
//选中闰月
return ChinaDate.leapDays(year);
} else {
return ChinaDate.monthDays(year, month + 1);
}
}
}
/**
* @param year
* @param month 0-11
* @param day
*/
private void setLunarDaySelect(int year, int month, int day, boolean isLeap) {
if (year == lunarStartYear && month + 1 == lunarStartMonth && lunarStartMonthIsLeap == isLeap) {
wv_day.setCurrentItem(day - lunarStartDay);
} else {
wv_day.setCurrentItem(day - 1);
}
}
/**
* 选择的年份
*/
private int getLunarSelectedYear() {
return wv_year.getCurrentItem() + lunarStartYear;
}
/**
* 选择的月份
* @return int[0] : month : 1-12 ,int[1]: 是否是闰月
*/
private int[] getLunarSelectedMonth() {
int[] res = new int[2];
int year_num = getLunarSelectedYear();
int leapMonth = ChinaDate.leapMonth(year_num);
if (year_num == lunarStartYear) {
if (leapMonth != 0 && (leapMonth >= lunarStartMonth)) {//闰月在开始范围之后
if (wv_month.getCurrentItem() + lunarStartMonth < leapMonth) {
//非闰月,小于闰月
res[0] = wv_month.getCurrentItem() + lunarStartMonth;
} else if (wv_month.getCurrentItem() + lunarStartMonth == leapMonth && !lunarStartMonthIsLeap) {
//非闰月,闰月前一个月
res[0] = wv_month.getCurrentItem() + lunarStartMonth;
} else if (wv_month.getCurrentItem() + lunarStartMonth == leapMonth && lunarStartMonthIsLeap) {
//闰月,开始月份为闰月
res[0] = wv_month.getCurrentItem() + lunarStartMonth;
res[1] = 1;
} else if (wv_month.getCurrentItem() + lunarStartMonth - 1 == leapMonth && !lunarStartMonthIsLeap) {
//闰月
res[0] = wv_month.getCurrentItem() + lunarStartMonth - 1;
res[1] = 1;
} else {
//大于闰月
if (lunarStartMonthIsLeap) {
res[0] = wv_month.getCurrentItem() + lunarStartMonth;
} else {
res[0] = wv_month.getCurrentItem() + lunarStartMonth - 1;
}
}
} else {
//无闰月
res[0] = wv_month.getCurrentItem() + lunarStartMonth;
}
} else {
if (ChinaDate.leapMonth(year_num) != 0 && wv_month.getCurrentItem() > ChinaDate.leapMonth(year_num) - 1) {//选中月是闰月或大于闰月
if (wv_month.getCurrentItem() == ChinaDate.leapMonth(year_num)) {
//选中闰月
res[0] = wv_month.getCurrentItem();
res[1] = 1;
} else {
//选中大于闰月
res[0] = wv_month.getCurrentItem();
}
} else {
//没有闰月或者选中小于闰月
res[0] = wv_month.getCurrentItem() + 1;
}
}
return res;
}
/**
* 选择的日期
* @param year
* @param month 0-11
* @return
*/
private int getLunarSelectedDay(int year, int month, boolean isLeap) {
if (year == lunarStartYear && month + 1 == lunarStartMonth && lunarStartMonthIsLeap == isLeap) {
return wv_day.getCurrentItem() + lunarStartDay;
} else {
return wv_day.getCurrentItem() + 1;
}
}
/**
* 设置公历
*
* @param year
* @param month
* @param day
* @param h
* @param m
* @param s
*/
private void setSolar(int year, final int month, int day, int h, int m, int s) {
// 添加大小月月份并将其转换为list,方便之后的判断
String[] months_big = {"1", "3", "5", "7", "8", "10", "12"};
String[] months_little = {"4", "6", "9", "11"};
final List<String> list_big = Arrays.asList(months_big);
final List<String> list_little = Arrays.asList(months_little);
currentYear = year;
// 年
wv_year = (WheelView) view.findViewById(R.id.year);
wv_year.setAdapter(new NumericWheelAdapter(startYear, endYear));// 设置"年"的显示数据
wv_year.setCurrentItem(year - startYear);// 初始化时显示的数据
wv_year.setGravity(gravity);
// 月
wv_month = (WheelView) view.findViewById(R.id.month);
if (startYear == endYear) {//开始年等于终止年
wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
wv_month.setCurrentItem(month + 1 - startMonth);
} else if (year == startYear) {
//起始日期的月份控制
wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12));
wv_month.setCurrentItem(month + 1 - startMonth);
} else if (year == endYear) {
//终止日期的月份控制
wv_month.setAdapter(new NumericWheelAdapter(1, endMonth));
wv_month.setCurrentItem(month);
} else {
wv_month.setAdapter(new NumericWheelAdapter(1, 12));
wv_month.setCurrentItem(month);
}
wv_month.setGravity(gravity);
// 日
wv_day = (WheelView) view.findViewById(R.id.day);
boolean leapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
if (startYear == endYear && startMonth == endMonth) {
if (list_big.contains(String.valueOf(month + 1))) {
if (endDay > 31) {
endDay = 31;
}
wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
} else if (list_little.contains(String.valueOf(month + 1))) {
if (endDay > 30) {
endDay = 30;
}
wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
} else {
// 闰年
if (leapYear) {
if (endDay > 29) {
endDay = 29;
}
wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
} else {
if (endDay > 28) {
endDay = 28;
}
wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
}
}
wv_day.setCurrentItem(day - startDay);
} else if (year == startYear && month + 1 == startMonth) {
// 起始日期的天数控制
if (list_big.contains(String.valueOf(month + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(startDay, 31));
} else if (list_little.contains(String.valueOf(month + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(startDay, 30));
} else {
// 闰年 29,平年 28
wv_day.setAdapter(new NumericWheelAdapter(startDay, leapYear ? 29 : 28));
}
wv_day.setCurrentItem(day - startDay);
} else if (year == endYear && month + 1 == endMonth) {
// 终止日期的天数控制
if (list_big.contains(String.valueOf(month + 1))) {
if (endDay > 31) {
endDay = 31;
}
wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
} else if (list_little.contains(String.valueOf(month + 1))) {
if (endDay > 30) {
endDay = 30;
}
wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
} else {
// 闰年
if (leapYear) {
if (endDay > 29) {
endDay = 29;
}
wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
} else {
if (endDay > 28) {
endDay = 28;
}
wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
}
}
wv_day.setCurrentItem(day - 1);
} else {
// 判断大小月及是否闰年,用来确定"日"的数据
if (list_big.contains(String.valueOf(month + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 31));
} else if (list_little.contains(String.valueOf(month + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 30));
} else {
// 闰年 29,平年 28
wv_day.setAdapter(new NumericWheelAdapter(1, leapYear ? 29 : 28));
}
wv_day.setCurrentItem(day - 1);
}
wv_day.setGravity(gravity);
//时
wv_hours = (WheelView) view.findViewById(R.id.hour);
wv_hours.setAdapter(new NumericWheelAdapter(0, 23));
wv_hours.setCurrentItem(h);
wv_hours.setGravity(gravity);
//分
wv_minutes = (WheelView) view.findViewById(R.id.min);
wv_minutes.setAdapter(new NumericWheelAdapter(0, 59));
wv_minutes.setCurrentItem(m);
wv_minutes.setGravity(gravity);
//秒
wv_seconds = (WheelView) view.findViewById(R.id.second);
wv_seconds.setAdapter(new NumericWheelAdapter(0, 59));
wv_seconds.setCurrentItem(s);
wv_seconds.setGravity(gravity);
// 添加"年"监听
wv_year.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int year_num = index + startYear;
currentYear = year_num;
int currentMonthItem = wv_month.getCurrentItem();//记录上一次的item位置
// 判断大小月及是否闰年,用来确定"日"的数据
if (startYear == endYear) {
//重新设置月份
wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
wv_month.setCurrentItem(currentMonthItem);
}
int monthNum = currentMonthItem + startMonth;
if (startMonth == endMonth) {
//重新设置日
setReDay(year_num, monthNum, startDay, endDay, list_big, list_little);
} else if (monthNum == startMonth) {
//重新设置日
setReDay(year_num, monthNum, startDay, 31, list_big, list_little);
} else if (monthNum == endMonth) {
setReDay(year_num, monthNum, 1, endDay, list_big, list_little);
} else {//重新设置日
setReDay(year_num, monthNum, 1, 31, list_big, list_little);
}
} else if (year_num == startYear) {//等于开始的年
//重新设置月份
wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12));
if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
wv_month.setCurrentItem(currentMonthItem);
}
int month = currentMonthItem + startMonth;
if (month == startMonth) {
//重新设置日
setReDay(year_num, month, startDay, 31, list_big, list_little);
} else {
//重新设置日
setReDay(year_num, month, 1, 31, list_big, list_little);
}
} else if (year_num == endYear) {
//重新设置月份
wv_month.setAdapter(new NumericWheelAdapter(1, endMonth));
if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
wv_month.setCurrentItem(currentMonthItem);
}
int monthNum = currentMonthItem + 1;
if (monthNum == endMonth) {
//重新设置日
setReDay(year_num, monthNum, 1, endDay, list_big, list_little);
} else {
//重新设置日
setReDay(year_num, monthNum, 1, 31, list_big, list_little);
}
} else {
//重新设置月份
wv_month.setAdapter(new NumericWheelAdapter(1, 12));
//重新设置日
setReDay(year_num, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little);
}
if (mSelectChangeCallback != null) {
mSelectChangeCallback.onTimeSelectChanged();
}
}
});
// 添加"月"监听
wv_month.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int month_num = index + 1;
if (startYear == endYear) {
month_num = month_num + startMonth - 1;
if (startMonth == endMonth) {
//重新设置日
setReDay(currentYear, month_num, startDay, endDay, list_big, list_little);
} else if (startMonth == month_num) {
//重新设置日
setReDay(currentYear, month_num, startDay, 31, list_big, list_little);
} else if (endMonth == month_num) {
setReDay(currentYear, month_num, 1, endDay, list_big, list_little);
} else {
setReDay(currentYear, month_num, 1, 31, list_big, list_little);
}
} else if (currentYear == startYear) {
month_num = month_num + startMonth - 1;
if (month_num == startMonth) {
//重新设置日
setReDay(currentYear, month_num, startDay, 31, list_big, list_little);
} else {
//重新设置日
setReDay(currentYear, month_num, 1, 31, list_big, list_little);
}
} else if (currentYear == endYear) {
if (month_num == endMonth) {
//重新设置日
setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, endDay, list_big, list_little);
} else {
setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little);
}
} else {
//重新设置日
setReDay(currentYear, month_num, 1, 31, list_big, list_little);
}
if (mSelectChangeCallback != null) {
mSelectChangeCallback.onTimeSelectChanged();
}
}
});
setChangedListener(wv_day);
setChangedListener(wv_hours);
setChangedListener(wv_minutes);
setChangedListener(wv_seconds);
if (type.length != 6) {
throw new IllegalArgumentException("type[] length is not 6");
}
wv_year.setVisibility(type[0] ? View.VISIBLE : View.GONE);
wv_month.setVisibility(type[1] ? View.VISIBLE : View.GONE);
wv_day.setVisibility(type[2] ? View.VISIBLE : View.GONE);
wv_hours.setVisibility(type[3] ? View.VISIBLE : View.GONE);
wv_minutes.setVisibility(type[4] ? View.VISIBLE : View.GONE);
wv_seconds.setVisibility(type[5] ? View.VISIBLE : View.GONE);
setContentTextSize();
}
private void setChangedListener(WheelView wheelView) {
if (mSelectChangeCallback != null) {
wheelView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
mSelectChangeCallback.onTimeSelectChanged();
}
});
}
}
private void setReDay(int year_num, int monthNum, int startD, int endD, List<String> list_big, List<String> list_little) {
int currentItem = wv_day.getCurrentItem();
// int maxItem;
if (list_big.contains(String.valueOf(monthNum))) {
if (endD > 31) {
endD = 31;
}
wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
// maxItem = endD;
} else if (list_little.contains(String.valueOf(monthNum))) {
if (endD > 30) {
endD = 30;
}
wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
// maxItem = endD;
} else {
if ((year_num % 4 == 0 && year_num % 100 != 0)
|| year_num % 400 == 0) {
if (endD > 29) {
endD = 29;
}
wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
// maxItem = endD;
} else {
if (endD > 28) {
endD = 28;
}
wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
// maxItem = endD;
}
}
if (currentItem > wv_day.getAdapter().getItemsCount() - 1) {
currentItem = wv_day.getAdapter().getItemsCount() - 1;
wv_day.setCurrentItem(currentItem);
}
}
private void setContentTextSize() {
wv_day.setTextSize(textSize);
wv_month.setTextSize(textSize);
wv_year.setTextSize(textSize);
wv_hours.setTextSize(textSize);
wv_minutes.setTextSize(textSize);
wv_seconds.setTextSize(textSize);
}
public void setLabels(String label_year, String label_month, String label_day, String label_hours, String label_mins, String label_seconds) {
if (isLunarCalendar) {
return;
}
if (label_year != null) {
wv_year.setLabel(label_year);
} else {
wv_year.setLabel(view.getContext().getString(R.string.pickerview_year));
}
if (label_month != null) {
wv_month.setLabel(label_month);
} else {
wv_month.setLabel(view.getContext().getString(R.string.pickerview_month));
}
if (label_day != null) {
wv_day.setLabel(label_day);
} else {
wv_day.setLabel(view.getContext().getString(R.string.pickerview_day));
}
if (label_hours != null) {
wv_hours.setLabel(label_hours);
} else {
wv_hours.setLabel(view.getContext().getString(R.string.pickerview_hours));
}
if (label_mins != null) {
wv_minutes.setLabel(label_mins);
} else {
wv_minutes.setLabel(view.getContext().getString(R.string.pickerview_minutes));
}
if (label_seconds != null) {
wv_seconds.setLabel(label_seconds);
} else {
wv_seconds.setLabel(view.getContext().getString(R.string.pickerview_seconds));
}
}
public void setTextXOffset(int x_offset_year, int x_offset_month, int x_offset_day,
int x_offset_hours, int x_offset_minutes, int x_offset_seconds) {
wv_year.setTextXOffset(x_offset_year);
wv_month.setTextXOffset(x_offset_month);
wv_day.setTextXOffset(x_offset_day);
wv_hours.setTextXOffset(x_offset_hours);
wv_minutes.setTextXOffset(x_offset_minutes);
wv_seconds.setTextXOffset(x_offset_seconds);
}
/**
* 设置是否循环滚动
*
* @param cyclic
*/
public void setCyclic(boolean cyclic) {
wv_year.setCyclic(cyclic);
wv_month.setCyclic(cyclic);
wv_day.setCyclic(cyclic);
wv_hours.setCyclic(cyclic);
wv_minutes.setCyclic(cyclic);
wv_seconds.setCyclic(cyclic);
}
public String getTime() {
if (isLunarCalendar) {
//如果是农历 返回对应的公历时间
return getLunarTime();
}
StringBuilder sb = new StringBuilder();
if (currentYear == startYear) {
/* int i = wv_month.getCurrentItem() + startMonth;
System.out.println("i:" + i);*/
if ((wv_month.getCurrentItem() + startMonth) == startMonth) {
sb.append((wv_year.getCurrentItem() + startYear)).append("-")
.append((wv_month.getCurrentItem() + startMonth)).append("-")
.append((wv_day.getCurrentItem() + startDay)).append(" ")
.append(wv_hours.getCurrentItem()).append(":")
.append(wv_minutes.getCurrentItem()).append(":")
.append(wv_seconds.getCurrentItem());
} else {
sb.append((wv_year.getCurrentItem() + startYear)).append("-")
.append((wv_month.getCurrentItem() + startMonth)).append("-")
.append((wv_day.getCurrentItem() + 1)).append(" ")
.append(wv_hours.getCurrentItem()).append(":")
.append(wv_minutes.getCurrentItem()).append(":")
.append(wv_seconds.getCurrentItem());
}
} else {
sb.append((wv_year.getCurrentItem() + startYear)).append("-")
.append((wv_month.getCurrentItem() + 1)).append("-")
.append((wv_day.getCurrentItem() + 1)).append(" ")
.append(wv_hours.getCurrentItem()).append(":")
.append(wv_minutes.getCurrentItem()).append(":")
.append(wv_seconds.getCurrentItem());
}
return sb.toString();
}
/**
* 农历返回对应的公历时间
*
* @return
*/
private String getLunarTime() {
StringBuilder sb = new StringBuilder();
int lunarSelectedYear = getLunarSelectedYear();
int[] lunarSelectedMonth = getLunarSelectedMonth();
int lunarSelectedDay = getLunarSelectedDay(lunarSelectedYear, lunarSelectedMonth[0] - 1, lunarSelectedMonth[1] == 1);
int[] solar = LunarCalendar.lunarToSolar(lunarSelectedYear, lunarSelectedMonth[0], lunarSelectedDay, lunarSelectedMonth[1] == 1);
sb.append(solar[0]).append("-")
.append(solar[1]).append("-")
.append(solar[2]).append(" ")
.append(wv_hours.getCurrentItem()).append(":")
.append(wv_minutes.getCurrentItem()).append(":")
.append(wv_seconds.getCurrentItem());
return sb.toString();
}
public View getView() {
return view;
}
public int getStartYear() {
return startYear;
}
public void setStartYear(int startYear) {
this.startYear = startYear;
}
public int getEndYear() {
return endYear;
}
public void setEndYear(int endYear) {
this.endYear = endYear;
}
public void setRangDate(Calendar startDate, Calendar endDate) {
if (startDate == null && endDate != null) {
int year = endDate.get(Calendar.YEAR);
int month = endDate.get(Calendar.MONTH) + 1;
int day = endDate.get(Calendar.DAY_OF_MONTH);
if (year > startYear) {
this.endYear = year;
this.endMonth = month;
this.endDay = day;
} else if (year == startYear) {
if (month > startMonth) {
this.endYear = year;
this.endMonth = month;
this.endDay = day;
} else if (month == startMonth) {
if (day > startDay) {
this.endYear = year;
this.endMonth = month;
this.endDay = day;
}
}
}
} else if (startDate != null && endDate == null) {
int year = startDate.get(Calendar.YEAR);
int month = startDate.get(Calendar.MONTH) + 1;
int day = startDate.get(Calendar.DAY_OF_MONTH);
if (year < endYear) {
this.startMonth = month;
this.startDay = day;
this.startYear = year;
} else if (year == endYear) {
if (month < endMonth) {
this.startMonth = month;
this.startDay = day;
this.startYear = year;
} else if (month == endMonth) {
if (day < endDay) {
this.startMonth = month;
this.startDay = day;
this.startYear = year;
}
}
}
} else if (startDate != null && endDate != null) {
this.startYear = startDate.get(Calendar.YEAR);
this.endYear = endDate.get(Calendar.YEAR);
this.startMonth = startDate.get(Calendar.MONTH) + 1;
this.endMonth = endDate.get(Calendar.MONTH) + 1;
this.startDay = startDate.get(Calendar.DAY_OF_MONTH);
this.endDay = endDate.get(Calendar.DAY_OF_MONTH);
}
int[] lunarStartDate = LunarCalendar.solarToLunar(startYear, startMonth, startDay);
int[] lunarEndDate = LunarCalendar.solarToLunar(endYear, endMonth, endDay);
lunarStartYear = lunarStartDate[0];
lunarStartMonth = lunarStartDate[1];
lunarStartDay = lunarStartDate[2];
lunarStartMonthIsLeap = lunarStartDate[3] == 1;
lunarEndYear = lunarEndDate[0];
lunarEndMonth = lunarEndDate[1];
lunarEndDay = lunarEndDate[2];
lunarEndMonthIsLeap = lunarEndDate[3] == 1;
}
/**
* 设置间距倍数,但是只能在1.0-4.0f之间
*
* @param lineSpacingMultiplier
*/
public void setLineSpacingMultiplier(float lineSpacingMultiplier) {
wv_day.setLineSpacingMultiplier(lineSpacingMultiplier);
wv_month.setLineSpacingMultiplier(lineSpacingMultiplier);
wv_year.setLineSpacingMultiplier(lineSpacingMultiplier);
wv_hours.setLineSpacingMultiplier(lineSpacingMultiplier);
wv_minutes.setLineSpacingMultiplier(lineSpacingMultiplier);
wv_seconds.setLineSpacingMultiplier(lineSpacingMultiplier);
}
/**
* 设置分割线的颜色
*
* @param dividerColor
*/
public void setDividerColor(int dividerColor) {
wv_day.setDividerColor(dividerColor);
wv_month.setDividerColor(dividerColor);
wv_year.setDividerColor(dividerColor);
wv_hours.setDividerColor(dividerColor);
wv_minutes.setDividerColor(dividerColor);
wv_seconds.setDividerColor(dividerColor);
}
/**
* 设置分割线的类型
*
* @param dividerType
*/
public void setDividerType(WheelView.DividerType dividerType) {
wv_day.setDividerType(dividerType);
wv_month.setDividerType(dividerType);
wv_year.setDividerType(dividerType);
wv_hours.setDividerType(dividerType);
wv_minutes.setDividerType(dividerType);
wv_seconds.setDividerType(dividerType);
}
/**
* 设置分割线之间的文字的颜色
*
* @param textColorCenter
*/
public void setTextColorCenter(int textColorCenter) {
wv_day.setTextColorCenter(textColorCenter);
wv_month.setTextColorCenter(textColorCenter);
wv_year.setTextColorCenter(textColorCenter);
wv_hours.setTextColorCenter(textColorCenter);
wv_minutes.setTextColorCenter(textColorCenter);
wv_seconds.setTextColorCenter(textColorCenter);
}
/**
* 设置分割线以外文字的颜色
*
* @param textColorOut
*/
public void setTextColorOut(int textColorOut) {
wv_day.setTextColorOut(textColorOut);
wv_month.setTextColorOut(textColorOut);
wv_year.setTextColorOut(textColorOut);
wv_hours.setTextColorOut(textColorOut);
wv_minutes.setTextColorOut(textColorOut);
wv_seconds.setTextColorOut(textColorOut);
}
/**
* @param isCenterLabel 是否只显示中间选中项的
*/
public void isCenterLabel(boolean isCenterLabel) {
wv_day.isCenterLabel(isCenterLabel);
wv_month.isCenterLabel(isCenterLabel);
wv_year.isCenterLabel(isCenterLabel);
wv_hours.isCenterLabel(isCenterLabel);
wv_minutes.isCenterLabel(isCenterLabel);
wv_seconds.isCenterLabel(isCenterLabel);
}
public void setSelectChangeCallback(ISelectTimeCallback mSelectChangeCallback) {
this.mSelectChangeCallback = mSelectChangeCallback;
}
public void setItemsVisible(int itemsVisibleCount) {
wv_day.setItemsVisibleCount(itemsVisibleCount);
wv_month.setItemsVisibleCount(itemsVisibleCount);
wv_year.setItemsVisibleCount(itemsVisibleCount);
wv_hours.setItemsVisibleCount(itemsVisibleCount);
wv_minutes.setItemsVisibleCount(itemsVisibleCount);
wv_seconds.setItemsVisibleCount(itemsVisibleCount);
}
public void setAlphaGradient(boolean isAlphaGradient) {
wv_day.setAlphaGradient(isAlphaGradient);
wv_month.setAlphaGradient(isAlphaGradient);
wv_year.setAlphaGradient(isAlphaGradient);
wv_hours.setAlphaGradient(isAlphaGradient);
wv_minutes.setAlphaGradient(isAlphaGradient);
wv_seconds.setAlphaGradient(isAlphaGradient);
}
}
public class ChinaDate {
/**
* <lunarInfo 数组值的计算原理>
* <p>
* 0x代表十六进制,后面的五位数是十六进制数。
* 举个例子: 1980年的数据是 0x095b0
* 二进制: 0000 1001 0101 1011 0000
* 1-4: 表示当年是否为闰年,是的话为1,否则为0。
* 5-16: 为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
* 注意: 从1月到12月对应的是第16位到第5位。
* 17-20: 非闰年为0,大于0表示闰月月份,仅当存在闰月的情况下有意义。
*/
final private static long[] lunarInfo = new long[]{
0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,//1900-1909
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,//1910-1919
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,//1920-1929
0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,//1930-1939
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,//1940-1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,//1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,//1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,//1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,//1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,//1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,//2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,//2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,//2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,//2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,//2040-2049
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0,//2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4,//2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0,//2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160,//2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-2099
0x0d520};//2100
private final static String[] nStr1 = new String[]{"", "正", "二", "三", "四",
"五", "六", "七", "八", "九", "十", "冬", "腊"};
private final static String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊",
"己", "庚", "辛", "壬", "癸"};
private final static String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰",
"巳", "午", "未", "申", "酉", "戌", "亥"};
private final static String[] Animals = new String[]{"鼠", "牛", "虎", "兔",
"龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
/**
* 传回农历
*
* @param y 年的总天数
* @return 农历
*/
final private static int lYearDays(int y) {
int i, sum = 348;
for (i = 0x8000; i > 0x8; i >>= 1) {
if ((lunarInfo[y - 1900] & i) != 0)
sum += 1;
}
return (sum + leapDays(y));
}
/**
* 传回农历
*
* @param y 年闰月的天数
* @return 农历
*/
final public static int leapDays(int y) {
if (leapMonth(y) != 0) {
if ((lunarInfo[y - 1900] & 0x10000) != 0)
return 30;
else
return 29;
} else
return 0;
}
/**
* 传回农历
*
* @param y 年闰哪个月 1-12 , 没闰传回 0
* @return 农历
*/
final public static int leapMonth(int y) {
return (int) (lunarInfo[y - 1900] & 0xf);
}
/**
* 传回农历 y
*
* @param y y年m月的总天数
* @param m y年m月的总天数
* @return 农历
*/
final public static int monthDays(int y, int m) {
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
return 29;
else
return 30;
}
/**
* 传回农历
*
* @param y 年的生肖
* @return
*/
final public static String AnimalsYear(int y) {
return Animals[(y - 4) % 12];
}
/**
* 传入
*
* @param num 月日的offset 传回干支,0是甲子
* @return 干支
*/
final private static String cyclicalm(int num) {
return (Gan[num % 10] + Zhi[num % 12]);
}
/**
* 传入 offset 传回干支
*
* @param y 0是甲子
* @return 干支
*/
final public static String cyclical(int y) {
int num = y - 1900 + 36;
return (cyclicalm(num));
}
/**
* 传出y年m月d日对应的农历.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
*
* @param y 年
* @param m 月
* @param d 日
* @return y年m月d日对应的农历
*/
final public static long[] calElement(int y, int m, int d) {
long[] nongDate = new long[7];
int i = 0, temp = 0, leap = 0;
Date baseDate = new GregorianCalendar(0 + 1900, 0, 31).getTime();
Date objDate = new GregorianCalendar(y, m - 1, d).getTime();
long offset = (objDate.getTime() - baseDate.getTime()) / 86400000L;
nongDate[5] = offset + 40;
nongDate[4] = 14;
for (i = 1900; i < 2100 && offset > 0; i++) {
temp = lYearDays(i);
offset -= temp;
nongDate[4] += 12;
}
if (offset < 0) {
offset += temp;
i--;
nongDate[4] -= 12;
}
nongDate[0] = i;
nongDate[3] = i - 1864;
leap = leapMonth(i); // 闰哪个月
nongDate[6] = 0;
for (i = 1; i < 13 && offset > 0; i++) {
// 闰月
if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) {
--i;
nongDate[6] = 1;
temp = leapDays((int) nongDate[0]);
} else {
temp = monthDays((int) nongDate[0], i);
}
// 解除闰月
if (nongDate[6] == 1 && i == (leap + 1))
nongDate[6] = 0;
offset -= temp;
if (nongDate[6] == 0)
nongDate[4]++;
}
if (offset == 0 && leap > 0 && i == leap + 1) {
if (nongDate[6] == 1) {
nongDate[6] = 0;
} else {
nongDate[6] = 1;
--i;
--nongDate[4];
}
}
if (offset < 0) {
offset += temp;
--i;
--nongDate[4];
}
nongDate[1] = i;
nongDate[2] = offset + 1;
return nongDate;
}
public final static String getChinaDate(int day) {
String a = "";
if (day == 10)
return "初十";
if (day == 20)
return "二十";
if (day == 30)
return "三十";
int two = (int) ((day) / 10);
if (two == 0)
a = "初";
if (two == 1)
a = "十";
if (two == 2)
a = "廿";
if (two == 3)
a = "三";
int one = (int) (day % 10);
switch (one) {
case 1:
a += "一";
break;
case 2:
a += "二";
break;
case 3:
a += "三";
break;
case 4:
a += "四";
break;
case 5:
a += "五";
break;
case 6:
a += "六";
break;
case 7:
a += "七";
break;
case 8:
a += "八";
break;
case 9:
a += "九";
break;
}
return a;
}
public static String getCurrentLunarDate() {
Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
int year = today.get(Calendar.YEAR);
int month = today.get(Calendar.MONTH) + 1;
int date = today.get(Calendar.DATE);
long[] l = calElement(year, month, date);
StringBuffer sToday = new StringBuffer();
try {
sToday.append(sdf.format(today.getTime()));
sToday.append(" 农历");
sToday.append(cyclical(year));
sToday.append('(');
sToday.append(AnimalsYear(year));
sToday.append(")年");
sToday.append(nStr1[(int) l[1]]);
sToday.append("月");
sToday.append(getChinaDate((int) (l[2])));
return sToday.toString();
} finally {
sToday = null;
}
}
public static String oneDay(int year, int month, int day) {
// Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
long[] l = calElement(year, month, day);
StringBuffer sToday = new StringBuffer();
try {
// sToday.append(sdf.format(today.getTime()));
sToday.append(" 农历");
sToday.append(cyclical(year));
sToday.append('(');
sToday.append(AnimalsYear(year));
sToday.append(")年");
sToday.append(nStr1[(int) l[1]]);
sToday.append("月");
sToday.append(getChinaDate((int) (l[2])));
return sToday.toString();
} finally {
sToday = null;
}
}
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日 EEEEE");
/**
* @param lunarYear 农历年份
* @return String of Ganzhi: 甲子年
* 甲乙丙丁戊己庚辛壬癸
* 子丑寅卯辰巳无为申酉戌亥
*/
public static String getLunarYearText(int lunarYear) {
return Gan[(lunarYear - 4) % 10] + Zhi[(lunarYear - 4) % 12] + "年";
}
public static ArrayList<String> getYears(int startYear, int endYear) {
ArrayList<String> years = new ArrayList<>();
for (int i = startYear; i < endYear; i++) {
//years.add(String.format("%s(%d)", getLunarYearText(i), i));
years.add(String.format("%d", i));
}
return years;
}
/**
* 获取year年的所有月份
*
* @param year 年
* @return 月份列表
*/
public static ArrayList<String> getMonths(int year, int startMonth, boolean startMonthIsLeap, int endMonth, boolean endMonthIsLeap) {
ArrayList<String> baseMonths = new ArrayList<>();
int leapMonth = leapMonth(year);
for (int i = startMonth; i <= endMonth; i++) {
if (i != startMonth || !startMonthIsLeap){
baseMonths.add(nStr1[i] + "月");
}
if (i == leapMonth && (i != endMonth || endMonthIsLeap)){
baseMonths.add("闰" + nStr1[leapMonth(year)] + "月");
}
}
return baseMonths;
}
/**
* 获取每月农历显示名称
*
* @param maxDay 天
* @return 名称列表
*/
public static ArrayList<String> getLunarDays(int minDay, int maxDay) {
ArrayList<String> days = new ArrayList<>();
for (int i = minDay; i <= maxDay; i++) {
days.add(getChinaDate(i));
}
return days;
}
}
/**
* author: Jerry on 2016/7/11 11:29.
* description:工具类,实现公农历互转
*/
public class LunarCalendar {
/**
* 支持转换的最小农历年份
*/
public static final int MIN_YEAR = 1900;
/**
* 支持转换的最大农历年份
*/
public static final int MAX_YEAR = 2099;
/**
* 公历每月前的天数
*/
private static final int DAYS_BEFORE_MONTH[] = {0, 31, 59, 90, 120, 151, 181,
212, 243, 273, 304, 334, 365};
/**
* 用来表示1900年到2099年间农历年份的相关信息,共24位bit的16进制表示,其中:
* 1. 前4位表示该年闰哪个月;
* 2. 5-17位表示农历年份13个月的大小月分布,0表示小,1表示大;
* 3. 最后7位表示农历年首(正月初一)对应的公历日期。
* <p>
* 以2014年的数据0x955ABF为例说明:
* 1001 0101 0101 1010 1011 1111
* 闰九月 农历正月初一对应公历1月31号
*/
private static final int LUNAR_INFO[] = {
0x84B6BF,/*1900*/
0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A,/*1901-1910*/
0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754,/*1911-1920*/
0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E,/*1921-1930*/
0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48,/*1931-1940*/
0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51,/*1941-1950*/
0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C,/*1951-1960*/
0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46,/*1961-1970*/
0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50,/*1971-1980*/
0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x095746, 0x5497BB,/*1981-1990*/
0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645,/*1991-2000*/
0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E,/*2001-2010*/
0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9,/*2011-2020*/
0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x6a573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43,/*2021-2030*/
0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C,/*2031-2040*/
0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37,/*2041-2050*/
0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06AA44, 0x4AB638, 0x0AAE4C, 0x092E42,/*2051-2060*/
0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B,/*2061-2070*/
0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6,/*2071-2080*/
0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E,/*2081-2090*/
0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 /*2091-2099*/
};
private static int[] solar_1_1 = {1887, 0xec04c, 0xec23f, 0xec435, 0xec649,
0xec83e, 0xeca51, 0xecc46, 0xece3a, 0xed04d, 0xed242, 0xed436,
0xed64a, 0xed83f, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244,
0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052,
0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41,
0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d,
0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651, 0xf1846, 0xf1a3a,
0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848,
0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636,
0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443,
0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f,
0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e,
0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b,
0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850, 0xf7a45, 0xf7c39,
0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46,
0xf8c3b, 0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853,
0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641,
0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e,
0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c,
0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a,
0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43, 0xfde37,
0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44,
0xfee38, 0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51,
0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437, 0x10064b, 0x100841,
0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438,
0x10164c, 0x101842, 0x101a35, 0x101c49, 0x101e3d, 0x102051,
0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b,
0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845,
0x103a38, 0x103c4c, 0x103e42, 0x104036, 0x104249, 0x10443d,
0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038,
0x10524a, 0x10543e, 0x105652, 0x105847, 0x105a3b, 0x105c4f,
0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849,
0x106a3d, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444,
0x107638, 0x10784c, 0x107a3f, 0x107c53, 0x107e48};
private static int[] lunar_month_days = {1887, 0x1694, 0x16aa, 0x4ad5,
0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a, 0xd54, 0x75aa, 0x156a,
0x1096d, 0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4,
0x135a, 0x495d, 0x95c, 0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8,
0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e, 0x1496, 0xb64b, 0xd4a,
0xda8, 0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96, 0x1a94,
0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d, 0x192a,
0x1a94, 0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b,
0x152a, 0xf695, 0xd94, 0x16aa, 0xaab5, 0x9b4, 0x14b6, 0x6a57,
0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa, 0x156a, 0x96c, 0x94ae,
0x14ae, 0xa4c, 0x7d26, 0x1b2a, 0xeb55, 0xad4, 0x12da, 0xa95d,
0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da,
0x12b6, 0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4,
0x156c, 0x12ae, 0xa92f, 0x92e, 0xc96, 0x6d4a, 0x1d4a, 0x10d65,
0xb58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a,
0x4b55, 0xad4, 0xf55b, 0x4ba, 0x125a, 0xb92b, 0x152a, 0x1694,
0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526,
0x8e95, 0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c,
0xbd26, 0x1aa6, 0xb54, 0x6d6a, 0x12da, 0x1695d, 0x95a, 0x149a,
0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0xada, 0x495b, 0x936,
0xf497, 0x1496, 0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6, 0x126e,
0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c,
0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4,
0x14da, 0x8a5d, 0xa5a, 0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa,
0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527, 0xd26, 0xee53, 0xd54, 0x15aa,
0xa9b5, 0x96c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54,
0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25, 0x1aa4,
0xfb52, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a,
0x136a5, 0xda4, 0x15ac};
/**
* 将农历日期转换为公历日期
*
* @param year 农历年份
* @param month 农历月
* @param monthDay 农历日
* @param isLeapMonth 该月是否是闰月
* @return 返回农历日期对应的公历日期,year0, month1, day2.
*/
/*public static final int[] lunarToSolar(int year, int month, int monthDay,
boolean isLeapMonth) {
int dayOffset;
int leapMonth;
int i;
if (year < MIN_YEAR || year > MAX_YEAR || month < 1 || month > 12
|| monthDay < 1 || monthDay > 30) {
throw new IllegalArgumentException(
"Illegal lunar date, must be like that:\n\t" +
"year : 1900~2099\n\t" +
"month : 1~12\n\t" +
"day : 1~30");
}
dayOffset = (LUNAR_INFO[year - MIN_YEAR] & 0x001F) - 1;
if (((LUNAR_INFO[year - MIN_YEAR] & 0x0060) >> 5) == 2)
dayOffset += 31;
for (i = 1; i < month; i++) {
if ((LUNAR_INFO[year - MIN_YEAR] & (0x80000 >> (i - 1))) == 0)
dayOffset += 29;
else
dayOffset += 30;
}
dayOffset += monthDay;
leapMonth = (LUNAR_INFO[year - MIN_YEAR] & 0xf00000) >> 20;
// 这一年有闰月
if (leapMonth != 0) {
if (month > leapMonth || (month == leapMonth && isLeapMonth)) {
if ((LUNAR_INFO[year - MIN_YEAR] & (0x80000 >> (month - 1))) == 0)
dayOffset += 29;
else
dayOffset += 30;
}
}
if (dayOffset > 366 || (year % 4 != 0 && dayOffset > 365)) {
year += 1;
if (year % 4 == 1)
dayOffset -= 366;
else
dayOffset -= 365;
}
int[] solarInfo = new int[3];
for (i = 1; i < 13; i++) {
int iPos = DAYS_BEFORE_MONTH[i];
if (year % 4 == 0 && i > 2) {
iPos += 1;
}
if (year % 4 == 0 && i == 2 && iPos + 1 == dayOffset) {
solarInfo[1] = i;
solarInfo[2] = dayOffset - 31;
break;
}
if (iPos >= dayOffset) {
solarInfo[1] = i;
iPos = DAYS_BEFORE_MONTH[i - 1];
if (year % 4 == 0 && i > 2) {
iPos += 1;
}
if (dayOffset > iPos)
solarInfo[2] = dayOffset - iPos;
else if (dayOffset == iPos) {
if (year % 4 == 0 && i == 2)
solarInfo[2] = DAYS_BEFORE_MONTH[i] - DAYS_BEFORE_MONTH[i - 1] + 1;
else
solarInfo[2] = DAYS_BEFORE_MONTH[i] - DAYS_BEFORE_MONTH[i - 1];
} else
solarInfo[2] = dayOffset;
break;
}
}
solarInfo[0] = year;
return solarInfo;
}
public static final int[] solarToLunar(int year, int month, int monthDay) {
int[] lunarDate = new int[4];
int index = year - solar_1_1[0];
int data = (year << 9) | (month << 5)
| (monthDay);
int solar11 = 0;
if (solar_1_1[index] > data) {
index--;
}
solar11 = solar_1_1[index];
int y = getBitInt(solar11, 12, 9);
int m = getBitInt(solar11, 4, 5);
int d = getBitInt(solar11, 5, 0);
long offset = solarToInt(year, month,
monthDay) - solarToInt(y, m, d);
int days = lunar_month_days[index];
int leap = getBitInt(days, 4, 13);
int lunarY = index + solar_1_1[0];
int lunarM = 1;
int lunarD = 1;
offset += 1;
for (int i = 0; i < 13; i++) {
int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
if (offset > dm) {
lunarM++;
offset -= dm;
} else {
break;
}
}
lunarD = (int) (offset);
lunarDate[0] = lunarY;
lunarDate[1] = lunarM;
boolean isLeap = false;
if (leap != 0 && lunarM > leap) {
lunarDate[1] = lunarM - 1;
if (lunarM == leap + 1) {
isLeap = true;
}
}
lunarDate[2] = lunarD;
lunarDate[3] = isLeap ? 1 : 0;
//Log.i("----------->",year+"-"+month+"-"+monthDay+"====>"+lunarDate[0]+"-"+lunarDate[1]+"-"+lunarDate[2]+"-"+lunarDate[3]);
return lunarDate;
}*/
/**
* 公历转农历 Solar To Lunar
*
* @param year 公历年
* @param month 公历月
* @param day 公历日
* @return [0]农历年 [1]农历月 [2]农历日 [3]是否闰月 0 false : 1 true
*/
@SuppressWarnings("all")
public static int[] solarToLunar(int year, int month, int day) {
int[] lunarInt = new int[4];
int index = year - solar_1_1[0];
int data = (year << 9) | (month << 5) | (day);
int solar11;
if (solar_1_1[index] > data) {
index--;
}
solar11 = solar_1_1[index];
int y = getBitInt(solar11, 12, 9);
int m = getBitInt(solar11, 4, 5);
int d = getBitInt(solar11, 5, 0);
long offset = solarToInt(year, month, day) - solarToInt(y, m, d);
int days = lunar_month_days[index];
int leap = getBitInt(days, 4, 13);
int lunarY = index + solar_1_1[0];
int lunarM = 1;
int lunarD;
offset += 1;
for (int i = 0; i < 13; i++) {
int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
if (offset > dm) {
lunarM++;
offset -= dm;
} else {
break;
}
}
lunarD = (int) (offset);
lunarInt[0] = lunarY;
lunarInt[1] = lunarM;
lunarInt[3] = 0;
if (leap != 0 && lunarM > leap) {
lunarInt[1] = lunarM - 1;
if (lunarM == leap + 1) {
lunarInt[3] = 1;
}
}
lunarInt[2] = lunarD;
return lunarInt;
}
/**
* 农历转公历
*
* @param lunarYear 农历年
* @param lunarMonth 农历月
* @param lunarDay 农历天
* @param isLeap 是否是闰年 0 false : 1 true
* @return [0]新历年 [1]新历月 [2]新历日 [3]是否闰月 0 false : 1 true
*/
@SuppressWarnings("unused")
public static int[] lunarToSolar(int lunarYear, int lunarMonth, int lunarDay, boolean isLeap) {
int days = lunar_month_days[lunarYear - lunar_month_days[0]];
int leap = getBitInt(days, 4, 13);
int offset = 0;
int loop = leap;
if (!isLeap) {
if (lunarMonth <= leap || leap == 0) {
loop = lunarMonth - 1;
} else {
loop = lunarMonth;
}
}
for (int i = 0; i < loop; i++) {
offset += getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
}
offset += lunarDay;
int solar11 = solar_1_1[lunarYear - solar_1_1[0]];
int y = getBitInt(solar11, 12, 9);
int m = getBitInt(solar11, 4, 5);
int d = getBitInt(solar11, 5, 0);
return solarFromInt(solarToInt(y, m, d) + offset - 1);
}
private static int[] solarFromInt(long g) {
long y = (10000 * g + 14780) / 3652425;
long ddd = g - (365 * y + y / 4 - y / 100 + y / 400);
if (ddd < 0) {
y--;
ddd = g - (365 * y + y / 4 - y / 100 + y / 400);
}
long mi = (100 * ddd + 52) / 3060;
long mm = (mi + 2) % 12 + 1;
y = y + (mi + 2) / 12;
long dd = ddd - (mi * 306 + 5) / 10 + 1;
int[] solar = new int[4];
solar[0] = (int) y;
solar[1] = (int) mm;
solar[2] = (int) dd;
return solar;
}
/**
* 将公历日期转换为农历日期,且标识是否是闰月
*
* @param year
* @param month
* @param monthDay
* @return 返回公历日期对应的农历日期,year0,month1,day2,leap3
* @deprecated 不准确
*/
@Deprecated
public static final int[] solarToLunarDeprecated(int year, int month, int monthDay) {
int[] lunarDate = new int[4];
Date baseDate = new GregorianCalendar(1900, 0, 31).getTime();
Date objDate = new GregorianCalendar(year, month - 1, monthDay).getTime();
int offset = (int) ((objDate.getTime() - baseDate.getTime()) / 86400000L);
// 用offset减去每农历年的天数计算当天是农历第几天
// iYear最终结果是农历的年份, offset是当年的第几天
int iYear, daysOfYear = 0;
for (iYear = MIN_YEAR; iYear <= MAX_YEAR && offset > 0; iYear++) {
daysOfYear = daysInLunarYear(iYear);
offset -= daysOfYear;
}
if (offset < 0) {
offset += daysOfYear;
iYear--;
}
// 农历年份
lunarDate[0] = iYear;
int leapMonth = leapMonth(iYear); // 闰哪个月,1-12
boolean isLeap = false;
// 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
int iMonth, daysOfMonth = 0;
for (iMonth = 1; iMonth <= 13 && offset > 0; iMonth++) {
daysOfMonth = daysInLunarMonth(iYear, iMonth);
offset -= daysOfMonth;
}
// 当前月超过闰月,要校正
if (leapMonth != 0 && iMonth > leapMonth) {
--iMonth;
Log.i("----------->", year + "-" + month + "-" + monthDay + "====>" + iMonth + "-" + leapMonth);
if (iMonth == leapMonth) {
isLeap = true;
}
}
// offset小于0时,也要校正
if (offset < 0) {
offset += daysOfMonth;
--iMonth;
}
lunarDate[1] = iMonth;
lunarDate[2] = offset + 1;
lunarDate[3] = isLeap ? 1 : 0;
//Log.i("----------->",year+"-"+month+"-"+monthDay+"====>"+lunarDate[0]+"-"+lunarDate[1]+"-"+lunarDate[2]+"-"+lunarDate[3]);
return lunarDate;
}
/**
* 传回农历year年month月的总天数
*
* @param year 要计算的年份
* @param month 要计算的月
* @return 传回天数
*/
final public static int daysInMonth(int year, int month) {
return daysInMonth(year, month, false);
}
/**
* 传回农历year年month月的总天数
*
* @param year 要计算的年份
* @param month 要计算的月
* @param leap 当月是否是闰月
* @return 传回天数,如果闰月是错误的,返回0.
*/
public static final int daysInMonth(int year, int month, boolean leap) {
int leapMonth = leapMonth(year);
int offset = 0;
// 如果本年有闰月且month大于闰月时,需要校正
if (leapMonth != 0 && month > leapMonth) {
offset = 1;
}
// 不考虑闰月
if (!leap) {
return daysInLunarMonth(year, month + offset);
} else {
// 传入的闰月是正确的月份
if (leapMonth != 0 && leapMonth == month) {
return daysInLunarMonth(year, month + 1);
}
}
return 0;
}
/**
* 传回农历 year年的总天数
*
* @param year 将要计算的年份
* @return 返回传入年份的总天数
*/
private static int daysInLunarYear(int year) {
int i, sum = 348;
if (leapMonth(year) != 0) {
sum = 377;
}
int monthInfo = LUNAR_INFO[year - MIN_YEAR] & 0x0FFF80;
for (i = 0x80000; i > 0x7; i >>= 1) {
if ((monthInfo & i) != 0)
sum += 1;
}
return sum;
}
/**
* 传回农历 year年month月的总天数,总共有13个月包括闰月
*
* @param year 将要计算的年份
* @param month 将要计算的月份
* @return 传回农历 year年month月的总天数
*/
private static int daysInLunarMonth(int year, int month) {
if ((LUNAR_INFO[year - MIN_YEAR] & (0x100000 >> month)) == 0)
return 29;
else
return 30;
}
/**
* 传回农历 year年闰哪个月 1-12 , 没闰传回 0
*
* @param year 将要计算的年份
* @return 传回农历 year年闰哪个月1-12, 没闰传回 0
*/
public static int leapMonth(int year) {
return (int) ((LUNAR_INFO[year - MIN_YEAR] & 0xF00000)) >> 20;
}
private static int getBitInt(int data, int length, int shift) {
return (data & (((1 << length) - 1) << shift)) >> shift;
}
private static long solarToInt(int y, int m, int d) {
m = (m + 9) % 12;
y = y - m / 10;
return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10
+ (d - 1);
}
}