import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;public class ChinaDate {// private static final Logger logger = LoggerFactory.getLogger(CalendarUtil.class);// 计算阴历日期参照1900年到2049年private final static int[] LUNAR_INFO = {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};// 允许输入的最小年份private final static int MIN_YEAR = 1900;// 允许输入的最大年份private final static int MAX_YEAR = 2049;// 当年是否有闰月private static boolean isLeapYear;// 阳历日期计算起点private final static String START_DATE = "1900-01-30";/*** 计算阴历 {@code year}年闰哪个月 1-12 , 没闰传回 0* @param year 阴历年* @return (int)月份*/private static int getLeapMonth(int year) {return (int) (LUNAR_INFO[year - 1900] & 0xf);}/*** 计算阴历{@code year}年闰月多少天* @param year 阴历年* @return (int)天数*/private static int getLeapMonthDays(int year) {if(getLeapMonth(year)!=0){if((LUNAR_INFO[year - 1900] & 0xf0000)==0){return 29;}else {return 30;}}else{return 0;}}/*** 计算阴历{@code lunarYeay}年{@code month}月的天数* @param lunarYeay 阴历年* @param month 阴历月* @return (int)该月天数* @throws Exception*/private static int getMonthDays(int lunarYeay, int month) throws Exception {if ((month > 31) || (month < 0)) {throw(new Exception("月份有错!"));}// 0X0FFFF[0000 {1111 1111 1111} 1111]中间12位代表12个月,1为大月,0为小月int bit = 1 << (16-month);if(((LUNAR_INFO[lunarYeay - 1900] & 0x0FFFF)&bit)==0){return 29;}else {return 30;}}/*** 计算阴历{@code year}年的总天数* @param year 阴历年* @return (int)总天数*/private static int getYearDays(int year) {int sum = 29*12;for(int i=0x8000;i>=0x8;i>>=1){if((LUNAR_INFO[year-1900]&0xfff0&i)!=0){sum++;}}return sum+getLeapMonthDays(year);}/*** 计算两个阳历日期相差的天数。计算不准确,已经废弃* @param startDate 开始时间* @param endDate 截至时间* @return (int)天数*/@Deprecatedprivate static int daysBetween2(Date startDate, Date endDate) {long between_days=(endDate.getTime()-startDate.getTime())/(1000*3600*24);return Integer.parseInt(String.valueOf(between_days));}/*** 计算两个阳历日期相差的天数。* @param startDate 开始时间* @param endDate 截至时间* @return (int)天数*/private static int daysBetween(Date startDate, Date endDate) {int days = 0;//将转换的两个时间对象转换成Calendar对象Calendar can1 = Calendar.getInstance();can1.setTime(startDate);Calendar can2 = Calendar.getInstance();can2.setTime(endDate);//拿出两个年份int year1 = can1.get(Calendar.YEAR);int year2 = can2.get(Calendar.YEAR);//天数Calendar can = null;//如果can1 < can2//减去小的时间在这一年已经过了的天数//加上大的时间已过的天数if(can1.before(can2)){days -= can1.get(Calendar.DAY_OF_YEAR);days += can2.get(Calendar.DAY_OF_YEAR);can = can1;}else{days -= can2.get(Calendar.DAY_OF_YEAR);days += can1.get(Calendar.DAY_OF_YEAR);can = can2;}for (int i = 0; i < Math.abs(year2-year1); i++) {//获取小的时间当前年的总天数days += can.getActualMaximum(Calendar.DAY_OF_YEAR);//再计算下一年。can.add(Calendar.YEAR, 1);}return days;}/*** 检查阴历日期是否合法* @param lunarYear 阴历年* @param lunarMonth 阴历月* @param lunarDay 阴历日* @param leapMonthFlag 闰月标志* @throws Exception*/private static void checkLunarDate(int lunarYear, int lunarMonth, int lunarDay, boolean leapMonthFlag) throws Exception {if ((lunarYear < MIN_YEAR) || (lunarYear > MAX_YEAR)) {throw(new Exception("非法农历年份!"));}if ((lunarMonth < 1) || (lunarMonth > 12)) {throw(new Exception("非法农历月份!"));}if ((lunarDay < 1) || (lunarDay > 30)) { // 中国的月最多30天throw(new Exception("非法农历天数!"));}int leap = getLeapMonth(lunarYear);// 计算该年应该闰哪个月if ((leapMonthFlag == true) && (lunarMonth != leap)) {throw(new Exception("非法闰月!"));}}/*** 阴历转换为阳历* @param lunarDate 阴历日期,格式YYYYMMDD* @param leapMonthFlag 是否为闰月* @return 阳历日期,格式:YYYYMMDD* @throws Exception*/public static String lunarToSolar(String lunarDate, boolean leapMonthFlag) throws Exception{int lunarYear = Integer.parseInt(lunarDate.substring(0, 4));int lunarMonth = Integer.parseInt(lunarDate.substring(4, 6));int lunarDay = Integer.parseInt(lunarDate.substring(6, 8));checkLunarDate(lunarYear, lunarMonth, lunarDay, leapMonthFlag);int offset = 0;for (int i = MIN_YEAR; i < lunarYear; i++) {int yearDaysCount = getYearDays(i); // 求阴历某年天数offset += yearDaysCount;}//计算该年闰几月int leapMonth = getLeapMonth(lunarYear);if(leapMonthFlag & leapMonth != lunarMonth){throw(new Exception("您输入的闰月标志有误!"));}//当年没有闰月或月份早于闰月或和闰月同名的月份if(leapMonth==0|| (lunarMonth < leapMonth) || (lunarMonth==leapMonth && !leapMonthFlag)){for (int i = 1; i < lunarMonth; i++) {int tempMonthDaysCount = getMonthDays(lunarYear, i);offset += tempMonthDaysCount;}// 检查日期是否大于最大天if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {throw(new Exception("不合法的农历日期!"));}offset += lunarDay; // 加上当月的天数}else{//当年有闰月,且月份晚于或等于闰月for (int i = 1; i < lunarMonth; i++) {int tempMonthDaysCount = getMonthDays(lunarYear, i);offset += tempMonthDaysCount;}if (lunarMonth>leapMonth) {int temp = getLeapMonthDays(lunarYear); // 计算闰月天数offset += temp; // 加上闰月天数if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {throw(new Exception("不合法的农历日期!"));}offset += lunarDay;}else {    // 如果需要计算的是闰月,则应首先加上与闰月对应的普通月的天数// 计算月为闰月int temp = getMonthDays(lunarYear, lunarMonth); // 计算非闰月天数offset += temp;if (lunarDay > getLeapMonthDays(lunarYear)) {throw(new Exception("不合法的农历日期!"));}offset += lunarDay;}}SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");Date myDate = null;myDate = formatter.parse(START_DATE);Calendar c = Calendar.getInstance();c.setTime(myDate);c.add(Calendar.DATE, offset);myDate = c.getTime();return formatter.format(myDate);}/*** 阳历日期转换为阴历日期* @param solarDate 阳历日期,格式YYYYMMDD* @return 阴历日期* @throws Exception*/public static String solarToLunar(String solarDate, Boolean isFormat) throws Exception{int i;int temp = 0;int lunarYear;int lunarMonth; //农历月份int lunarDay; //农历当月第几天boolean leapMonthFlag =false;SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");Date myDate = null;Date startDate = null;try {myDate = formatter.parse(solarDate);startDate = formatter.parse(START_DATE);} catch (ParseException e) {e.printStackTrace();}int offset = daysBetween(startDate,myDate);for (i = MIN_YEAR; i <= MAX_YEAR; i++){temp = getYearDays(i);  //求当年农历年天数if (offset - temp < 1){break;}else{offset -= temp;}}lunarYear = i;int leapMonth = getLeapMonth(lunarYear);//计算该年闰哪个月//设定当年是否有闰月if (leapMonth > 0){isLeapYear = true;}else{isLeapYear = false;}for (i = 1;  i<=12; i++) {if(i==leapMonth+1 && isLeapYear){temp = getLeapMonthDays(lunarYear);isLeapYear = false;leapMonthFlag = true;i--;}else{temp = getMonthDays(lunarYear, i);}offset -= temp;if(offset<=0){break;}}offset += temp;lunarMonth = i;lunarDay = offset;if(isFormat)return "阴历:"+lunarYear+"年"+(leapMonthFlag&(lunarMonth==leapMonth)?"闰":"")+lunarMonth+"月"+lunarDay+"日";return "" + lunarYear + lunarMonth + lunarDay;}public static void main(String[] args) throws Exception {System.out.println(ChinaDate.lunarToSolar("1990-12-04", false));System.out.println(ChinaDate.lunarToSolar("1984-10-21", true));System.out.println(ChinaDate.lunarToSolar("1990-12-25", false));System.out.println("************");System.out.println(ChinaDate.solarToLunar("1900-09-23", true));System.out.println(ChinaDate.solarToLunar("1900-09-24", true));System.out.println(ChinaDate.solarToLunar("1900-10-22", true));System.out.println(ChinaDate.solarToLunar("1900-10-23", true));System.out.println(ChinaDate.solarToLunar("1991-02-09", true));System.out.println(ChinaDate.solarToLunar("1990-06-30", true));System.out.println(ChinaDate.solarToLunar("1984-12-13", true));System.out.println(ChinaDate.solarToLunar("1991-01-19", true));}
}

阴历日期和阳历日期互相转换(java)相关推荐

  1. java 获取阴历日期公历日期转农历日期或者阳历日期转阴历日期

    背景 项目中需要获取农历日期,展示在页面,不使用第三方工具类的情况下,直接使用原生的java api工具类开发 代码如下 package com.hidata.devops.paas;import j ...

  2. java 公历 农历_java已知阳历日期求对应阴历日期源代码

    import java.text.*; import java.util.*; class ChineseCalendarGB { private int gregorianYear; private ...

  3. solarlunar库, 阴历,阳历日期及转换库

    阴历日期,阳历日期,阴历阳历转换库. 没时间写中文了,直接复制库文件里面的,见量.... 1. solar calendar interface:    date range: any date... ...

  4. 阴历转阳历java_GitHub - opprime/calendarist: 一个可实现阳历、阴历、干支历间相互转换的JAVA工具...

    历法计算家,可实现阳历.阴历.干支历的相互转换 使用方法 Maven引用 org.hothub calendarist 1.0.7 功能介绍 支持1900 - 2100年份的日期转换 支持阳历日期转阴 ...

  5. java中M格式_Java中Date日期字符串格式的各种转换

    编程语言 Java中Date日期字符串格式的各种转换 字号+ 作者:小虾米 2017-04-21 08:51 以下程序源码都是从网络上整理之后,才发到本网站的,新手请收藏啊! public class ...

  6. python实现农历和阳历日期转换

    需安装sxtwl包,命令如下 pip install sxtwl 农历(Lunar calendar)<->阳历(solar calendar)转换 代码如下(基于python3): im ...

  7. java 农历节日 转公历日期_公历农历互相转换的Java日历工具类

    /** * 工具类,实现公农历互转 */ public class LunarCalendar { /** * 支持转换的最小农历年份 */ public static final int MIN_Y ...

  8. java utc 转换pst_关于c#:如何将UTC + 0日期转换为PST日期?

    我有这个UTC+0日期: 2011-11-28T07:21:41.000Z 我想在C上把它转换成一个PST日期.我该怎么做?尝试: object.Data.ToLocalTime() 但是我不能得到正 ...

  9. java阳历农历互相转换

    package fhj.help; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...

  10. 公元元年之后的天数与日期之间的相互转换 阳历日期转农历

    前几天,有个同事问:知道现在距离公元元年1月1日的天数,如何计算日期?此前对闰年的概念也不是很清晰,在网上查了下闰年规则,整理出一个日期转换类,贴出来和大家分享,不足之处还请多多指教! 先说下闰年规则 ...

最新文章

  1. 读“深度学习在图像处理领域中的应用综述”有感
  2. 拍个自拍,让Python告诉你,军训过后你黑了几度?
  3. nefu java作业2020.3.11第二章
  4. python各种数据类型的常用方法_python的基本数据类型:列表的方法
  5. [xsy3343]程序锁
  6. 【渝粤教育】国家开放大学2018年秋季 1317T社会工作行政(本) 参考试题
  7. php更多式样,php_1
  8. 打造超酷的PHP数据饼图
  9. node sqlite 插入数据_方便且实用,Python内置的轻量级数据库实操
  10. 将apache的htaccess转换为nginx的重写规则
  11. 【VS2010学习笔记】【函数学习】二(SetTimer()函数)
  12. 常见测试用例设计方法1---等价类划分
  13. 关于一张 5 亿数据表之我与 DBA 的 battle
  14. 梁德伟-唯品会物流信息部技术部应用架构实践总结
  15. day03-文字效果标签及特殊符号
  16. mysql升级8.0后,项目遇到的坑
  17. 医院门诊透视的生活万花筒
  18. 【转】WPF自定义控件与样式(13)-自定义窗体Window 自适应内容大小消息框MessageBox...
  19. 2020社会热点问题及看法_翁源县2020年食品安全宣传周正式启动!
  20. Vue中怎么加载pdf文件

热门文章

  1. aras innovator: 分类筛选如何做?
  2. 图解网络(一)——计算机网络基础
  3. 数据结构——学期总结
  4. 碧蓝航线服务器维护到几点,碧蓝航线9月26日更新官方公告及内容汇总 维护到几点 碧蓝航线什么时候能玩_蚕豆网新闻...
  5. 2021-2025年中国休闲凉鞋行业市场供需与战略研究报告
  6. OK6410A 之 SPI 驱动 测试 步骤
  7. dva 路由/导航/
  8. 爱荷华州立大学计算机学院,享誉全美的祖父级大学——爱荷华州立大学(ISU)...
  9. 游戏模型与动漫之间,有多大差距?
  10. P2P软件工作原理是什么?