[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    patch yearfrac
From:       Sascha Pfau <mrpeacock () gmail ! com>
Date:       2006-12-21 21:13:12
Message-ID: 200612212213.12549.MrPeacock () gmail ! com
[Download RAW message or body]

hello list,

another patch is ready. after some difficulties with the definition of some 
functions, i 've successfuly tested the yearfrac function.

regards

Sascha Pfau

["kspread-add-yearfrac.patch" (text/x-diff)]

Index: datetime.xml
===================================================================
--- datetime.xml	(revision 615506)
+++ datetime.xml	(working copy)
@@ -640,6 +640,28 @@
 	</Help>
     </Function>
 
+    <Function>
+	<Name>YEARFRAC</Name>
+	<Type>Int</Type>
+	<Parameter>
+	    <Comment>First date</Comment>
+	    <Type>String</Type>
+	</Parameter>
+	<Parameter>
+	    <Comment>Second date</Comment>
+	    <Type>String</Type>
+	</Parameter>
+	<Parameter>
+	    <Comment>interval</Comment>
+	    <Type>String</Type>
+	</Parameter>
+	<Help>
+	    <Text>The YEARFRAC() function returns the number of full days between start \
date and end date according to the basis.</Text> +            <Text>Basis must be one \
of the following: 0 = 30/360 US, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 \
= European 30/360</Text> +	    <Syntax>YEARFRAC(start date; endd date; \
basis)</Syntax> +	</Help>
+    </Function>
+
   </Group>
 
 </KSpreadFunctions>
Index: datetime.cpp
===================================================================
--- datetime.cpp	(revision 615506)
+++ datetime.cpp	(working copy)
@@ -68,6 +68,7 @@ Value func_weekNum (valVector args, Valu
 Value func_weeks (valVector args, ValueCalc *calc, FuncExtra *);
 Value func_weeksInYear (valVector args, ValueCalc *calc, FuncExtra *);
 Value func_year (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_yearFrac (valVector args, ValueCalc *calc, FuncExtra *);
 Value func_years (valVector args, ValueCalc *calc, FuncExtra *);
 
 // registers all date/time functions
@@ -175,6 +176,9 @@ void RegisterDateTimeFunctions()
   repo->add (f);
   f = new Function ("YEAR",   func_year);
   repo->add (f);
+  f = new Function ("YEARFRAC",  func_yearFrac);
+  f->setParamCount (2, 3);
+  repo->add (f);
   f = new Function ("YEARS",  func_years);
   f->setParamCount (3);
   repo->add (f);
@@ -806,3 +810,136 @@ Value func_dateDif (valVector args, Valu
   }
   return Value( res );
 }
+
+// Function: yearFrac
+//
+// 		basis    descritption day-count 	
+// default: 	0	 US (NASD) system. 30 days/month, 360 days/year (30/360)
+//		1	 Actual/actual (Euro), also known as AFB
+//		2	 Actual/360
+//		3	 Actual/365
+//		4	 European 30/360
+//
+Value func_yearFrac (valVector args, ValueCalc *calc, FuncExtra *)
+{
+  Value v1( calc->conv()->asDate (args[0]).asDate( calc->doc() ), calc->doc() );
+  if (v1.isError()) return v1;
+  QDate date1 = v1.asDate( calc->doc() );
+
+  if (!date1.isValid())
+      return Value::errorVALUE();
+
+  Value v2( calc->conv()->asDate (args[1]).asDate( calc->doc() ), calc->doc() );
+  if (v2.isError()) return v2;
+  QDate date2 = v2.asDate( calc->doc() );
+
+  if (!date2.isValid())
+      return Value::errorVALUE();
+
+  // check if basis is valid
+  int basis = calc->conv()->asInteger (args[2]).asInteger();
+  if ( basis < 0 || basis > 4 ) 
+    return Value::errorVALUE();
+
+  //
+  // calculation
+  //
+
+  QDate date0 = calc->doc()->referenceDate(); // referenceDate
+  
+  if ( date2 < date1 )
+  {
+    // exchange dates
+    QDate Temp1=date1;
+    date1=date2;
+    date2=Temp1;
+  }
+  
+  int days = date0.daysTo(date2) - date0.daysTo(date1);
+  
+  //kDebug(36002) << "date1 = " << date1 << "    date2 = " << date2 << "    days = " \
<< days << "    basis = " << basis << endl; +    
+  double res=0;
+  double peryear=0;
+    
+  switch(basis)
+  {
+    case 1:
+    {
+      // Actual/actual
+      int leaps=0,years=0;
+      double k;
+      
+      if (days < (365 + QDate::isLeapYear(date1.year()) + 1))
+      {
+        // less than 1 year
+        //kDebug(36002) << "less tahn 1 year ..." << endl;
+    
+	// bool 1 = 29.2. is in between dates
+        k = (QDate::isLeapYear(date1.year()) && date1.month()<3) || \
(QDate::isLeapYear(date2.year()) && date2.month()*100+date2.day() >= 2*100+29); +     \
years = 1; +      }
+      else
+      {
+        // more than 1 year
+        //kDebug(36002) << "more than 1 year ..." << endl;
+        years = date2.year()-date1.year()+1;
+        leaps = QDate(date2.year()+1, 1, 1).toJulianDay() - QDate(date1.year(), 1, \
1).toJulianDay() - 365*years; +	k = (double)leaps/years;
+      }
+      
+      //kDebug(36002) << "leaps = " << leaps << "    years = " << years << "    \
leaps per year = " << (double)leaps/years << endl; +      peryear = 365 + k;
+      break;
+    }
+    case 2:
+    {
+      // Actual/360
+      peryear = 360;
+      break;
+    }
+    case 3:
+    {
+      // Actual/365
+      peryear = 365;
+      break;
+    }
+    case 4:
+    {
+      // 30/360 Europe
+      
+      // calc datedif360 (start, end, 1)
+      int a = date2.year() - date1.year();
+      int m = date2.month() - date1.month();
+      int j = date2.day() - date1.day();
+      
+      // diff
+      days = a*360 + m*30 + j;
+      days = days + (date1.day()==31) - (date2.day()==31);
+      //kDebug(36002) << "corrected days = " << days << endl;
+      
+      peryear = 360;
+      break;
+    }
+    default:
+    {
+      // NASD 30/360
+      basis = 0;
+      
+      // calc datedif360 (start, end, 0)
+      int a = date2.year() - date1.year();
+      int m = date2.month() - date1.month();
+      int j = date2.day() - date1.day();
+      
+      // diff
+      days = a * 360 + m*30 + j;
+      
+      peryear = 360;
+    }	
+  }
+  
+  res = (double)days / peryear;
+ 
+  //kDebug(36002) << "Basis = " << basis << "   res = " << res << endl; 
+  return Value( res );
+}



_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic