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版实现(完整版)相关推荐

  1. 魔塔小游戏Java版项目完整版

    这是一款童年游戏4399网站上的魔塔仿制版,回忆童年,入手开发项目,全方面的代码解析 ⭐本项目演示地址⭐ ⭐资源图片源代码私信博主⭐ 项目的完整结构图: 游戏部分闯关图: 源代码如下: 怪物数据代码:

  2. c语言s开头的函数以及作用,C语言函数大全-s开头-完整版.doc

    C语言函数大全-s开头-完整版 C语言函数大全(s开头) 函数名: sbrk 功能: 改变数据段空间位置 用法: char *sbrk(int incr); 程序例: #include#include ...

  3. 温州地图高清版全图完整版

    温州地图高清版 全图完整版 软件大小:237KB 软件语言:简体中文 软件类别:图像浏览 软件授权:官方版 更新时间:2015-01-05 应用平台:/Win8/Win7/WinXP 温州地图高清版完 ...

  4. 基于内容的图像检索系统设计与实现--颜色信息--纹理信息--形状信息--PHASH--SHFT特征点的综合检测项目,包含简易版与完整版的源码及数据!

    百度云提取源码以及数据包,直接下载压缩包解压就可以使用,数据就在压缩包文件dataset中. 简化版:只有-颜色信息–纹理信息–形状信息–PHASH–SHFT特征点的综合检测 [百度云链接,提取码:6 ...

  5. 你真的了解Java系统启动流程吗?java基础教程完整版

    摘要 Apache Kafka是一个分布式消息发布订阅系统.它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Ap ...

  6. Java 对象排序完整版

    前几天在 LeetCode 刷题的时候,遇到了利用 Arrays.sort() 或 Collections.sort() 来对 Java 对象进行排序的需求,于是想较详细地总结一下 Java 对象的排 ...

  7. java教程pdf(java教程视频完整版)

    JAVA程序设计基础教程PDF 你在百度文库里找找好像有的,如果没有就去taobao吧,太多的二手旧书了.百度 谷歌上面这样的只是多的是 还有就是百度百科fsd <JAVA从入门到精通>电 ...

  8. 编写函数求阶乘(完整版)

    一.编写函数 1.基础 //用函数编写 计算整数n的阶乘 #include<stdio.h>long Fact(int n); int main(void) {int m;//给出整数求阶 ...

  9. 如何用python计算函数的值域_(完整版)求函数定义域及值域方法及典型题归纳

    范文 . 范例 . 指导 . 参考 < 一 > 求函数定义域.值域方法和典型题归纳 一.基础知识整合 1. 函数的定义:设集合 A 和 B 是非空数集,按照某一确定的对应关系 f , 使得 ...

最新文章

  1. Python时间戳转时间
  2. Qt QML页面翻转控件封装
  3. 将图卷积神经网络用于解码分子生成
  4. Java JDBC连接SQL Server2005错误:通过port 1433 连接到主机 localhost 的 TCP/IP 连接失败...
  5. 【BUG记录】Matisse显示的图片乱序或者在全部项不显示
  6. 微信小程序_(校园视)开发视频的展示页_上
  7. Flutter基础—质感设计
  8. win7和xp无线共享网络问题
  9. 2017年前端该学些什么(译)
  10. 三问智能体,华为如何落地全场景智慧
  11. 实现财务自由 之 不可不知的常用财务网站或应用软件
  12. USDA土壤粒径分布图及韦恩图在线绘制-USDA_Soil_Texture_Calculator soil textual triangle
  13. 用Python制作一个自动抢票脚本
  14. SXT:聚合与组合的理解
  15. windows下用cmd卸载程序
  16. 最新Google Earth 5.0简体中文版发布
  17. Python构造虚数矩阵报警告ComplexWarning: Casting complex values to real discards the imaginary part
  18. error C2065: ‘salary‘ : undeclared identifier
  19. ACM-ICPC近年省赛汇总
  20. A. Bear and Big Brother

热门文章

  1. java se7 新特性_Java SE7新特性之try-with-resources语句
  2. 【前端学习】Git的安装和基本使用方法和环境变量配置 时光大魔王
  3. 职场中的天龙八部——北漂18年(53)
  4. 大数据批量处理神器 - 自定义周期批量消费队列的实现
  5. 滑坡、沉降监测方案简析
  6. 金山词霸2005,郁闷……
  7. ISO质量管理体系认证审核前需要准备的资料
  8. 联结主义时间分类(Connectionist temporal classification)的论文笔记
  9. 前端 JSP颜色大全(网址)
  10. 简历 解析 技术总结