YearFrac函数Java版实现(完整版)
YEARFRAC 可计算两个日期(start_date 和 end_date)之间的天数(取整天数)占一年的比例。 例如,可使用 YEARFRAC 确定某一特定条件下全年效益或债务的比例。
语法
YEARFRAC(start_date, end_date, [basis])
YEARFRAC 函数语法具有下列参数:
◾ Start_date 必需。 一个代表开始日期的日期。
◾ End_date 必需。 一个代表终止日期的日期。
◾ Basis 可选。 要使用的日计数基准类型。
Basis 日计数基准
0 或省略 US (NASD) 30/360
1 实际/实际
2 实际/360
3 实际/365
4 欧洲 30/360
重要:
◾应使用 DATE 函数输入日期,或者将日期作为其他公式或函数的结果输入。 例如,使用函数 DATE(2018,5,23) 输入 2018 年 5 月 23 日。 如果日期以文本形式输入,则会出现问题。
◾如果使用 US (NASD) 30/360 基准,且 start_date 是二月的最后一天,则 YEARFRAC 函数可能会返回错误的结果。
备注
◾Excel 将日期存储为可用于计算的序列号。 默认情况下,1900 年 1 月 1 日的序列号是 1,而 2018 年 1 月 1 日的序列号是 43101,这是因为它距 1900 年 1 月 1 日有 43101 天。
◾所有参数都将被截尾取整。
◾如果 start_date 或 end_date 不是有效日期,YEARFRAC 会返回错误值 #VALUE! 。
◾如果 basis < 0 或 basis > 4,函数 YEARFRAC 会返回错误值 #NUM!。 。
JAVA版本的实现参考了以下资料:
1、https://lists.oasis-open.org/archives/office-formula/200806/msg00039.html
2、https://stackoverflow.com/questions/43355292/replicating-yearfrac-function-from-excel-in-python
3、https://support.microsoft.com/zh-cn/office/yearfrac-%E5%87%BD%E6%95%B0-3844141e-c76d-4143-82b6-208454ddc6a8?ns=excel&version=90&ui=zh-cn&rs=zh-cn&ad=cn
参照vba的实现逻辑,实现了java版本,仅供参考。
import cn.hutool.core.date.DateUtil;import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;public class YearFracFunction {private static final Integer BIG_MONTH [] = {1 ,3 ,5 ,7 ,8 ,10 ,12 };private static final Integer SMALL_MONTH [] = {4 ,6 ,9 ,11 };/**** 是否闰年* @param year* @return*/public static boolean isLeapYear(Integer year) {return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;}/**** 判断是否是当前月份最后一天* @param day* @param month* @param year* @return*/public static boolean isEndOfMonth(Integer day, Integer month, Integer year) {for (Integer x : BIG_MONTH) {if( x.equals(month)) {return day == 31;}}for (Integer y : SMALL_MONTH) {if( y.equals(month)) {return day == 30;}}if( isLeapYear(year)) {return day == 29;}return day == 28;}/**** 360天情况下天数的计算方式* @param startYear* @param endYear* @param startMonth* @param endMonth* @param startDay* @param endDay* @return*/public static Long days360(Integer startYear, Integer endYear, Integer startMonth, Integer endMonth, Integer startDay, Integer endDay) {return (endYear - startYear) * 360 + (endMonth - startMonth) * 30 + (endDay - startDay) *1L ;}public static Long tmpdays360Nasd(Date startDate, Date endDate, Integer method, Boolean useEom ) {Integer StartDay = DateUtil.dayOfMonth(startDate) ;Integer StartMonth = DateUtil.month(startDate) ;Integer StartYear = DateUtil.year(startDate) ;Integer EndDay = DateUtil.dayOfMonth(endDate) ;Integer EndMonth = DateUtil.month(endDate) ;Integer EndYear = DateUtil.year(endDate) ;if( (EndMonth == 2 && isEndOfMonth(EndDay, EndMonth, EndYear)) &&( (StartMonth == 2 && isEndOfMonth(StartDay, StartMonth, StartYear)) || method == 3) ){EndDay = 30 ;}if( EndDay == 31 && (StartDay >= 30 || method == 3) ) {EndDay = 30 ;}if( StartDay == 31 ) {StartDay = 30 ;}if( useEom && StartMonth == 2 && isEndOfMonth(StartDay, StartMonth, StartYear) ) {StartDay = 30 ;}return days360(StartYear, EndYear, StartMonth, EndMonth, StartDay, EndDay) ;}public static Long tmpdays360Euro(Date startDate, Date endDate) {Integer StartDay = DateUtil.dayOfMonth(startDate) ;Integer StartMonth = DateUtil.month(startDate) ;Integer StartYear = DateUtil.year(startDate) ;Integer EndDay = DateUtil.dayOfMonth(endDate) ;Integer EndMonth = DateUtil.month(endDate) ;Integer EndYear = DateUtil.year(endDate) ;if( StartDay == 31) {StartDay = 30 ;}if( EndDay == 31) {EndDay = 30 ;}return days360(StartYear, EndYear, StartMonth, EndMonth, StartDay, EndDay) ;}public static Long tmpDiffDates(Date startDate, Date endDate, Integer Basis) {Long tmpDiffDates = 0L ;switch( Basis) {case 0 : //'atpmBasis30360tmpDiffDates = tmpdays360Nasd(startDate, endDate, 0, true) ;break;case 1 :case 2:case 3 : //'atpmBasisActual atpmBasisActual360 atpmBasisActual365 -- use actual count of daystmpDiffDates = DateUtil.betweenDay( startDate, endDate ,true) ;break;case 4 : //'atpmBasisE30360tmpDiffDates = tmpdays360Euro(startDate, endDate) ;break;}return tmpDiffDates ;}public static Double tmpCalcAnnualBasis(Date startDate, Date endDate,Integer Basis ) {Integer StartDay = 0 ;Integer StartMonth= 0 ;Integer StartYear= 0 ;Integer EndDay= 0 ;Integer EndMonth= 0 ;Integer EndYear= 0 ;Integer iYear = 0 ;Double tmpCalcAnnualBasis = 0.0 ;switch ( Basis) {case 0:case 2:case 4: // 'atpmBasis30360 atpmBasisActual360 atpmBasisE30360tmpCalcAnnualBasis = 360.0 ;break;case 3: // 'atpmBasisActual365tmpCalcAnnualBasis = 365.0 ;break;case 1: // ' atpmBasisActualStartDay = DateUtil.dayOfMonth(startDate) ;StartMonth = DateUtil.month(startDate) ;StartYear = DateUtil.year(startDate) ;EndDay = DateUtil.dayOfMonth(endDate) ;EndMonth = DateUtil.month(endDate) ;EndYear = DateUtil.year(endDate) ;if(StartYear == EndYear) {if(isLeapYear(StartYear)){tmpCalcAnnualBasis = 366.0 ;}else{tmpCalcAnnualBasis = 365.0 ;}}else if ( EndYear - 1 == StartYear&& ( (StartMonth > EndMonth) || ( (StartMonth == EndMonth) && StartDay >= EndDay) ) ) {if ( isLeapYear (StartYear) ){if( StartMonth <2 || (StartMonth == 2 && StartDay <= 29) ){tmpCalcAnnualBasis = 366.0 ;}else{tmpCalcAnnualBasis = 365.0 ;}}else if(isLeapYear (EndYear) ){if( EndMonth >2 || (EndMonth == 2 && EndDay == 29) ){tmpCalcAnnualBasis = 366.0 ;}else{tmpCalcAnnualBasis = 365.0 ;}}else{tmpCalcAnnualBasis = 365.0 ;}}else{for( iYear = StartYear ; iYear <= EndYear ; iYear ++){if(isLeapYear(iYear) ){tmpCalcAnnualBasis = tmpCalcAnnualBasis + 366 ;}else{tmpCalcAnnualBasis = tmpCalcAnnualBasis + 365 ;}}tmpCalcAnnualBasis = tmpCalcAnnualBasis / (EndYear - StartYear + 1) ;}break;}return tmpCalcAnnualBasis ;}public static Double tmpYearFrac(Date startDate, Date endDate, Integer Basis) {Long nNumerator = 0L ;Double nDenom = 0.0;nNumerator = tmpDiffDates(startDate, endDate, Basis) ;nDenom = tmpCalcAnnualBasis(startDate, endDate, Basis) ;Double result = nNumerator / nDenom ;BigDecimal t_result = new BigDecimal( result) ;return t_result.setScale( 14, RoundingMode.HALF_UP).doubleValue() ;}public static void main(String[] args) {Date startDate = DateUtil.parseDate( "2020-03-25") ;Date endDate = DateUtil.parseDate( "2022-03-31") ;Double yearfrac = tmpYearFrac( startDate ,endDate , 4) ;System.out.println(yearfrac);}
}
YearFrac函数Java版实现(完整版)相关推荐
- 魔塔小游戏Java版项目完整版
这是一款童年游戏4399网站上的魔塔仿制版,回忆童年,入手开发项目,全方面的代码解析 ⭐本项目演示地址⭐ ⭐资源图片源代码私信博主⭐ 项目的完整结构图: 游戏部分闯关图: 源代码如下: 怪物数据代码:
- c语言s开头的函数以及作用,C语言函数大全-s开头-完整版.doc
C语言函数大全-s开头-完整版 C语言函数大全(s开头) 函数名: sbrk 功能: 改变数据段空间位置 用法: char *sbrk(int incr); 程序例: #include#include ...
- 温州地图高清版全图完整版
温州地图高清版 全图完整版 软件大小:237KB 软件语言:简体中文 软件类别:图像浏览 软件授权:官方版 更新时间:2015-01-05 应用平台:/Win8/Win7/WinXP 温州地图高清版完 ...
- 基于内容的图像检索系统设计与实现--颜色信息--纹理信息--形状信息--PHASH--SHFT特征点的综合检测项目,包含简易版与完整版的源码及数据!
百度云提取源码以及数据包,直接下载压缩包解压就可以使用,数据就在压缩包文件dataset中. 简化版:只有-颜色信息–纹理信息–形状信息–PHASH–SHFT特征点的综合检测 [百度云链接,提取码:6 ...
- 你真的了解Java系统启动流程吗?java基础教程完整版
摘要 Apache Kafka是一个分布式消息发布订阅系统.它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Ap ...
- Java 对象排序完整版
前几天在 LeetCode 刷题的时候,遇到了利用 Arrays.sort() 或 Collections.sort() 来对 Java 对象进行排序的需求,于是想较详细地总结一下 Java 对象的排 ...
- java教程pdf(java教程视频完整版)
JAVA程序设计基础教程PDF 你在百度文库里找找好像有的,如果没有就去taobao吧,太多的二手旧书了.百度 谷歌上面这样的只是多的是 还有就是百度百科fsd <JAVA从入门到精通>电 ...
- 编写函数求阶乘(完整版)
一.编写函数 1.基础 //用函数编写 计算整数n的阶乘 #include<stdio.h>long Fact(int n); int main(void) {int m;//给出整数求阶 ...
- 如何用python计算函数的值域_(完整版)求函数定义域及值域方法及典型题归纳
范文 . 范例 . 指导 . 参考 < 一 > 求函数定义域.值域方法和典型题归纳 一.基础知识整合 1. 函数的定义:设集合 A 和 B 是非空数集,按照某一确定的对应关系 f , 使得 ...
最新文章
- Python时间戳转时间
- Qt QML页面翻转控件封装
- 将图卷积神经网络用于解码分子生成
- Java JDBC连接SQL Server2005错误:通过port 1433 连接到主机 localhost 的 TCP/IP 连接失败...
- 【BUG记录】Matisse显示的图片乱序或者在全部项不显示
- 微信小程序_(校园视)开发视频的展示页_上
- Flutter基础—质感设计
- win7和xp无线共享网络问题
- 2017年前端该学些什么(译)
- 三问智能体,华为如何落地全场景智慧
- 实现财务自由 之 不可不知的常用财务网站或应用软件
- USDA土壤粒径分布图及韦恩图在线绘制-USDA_Soil_Texture_Calculator soil textual triangle
- 用Python制作一个自动抢票脚本
- SXT:聚合与组合的理解
- windows下用cmd卸载程序
- 最新Google Earth 5.0简体中文版发布
- Python构造虚数矩阵报警告ComplexWarning: Casting complex values to real discards the imaginary part
- error C2065: ‘salary‘ : undeclared identifier
- ACM-ICPC近年省赛汇总
- A. Bear and Big Brother