Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


For some reason I can't connect with gerrit, so I submit this patch in the classic way.

The patch improves the calculation of YEARFRAC in case of leap years.

There still is one more possible improvement (see ToDo-comment in patch), but that could be 
argueable.
I'm interested in your opnions on that further improvement,
Eike, you will certainly have something to say about that.

Winfried
From a897334a5d183d24a2ec2dacfe50bf21239b78a6 Mon Sep 17 00:00:00 2001
From: Winfried Donkers <osc@dci-electronics>
Date: Thu, 11 Apr 2013 17:37:33 +0200
Subject: [PATCH] fdo#40100 correct result of calc function YEARFRAC

Change-Id: I8c27cf6ee942d42e8ca4d67a4c7665962094c4a1
---
 scaddins/source/analysis/analysishelper.cxx | 31 +++++++++++++++++------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/scaddins/source/analysis/analysishelper.cxx 
b/scaddins/source/analysis/analysishelper.cxx
index 27fea93..2b6c26e 100644
--- a/scaddins/source/analysis/analysishelper.cxx
+++ b/scaddins/source/analysis/analysishelper.cxx
@@ -366,21 +366,15 @@ void GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 
nEndDate
                                         nDay2, nMonth2, nYear2, nMode == 0 ) - nYears * 
nDaysInYear;
             break;
         case 1:         // 1=exact/exact
-            nYears = nYear2 - nYear1;
+            //fdo40100 because of possible leap years calculate number
+            //of days separately for year1 and year2 and let nYears
+            //contain only number of full calendar years
+            nYears = nYear2 - nYear1 - 1;
 
             nDaysInYear = IsLeapYear( nYear1 )? 366 : 365;
 
-            if( nYears && ( nMonth1 > nMonth2 || ( nMonth1 == nMonth2 && nDay1 > nDay2 ) ) )
-                nYears--;
-
-            if( nYears )
-                nDayDiff = nDate2 - DateToDays( nDay1, nMonth1, nYear2 );
-            else
-                nDayDiff = nDate2 - nDate1;
-
-            if( nDayDiff < 0 )
-                nDayDiff += nDaysInYear;
-
+            nDayDiff = ( nDate2 - DateToDays( 1, 1, nYear2 ) ) +
+                ( DateToDays( 31, 12, nYear1 ) - nDate1 ) + 1; //plus 1 for Dec 31 to Jan 1
             break;
         case 2:         // 2=exact/360
             nDaysInYear = 360;
@@ -508,6 +502,18 @@ sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode 
)
 }
 
 
+//TODO: In the case of nMode == 1 (exact), there still remains a small error
+//      in the result because of leap years. nDaysInYear is an integer and
+//      returns the days in the year of nStartDate. If nEndDate is not a
+//      leap year, the year fraction of the days in the year of nEndDate is
+//      a little bit too small. If nStardate is not in a leap year, but
+//      nEndDate is, then year fraction of the days in the year of nEndDate
+//      is a little bit too large.
+//      This could be corrected when nDaysInYear is a float and the value
+//      reflects the number of days in the leap year and the non-leap year.
+//      Example: If there are 80 days in the leap year and 80 days in the
+//      non-leap year, then nDaysInYear would be 365.5, resulting in a more
+//      or less exact year fraction.
 double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode 
) throw( uno::RuntimeException, lang::IllegalArgumentException )
 {
     if( nStartDate == nEndDate )
@@ -517,7 +523,6 @@ double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDat
     sal_Int32   nDayDiff, nDaysInYear;
 
     GetDiffParam( nNullDate, nStartDate, nEndDate, nMode, nYears, nDayDiff, nDaysInYear );
-
     return double( nYears ) + double( nDayDiff ) / double( nDaysInYear );
 }
 
-- 
1.8.1.4


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.