关于债券付息的一些日期计算方式
来源:互联网 发布:福利app软件 编辑:程序博客网 时间:2024/05/06 07:17
最近在二期开发的时候 碰到的主要难点是债券付息兑付计划制定的业务问题 开发过程中涉及的许多算法
初步完成的代码中涉及到很多日期的特殊计算 记录下来做金融项目的时候可以作为参考 因为进度很急代码没有重构 只是为了未完成功能的第一阶段的代码
—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——
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;}
- 关于债券付息的一些日期计算方式
- 关于国债的一些计算: 理论TF价格1(缴款日前无付息)
- 关于国债的一些计算: 理论TF价格2(缴款日前有付息)
- 债券的收益率计算
- 返回某个日期点的付息现金
- 关于日期计算的一些辅助函数
- Java中一些关于日期、日期格式、日期的解析和日期的计算[转贴]
- Java中一些关于日期、日期格式、日期的解析和日期的计算
- Java中一些关于日期、日期格式、日期的解析和日期的计算
- Java中一些关于日期、日期格式、日期的解析和日期的计算
- Java中一些关于日期、日期格式、日期的解析和日期的计算
- Java中一些关于日期、日期格式、日期的解析和日期的计算
- Java中一些关于日期、日期格式、日期的解析和日期的计算
- 关于日期的计算
- 关于投资的一些名词解释—股票,债券,基金,一级市场,二级市场
- 关于日期计算的问题
- 关于日期计算的问题
- 一些关于日期的操作
- Hyper-V故障转移群集
- ViewPager设计总体思路
- 清理缓存
- Java-类执行顺序(面向对像编程思想)
- 实习入职第九天:Attempt to call getDuration without a valid mediaplayer
- 关于债券付息的一些日期计算方式
- MongoDB的学习(二)-基本的操作
- 1.读懂tornado的预备知识:什么是epoll
- 关于Pointcut Joinpoint Advice Advisor的理解
- 有参数构造函数的调用
- 数据结构—二叉树层次遍历
- 基于springMVC的文件上传-图片
- 设计模式06_装饰者模式
- 阿里云CentOS7 Samba安装