Oracle函数MONTHS_BETWEEN的作用以及java翻译

使用格式:MONTHS_BETWEEN(DATE1,DATE2) 即MONTHS_BETWEEN(日期1,日期2)

场景应用:计算两个时间相差的月份差

下面给一些sql以及相应的执行结果:

 select months_between(to_date('20100529', 'yyyymmdd'), to_date('20100228', 'yyyymmdd')) as months from dual
 union all
  select months_between(to_date('20100531', 'yyyymmdd'), to_date('20100228', 'yyyymmdd')) as months from dual
  union all
select months_between(to_date('20100528', 'yyyymmdd'), to_date('20100228', 'yyyymmdd')) as months from dual;
3.03225806451613
3
3

这完全不符合常规思维的理解,查阅了资料大致的理解了下:

函数返回两个日期之间的月份数。如果两个日期月份内天数相同,或者都是某个月的最后一天,返回一个整数,否则,返回数值带小数,以每天1/31月来计算月中剩余天数。如果日期1比日期2小 ,返回值为负数。---呵呵呵呵~~~

那就是说只要两个月份的总天数存在差异,就会出现月份差先变大后变小的情况。这绝对是这个函数的逻辑问题!!!

但是没办法,前辈们偷懒直接用函数计算的,导致现在必须遵循这种逻辑。

 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
 
public class Test {
 
	public static void main(String[] args) {
		// Integer a = 10;
		// BigDecimal b = new BigDecimal(10.1);
		// BigDecimal c = new BigDecimal(a + 0.1);
		//
		// System.out.println("a:" + a + "///" + "b:" + b + "///" + "c:" + c);
		// System.out.println(b.toString());
 
		String str1 = "20110330000000";// 20110330000000 20110330000000
		String str2 = "20100130000000";// 20150228215906
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		try {
			System.out.println(sdf.parse(str1));
			System.out.println(sdf.parse(str2));
			System.out.println(months_Between(sdf.parse(str1), sdf.parse(str2)));
		} catch (ParseException e) {
			e.printStackTrace();
		}
 
	}
 
	public static double months_Between(Date oldDate, Date newDate) {
		Calendar old_date = Calendar.getInstance();
		Calendar new_date = Calendar.getInstance();
		old_date.setTime(oldDate);
		new_date.setTime(newDate);
		double month;
 
		int year = old_date.get(Calendar.YEAR) - new_date.get(Calendar.YEAR);
		// 兼容日期大小与参数位置对结果的影响
		if (year < 0) {
			year = -year;
			month = year * 12 - calMonthAndDay(old_date, new_date);
		} else {
			month = year * 12 + calMonthAndDay(old_date, new_date);
		}
		// 判断输入的两个日期是不是在同一年
		// if(oldYear!=newYear){
		// month = calMonthAndDay(old_date,new_date)+((oldYear-newYear)*12);
		// }else{
		// month = calMonthAndDay(old_date,new_date);
		// }
		return month;
	}
 
	public static double calMonthAndDay(Calendar old_date, Calendar new_date) {
		double month;
 
		// 在同一年只用处理月份和天数
		// 说明两个日期都是在当月的最后一天只用处理月份
		System.out.println(
				"old_date.getActualMaximum(Calendar.DAY_OF_MONTH)" + old_date.getActualMaximum(Calendar.DAY_OF_MONTH));
		System.out.println("old_date.get(Calendar.MONTH)" + old_date.get(Calendar.DAY_OF_MONTH));
		System.out.println(
				"new_date.getActualMaximum(Calendar.DAY_OF_MONTH)" + new_date.getActualMaximum(Calendar.DAY_OF_MONTH));
		System.out.println("new_date.get(Calendar.MONTH)" + new_date.get(Calendar.DAY_OF_MONTH));
		if (old_date.getActualMaximum(Calendar.DAY_OF_MONTH) == old_date.get(Calendar.DAY_OF_MONTH)
				&& new_date.getActualMaximum(Calendar.DAY_OF_MONTH) == new_date.get(Calendar.DAY_OF_MONTH)) {
			month = old_date.get(Calendar.MONTH) - new_date.get(Calendar.MONTH);
		}
		// 两个日期同天
		else if (old_date.get(Calendar.DAY_OF_MONTH) == new_date.get(Calendar.DAY_OF_MONTH)) {
			month = old_date.get(Calendar.MONTH) - new_date.get(Calendar.MONTH);
		} else {
			double day = old_date.get(Calendar.DAY_OF_MONTH) - new_date.get(Calendar.DAY_OF_MONTH);
			month = old_date.get(Calendar.MONTH) - new_date.get(Calendar.MONTH) + day / 31;
		}
		return month;
	}
}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值