当前位置: > 债券>正文

关于债券付息的一些日期计算方式

2023-07-17 09:39:05 互联网 未知 债券

关于债券付息的一些日期计算方式

最近在二期开发的时候 碰到的主要难点是债券付息兑付计划制定的业务问题  开发过程中涉及的许多算法

初步完成的代码中涉及到很多日期的特殊计算   记录下来做金融项目的时候可以作为参考   因为进度很急代码没有重构 只是为了未完成功能的第一阶段的代码

—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——

1.(1)业务场景

付息频率为 月/次 为单位   能拿到字段 起息日  到期日  需要计算出中间所有的付息兑付计划日期

(2)主要问题:

1>如果起息日为某月31号 遇到没有31号的月份需要取30号   

2>如果起息日为30号 或者29号 遇到平年2月份需要取28号

(3)算法分析:

按照付息频率 拿到每个付息月份可以用calendar类自带加法运算月份的方法 add(int field, int amount) ( 此方法取到的日期  假如起息日为某月30日  如果下一个计息月为2月 会给你自动取到最后一天28日  那么在for循环中再往下计算会都取到计息月份的28号)

calendar类自带可以取到一个月最后一天的方法 那么若是31号 则取到当月的最后一天

如果是30号或者29号 按照add方法计算出所有计息日期放入list  然后遍历list 将不是二月份的日期全部替换成30号或29号

(4)代码

// 获得所有付息日期private List awardInteDate(Long d1, Long d2,Long frequency) throws ParseException,java.text.ParseException {String str = d1.toString();List list = new ArrayList();//getMonthSpace()获得两个日期之间的月份数量for (int i = 0; i < InfordInteCalculateLogic.getMonthSpace(d1.toString(), d2.toString()) / frequency; i++) {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");Date date = sdf.parse(str);Calendar ins = Calendar.getInstance();ins.setTime(date);ins.add(Calendar.MONTH,frequency.intValue());//yyyyMMdd格式的日期 取到日String s = d1.toString().substring(str.length() - 2, str.length());if ("31".equals(s)) {//如果是31号 取每个月最后一天 ins.set(Calendar.DATE, ins.getActualMaximum(Calendar.DATE));str = sdf.format(ins.getTime()).toString();list.add(str);}else {str = sdf.format(ins.getTime()).toString();list.add(str);}}String ss = d1.toString().substring(str.length() - 2, str.length());//如果是30号 将list中除了2月份之外所有月份的日改为30号if ("30".equals(ss)) {for (int i = 0; i < list.size(); i++) {String str1 = list.get(i);if (!"02".equals(str1.substring(4, 6))) {StringBuilder builder = new StringBuilder(str1);builder.replace(6, 8, "30");str1 = builder.toString();list.set(i, str1);}}}if ("29".equals(ss)) {for (int i = 0; i < list.size(); i++) {String str1 = list.get(i);if (!"02".equals(str1.substring(4, 6))) {StringBuilder builder = new StringBuilder(str1);builder.replace(6, 8, "29");str1 = builder.toString();list.set(i, str1);}}}return list; // 计算两个日期之间月份数方法public static int getMonthSpace(String date1, String date2) throws ParseException,java.text.ParseException {int result = 0;SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");Calendar c1 = Calendar.getInstance();Calendar c2 = Calendar.getInstance();c1.setTime(sdf.parse(date1));c2.setTime(sdf.parse(date2));result = (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR)) * 12+ (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH));return result == 0 ? 1 : Math.abs(result);}

—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——

2.(1)业务场景

1>非闰年计息年度确定

按照产品本身的生命周期确定其计息年度。如某附息债权融资计划,5年期,每三个月付息一次,起息日为2016年4月20日,则2016年7月20日为第一个付息日,2016年10月20日为第二个付息日,那么2016年4月20日——2017年4月20日(利息计算算头不算尾,下同)为该产品的第一个完整计息年度,该产品共5个计息年度。

2>闰年计息年度确定

    闰年计息年度确定,以其一个完整的计息年度内是否跨越闰年中的2月29日为标准。仍以前款所举产品为例,因2023年2月处于该产品的2023年4月20日至2023年4月20日这一计息年度内,所以该计息年度为闰年计息年度。因此,2023年在自然年度上虽不是闰年,但第四个计息期(2023年1月20日——2023年4月20日)因属于该产品2023年4月20日——2023年4月20日这一计息年度,所以应按闰年处理。而2023年虽然是在自然年度上是闰年,但其第五个计息年度(2023年4月20日——2023年4月20日)不是闰年计息年度,仍按非闰年处理。

(2)算法分析:

拿到 2个如期间所有的闰年 如果起息日是一个2月29号之后的时间 那么拼接前一年和当年为计息年度横跨的2年 将这两个年度放入数组  

如果是一个2月29号之前的日期  那么拼接当年和后一年为计息年度横跨的2年 将这两个年度放入数组  

如果付息计划时间 在这个数组list中任意一个数组中的两个时间跨度之内 那么代表在闰年计息年度中 flag+1 标记为闰年计息年度

(3)代码

//判断是否为闰年计息年度方法private int judgeLeapYearStyle(String date,String begin,String end){int i;List list=new ArrayList();List arrList=new ArrayList();for(i=Integer.parseInt(begin.substring(0, 4));i=229){for (Integer integer : list) {String d1=String.valueOf(integer-1)+"0"+monthDay;String d2=String.valueOf(integer)+"0"+monthDay;String[] arr = new String []{d1,d2};arrList.add(arr);}}else{for (Integer integer : list) {String d1=String.valueOf(integer)+"0"+monthDay;String d2=String.valueOf(integer+1)+"0"+monthDay;String[] arr = new String []{d1,d2};arrList.add(arr);}}}else{monthDay=begin.substring(4, 8);if(Integer.parseInt(monthDay)>=229){for (Integer integer : list) {String d1=String.valueOf(integer-1)+monthDay;String d2=String.valueOf(integer)+monthDay;String[] arr = new String []{d1,d2};arrList.add(arr);}}else{for (Integer integer : list) {String d1=String.valueOf(integer)+"0"+monthDay;String d2=String.valueOf(integer+1)+"0"+monthDay;String[] arr = new String []{d1,d2};arrList.add(arr);}}}int flag = 0;for (String[] strings : arrList) {if(Integer.parseInt(date)>=Integer.parseInt(strings[0]) && Integer.parseInt(date)

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。