[Libreoffice-commits] core.git: Branch 'libreoffice-4-0' - scaddins/source

Winfried Donkers osc at dci-electronics.nl
Mon Apr 22 06:24:32 PDT 2013


 scaddins/source/analysis/analysishelper.cxx |  208 +++++++++++++++++-----------
 scaddins/source/analysis/analysishelper.hxx |    5 
 2 files changed, 131 insertions(+), 82 deletions(-)

New commits:
commit bd9238f3fe4bd004cb77e89813eb730e1e865667
Author: Winfried Donkers <osc at dci-electronics.nl>
Date:   Sat Apr 13 19:47:10 2013 +0200

    fdo#40100 make function YEARFRAC comply with ODFF Version1.2
    
    Reviewed-on: https://gerrit.libreoffice.org/3375
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 275e68d141179272258d03194d799495fa3dec4a)
    
    Conflicts:
    	scaddins/source/analysis/analysishelper.cxx
    	scaddins/source/analysis/analysishelper.hxx
    
    Change-Id: Ief5e5c89b7fb69fb9849cf2d6efe2b4c5b7f5391
    Signed-off-by: Eike Rathke <erack at redhat.com>

diff --git a/scaddins/source/analysis/analysishelper.cxx b/scaddins/source/analysis/analysishelper.cxx
index 8fddc7b..b540a88 100644
--- a/scaddins/source/analysis/analysishelper.cxx
+++ b/scaddins/source/analysis/analysishelper.cxx
@@ -333,78 +333,6 @@ sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 )
 }
 
 
-void GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
-    sal_uInt16& rYears, sal_Int32& rDayDiffPart, sal_Int32& rDaysInYear ) THROWDEF_RTE_IAE
-{
-    if( nStartDate > nEndDate )
-    {
-        sal_Int32   n = nEndDate;
-        nEndDate = nStartDate;
-        nStartDate = n;
-    }
-
-    sal_Int32   nDate1 = nStartDate + nNullDate;
-    sal_Int32   nDate2 = nEndDate + nNullDate;
-
-    sal_uInt16  nDay1, nDay2;
-    sal_uInt16  nMonth1, nMonth2;
-    sal_uInt16  nYear1, nYear2;
-
-    DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
-    DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
-
-    sal_uInt16  nYears;
-
-    sal_Int32   nDayDiff, nDaysInYear;
-
-    switch( nMode )
-    {
-        case 0:         // 0=USA (NASD) 30/360
-        case 4:         // 4=Europe 30/360
-            nDaysInYear = 360;
-            nYears = nYear2 - nYear1;
-            nDayDiff = GetDiffDate360( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ),
-                                        nDay2, nMonth2, nYear2, nMode == 0 ) - nYears * nDaysInYear;
-            break;
-        case 1:         // 1=exact/exact
-            nYears = nYear2 - nYear1;
-
-            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;
-
-            break;
-        case 2:         // 2=exact/360
-            nDaysInYear = 360;
-            nYears = sal_uInt16( ( nDate2 - nDate1 ) / nDaysInYear );
-            nDayDiff = nDate2 - nDate1;
-            nDayDiff %= nDaysInYear;
-            break;
-        case 3:         //3=exact/365
-            nDaysInYear = 365;
-            nYears = sal_uInt16( ( nDate2 - nDate1 ) / nDaysInYear );
-            nDayDiff = nDate2 - nDate1;
-            nDayDiff %= nDaysInYear;
-            break;
-        default:
-            THROW_IAE;
-    }
-
-    rYears = nYears;
-    rDayDiffPart = nDayDiff;
-    rDaysInYear = nDaysInYear;
-}
-
-
 sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
     sal_Int32* pOptDaysIn1stYear ) THROWDEF_RTE_IAE
 {
@@ -509,17 +437,143 @@ sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode )
 }
 
 
-double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE
+//fdo40100 toDo: make function fully compliant with ODFF1.2
+/**
+ * Function GetYearFrac implements YEARFRAC as defined in:
+ *   Open Document Format for Office Applications version 1.2 Part 2, par. 6.10.24
+ *   The calculations are defined in:
+ *   Open Document Format for Office Applications version 1.2 Part 2, par. 4.11.7
+ */
+double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException )
 {
     if( nStartDate == nEndDate )
         return 0.0;     // nothing to do...
 
-    sal_uInt16  nYears;
-    sal_Int32   nDayDiff, nDaysInYear;
+    if( nStartDate > nEndDate )
+    {
+        sal_Int32   n = nEndDate;
+        nEndDate = nStartDate;
+        nStartDate = n;
+    }
+
+    sal_Int32 nDate1 = nStartDate + nNullDate;
+    sal_Int32 nDate2 = nEndDate + nNullDate;
+
+    sal_uInt16  nDay1, nDay2;
+    sal_uInt16  nMonth1, nMonth2;
+    sal_uInt16  nYear1, nYear2;
+
+    DaysToDate( nDate1, nDay1, nMonth1, nYear1 );
+    DaysToDate( nDate2, nDay2, nMonth2, nYear2 );
+
+    // calculate days between nDate1 and nDate2
+    sal_Int32 nDayDiff;
+    switch( nMode )
+    {
+        case 0:         // 0=USA (NASD) 30/360
+            if ( nDay1 == 31 )
+            {
+                nDay1--;
+            }
+            if ( nDay1 == 30 && nDay2 == 31 )
+            {
+                nDay2--;
+            }
+            else
+            {
+                if ( nMonth1 == 2 && nDay1 == ( IsLeapYear( nYear1 ) ? 29 : 28 ) )
+                {
+                    nDay1 = 30;
+                    if ( nMonth2 == 2 && nDay2 == ( IsLeapYear( nYear2 ) ? 29 : 28 ) )
+                    {
+                        nDay2 = 30;
+                    }
+                }
+            }
+            nDayDiff = ( nYear2 - nYear1 ) * 360 + ( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );
+            break;
+        case 1:         // 1=exact/exact
+        case 2:         // 2=exact/360
+        case 3:         // 3=exact/365
+            nDayDiff = nDate2 - nDate1;
+            break;
+        case 4:         // 4=Europe 30/360
+            if ( nDay1 == 31 )
+            {
+                nDay1--;
+            }
+            if ( nDay2 == 31 )
+            {
+                nDay2--;
+            }
+            nDayDiff = ( nYear2 - nYear1 ) * 360 + ( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );
+            break;
+        default:
+            throw lang::IllegalArgumentException();
+    }
 
-    GetDiffParam( nNullDate, nStartDate, nEndDate, nMode, nYears, nDayDiff, nDaysInYear );
+    //calculate days in year
+    double nDaysInYear;
+    switch( nMode )
+    {
+        case 0:         // 0=USA (NASD) 30/360
+        case 2:         // 2=exact/360
+        case 4:         // 4=Europe 30/360
+            nDaysInYear = 360;
+            break;
+        case 1:         // 1=exact/exact
+            {
+                bool isYearDifferent = ( nYear1 != nYear2 );
+                if ( isYearDifferent &&
+                     ( ( nYear2 != nYear1 + 1 ) ||
+                       ( nMonth1 < nMonth2 ) ||
+                       ( nMonth1 == nMonth2 && nDay1 < nDay2 ) ) )
+                {
+                    // return average of days in year between nDate1 and nDate2, inclusive
+                    sal_Int32 nDayCount = 0;
+                    for ( sal_Int16 i = nYear1; i <= nYear2; i++ )
+                        nDayCount += ( IsLeapYear( i ) ? 366 : 365 );
+
+                    nDaysInYear = ( double ) nDayCount / ( double ) ( nYear2 - nYear1 + 1 );
+                }
+                else
+                {
+                    if ( isYearDifferent && IsLeapYear( nYear1 ) )
+                    {
+                        nDaysInYear = 366;
+                    }
+                    else
+                    {
+                        //if Feb 29 is between nDate1 and ndate2, inclusive
+                        if ( ( IsLeapYear( nYear1 ) && nMonth1 <= 2 && nDay1 <= 29 ) ||
+                             ( IsLeapYear( nYear2 ) && ( nMonth2 > 3 || ( nMonth2 == 2 && nDay1 == 29 ) ) ) )
+                        {
+                            nDaysInYear = 366;
+                        }
+                        else
+                        {
+                            nDaysInYear = 365;
+                            for ( sal_Int16 i = nYear1; i <= nYear2; i++ )
+                            {
+                                if ( IsLeapYear( i ) )
+                                {
+                                    nDaysInYear = 366;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+        case 3:         // 3=exact/365
+            nDaysInYear = 365;
+            break;
+        default:
+            throw lang::IllegalArgumentException();
+    }
 
-    return double( nYears ) + double( nDayDiff ) / double( nDaysInYear );
+    return double( nDayDiff ) / nDaysInYear;
 }
 
 double BinomialCoefficient( double n, double k )
diff --git a/scaddins/source/analysis/analysishelper.hxx b/scaddins/source/analysis/analysishelper.hxx
index 395348c..ceb3fe2 100644
--- a/scaddins/source/analysis/analysishelper.hxx
+++ b/scaddins/source/analysis/analysishelper.hxx
@@ -79,11 +79,6 @@ sal_Int32           GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_I
 
 sal_Int32           GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 );
 inline sal_Int16    GetDayOfWeek( sal_Int32 nDate );
-void                GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
-                        sal_uInt16& rYears, sal_Int32& rDayDiffPart, sal_Int32& rDaysInYear ) THROWDEF_RTE_IAE;
-                        // rYears = full num of years
-                        // rDayDiffPart = num of days for last year
-                        // rDaysInYear = num of days in first year
 sal_Int32           GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode,
                                 sal_Int32* pOptDaysIn1stYear = NULL ) THROWDEF_RTE_IAE;
 double              GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode )


More information about the Libreoffice-commits mailing list