码迷,mamicode.com
首页 > 其他好文 > 详细

债券付息日和兑付日计算

时间:2016-08-15 19:03:39      阅读:390      评论:0      收藏:0      [点我收藏+]

标签:

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<String> awardInteDate(Long d1, Long d2,Long frequency) throws ParseException,  
            java.text.ParseException {  
        String str = d1.toString();  
        List<String> list = new ArrayList<String>();  
        //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日为标准。仍以前款所举产品为例,因2020年2月处于该产品的2019年4月20 日至2020年4月20日这一计息年度内,所以该计息年度为闰年计息年度。因此,2019年在自然年度上虽不是闰年,但第四个计息期(2020年1月20 日——2020年4月20日)因属于该产品2019年4月20日——2020年4月20日这一计息年度,所以应按闰年处理。而2020年虽然是在自然年度 上是闰年,但其第五个计息年度(2020年4月20日——2021年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<Integer> list=new  ArrayList<Integer>();  
        List<String []> arrList=new  ArrayList<String []>();  
        for(i=Integer.parseInt(begin.substring(0, 4));i<=Integer.parseInt(end.substring(0, 4));i++){  
          if((i%4==0&&i%100!=0)||(i%400==0)) {  
              list.add(i);  
          }  
        }  
        // 拿到 2个如期间所有的闰年 如果起息日是一个2月29号之后的时间 那么拼接前一年和当年为计息年度横跨的2年 将这两个年度放入数组  
        // 如果是一个2月29号之前的日期  那么拼接当年和后一年为计息年度横跨的2年 将这两个年度放入数组     
        // 如果付息计划时间 在这个数组list中任意一个数组中的两个时间跨度之内 那么代表在闰年计息年度中 flag+1 标记为闰年计息年度  
        String monthDay;  
        if("0".equals(begin.substring(4, 5))){  
            monthDay=begin.substring(5, 8);  
            if(Integer.parseInt(monthDay)>=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)<=Integer.parseInt(strings[1])){  
                flag+=1;  
            }  
        }  
        return flag;  
    }  

 


浮息债的算法 计算方式会比这还要复杂很多。

债券付息日和兑付日计算

标签:

原文地址:http://www.cnblogs.com/zhouwp/p/5773795.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!