summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinfried Donkers <osc@dci-electronics.nl>2012-05-09 16:47:13 +0200
committerEike Rathke <erack@redhat.com>2012-05-13 13:51:13 +0200
commit4e71be498903dee5bf719a73f4976bb5356335dd (patch)
treebe542ccf54df83afe75f56ae341b11c66afedef9
parent2068144fdcfdee3abe2a90b3b4b3bd49589618f2 (diff)
fdo#44456 added calc function DATEDIF as in ODF1.2
Change-Id: I082ea20d02bf37d515fc33d627281696fc48fcb6
-rw-r--r--formula/inc/formula/compiler.hrc7
-rw-r--r--formula/inc/formula/opcode.hxx1
-rw-r--r--formula/source/core/resource/core_resource.src6
-rw-r--r--sc/inc/helpids.h1
-rw-r--r--sc/qa/unit/ucalc.cxx1
-rw-r--r--sc/source/core/inc/interpre.hxx1
-rw-r--r--sc/source/core/tool/interpr2.cxx91
-rw-r--r--sc/source/core/tool/interpr4.cxx1
-rw-r--r--sc/source/filter/excel/xlformula.cxx1
-rw-r--r--sc/source/filter/oox/formulabase.cxx2
-rw-r--r--sc/source/ui/src/scfuncs.src46
-rw-r--r--sc/util/hidother.src1
12 files changed, 155 insertions, 4 deletions
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index 15d8aab91e3c..a2d4bb52f10f 100644
--- a/formula/inc/formula/compiler.hrc
+++ b/formula/inc/formula/compiler.hrc
@@ -396,16 +396,17 @@
#define SC_OPCODE_CHISQ_INV 394
#define SC_OPCODE_BITAND 395
#define SC_OPCODE_BITOR 396
#define SC_OPCODE_BITXOR 397
#define SC_OPCODE_BITRSHIFT 398
#define SC_OPCODE_BITLSHIFT 399
-#define SC_OPCODE_STOP_2_PAR 400
-#define SC_OPCODE_LAST_OPCODE_ID 399 /* last OpCode */
+#define SC_OPCODE_GET_DATEDIF 400
+#define SC_OPCODE_STOP_2_PAR 401
+#define SC_OPCODE_LAST_OPCODE_ID 401 /* last OpCode */
-/*** Interna ***/
+/*** Internal ***/
#define SC_OPCODE_INTERNAL_BEGIN 9999
#define SC_OPCODE_TTT 9999
#define SC_OPCODE_INTERNAL_END 9999
/*** from here on ExtraData contained ***/
#define SC_OPCODE_DATA_TOKEN_1 10000
diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx
index b1e585cd8548..a1543ddcb427 100644
--- a/formula/inc/formula/opcode.hxx
+++ b/formula/inc/formula/opcode.hxx
@@ -209,12 +209,13 @@ enum OpCodeEnum
ocSumX2DY2 = SC_OPCODE_SUM_X2DY2,
ocSumXMY2 = SC_OPCODE_SUM_XMY2,
ocGetDate = SC_OPCODE_GET_DATE,
ocGetTime = SC_OPCODE_GET_TIME,
ocGetDiffDate = SC_OPCODE_GET_DIFF_DATE,
ocGetDiffDate360 = SC_OPCODE_GET_DIFF_DATE_360,
+ ocGetDateDif = SC_OPCODE_GET_DATEDIF,
ocMin = SC_OPCODE_MIN,
ocMax = SC_OPCODE_MAX,
ocSum = SC_OPCODE_SUM,
ocProduct = SC_OPCODE_PRODUCT,
ocAverage = SC_OPCODE_AVERAGE,
ocCount = SC_OPCODE_COUNT,
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index 12cb57d01bb8..12592316e384 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -167,12 +167,13 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
String SC_OPCODE_SUM_X2DY2 { Text = "SUMX2PY2" ; };
String SC_OPCODE_SUM_XMY2 { Text = "SUMXMY2" ; };
String SC_OPCODE_GET_DATE { Text = "DATE" ; };
String SC_OPCODE_GET_TIME { Text = "TIME" ; };
String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; };
String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; };
+ String SC_OPCODE_GET_DATEDIF { Text = "DATEDIF" ; };
String SC_OPCODE_MIN { Text = "MIN" ; };
String SC_OPCODE_MIN_A { Text = "MINA" ; };
String SC_OPCODE_MAX { Text = "MAX" ; };
String SC_OPCODE_MAX_A { Text = "MAXA" ; };
String SC_OPCODE_SUM { Text = "SUM" ; };
String SC_OPCODE_PRODUCT { Text = "PRODUCT" ; };
@@ -499,12 +500,13 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
String SC_OPCODE_SUM_X2DY2 { Text = "SUMX2PY2" ; };
String SC_OPCODE_SUM_XMY2 { Text = "SUMXMY2" ; };
String SC_OPCODE_GET_DATE { Text = "DATE" ; };
String SC_OPCODE_GET_TIME { Text = "TIME" ; };
String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; };
String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; };
+ String SC_OPCODE_GET_DATEDIF { Text = "DATEDIF" ; };
String SC_OPCODE_MIN { Text = "MIN" ; };
String SC_OPCODE_MIN_A { Text = "MINA" ; };
String SC_OPCODE_MAX { Text = "MAX" ; };
String SC_OPCODE_MAX_A { Text = "MAXA" ; };
String SC_OPCODE_SUM { Text = "SUM" ; };
String SC_OPCODE_PRODUCT { Text = "PRODUCT" ; };
@@ -1172,12 +1174,16 @@ Resource RID_STRLIST_FUNCTION_NAMES
Text [ en-US ] = "DAYS" ;
};
String SC_OPCODE_GET_DIFF_DATE_360
{
Text [ en-US ] = "DAYS360" ;
};
+ String SC_OPCODE_GET_DATEDIF
+ {
+ Text [ en-US ] = "DATEDIF" ;
+ };
String SC_OPCODE_MIN
{
Text [ en-US ] = "MIN" ;
};
String SC_OPCODE_MIN_A
{
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index 5eec0d1c3301..8d41ab7754ad 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -431,12 +431,13 @@
#define HID_FUNC_ZEIT "SC_HID_FUNC_ZEIT"
#define HID_FUNC_ZEITWERT "SC_HID_FUNC_ZEITWERT"
#define HID_FUNC_HEUTE "SC_HID_FUNC_HEUTE"
#define HID_FUNC_WOCHENTAG "SC_HID_FUNC_WOCHENTAG"
#define HID_FUNC_JAHR "SC_HID_FUNC_JAHR"
#define HID_FUNC_TAGE "SC_HID_FUNC_TAGE"
+#define HID_FUNC_DATEDIF "SC_HID_FUNC_DATEDIF"
#define HID_FUNC_KALENDERWOCHE "SC_HID_FUNC_KALENDERWOCHE"
#define HID_FUNC_OSTERSONNTAG "SC_HID_FUNC_OSTERSONNTAG"
#define HID_FUNC_BW "SC_HID_FUNC_BW"
#define HID_FUNC_ZW "SC_HID_FUNC_ZW"
#define HID_FUNC_ZZR "SC_HID_FUNC_ZZR"
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d875e4262530..ef33e64ca2aa 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -3073,12 +3073,13 @@ void Test::testFunctionLists()
"DVARP",
0
};
const char* aDateTime[] = {
"DATE",
+ "DATEDIF",
"DATEVALUE",
"DAY",
"DAYS",
"DAYS360",
"EASTERSUNDAY",
"HOUR",
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 192c2e05e315..5f57fefa8c70 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -588,12 +588,13 @@ void ScGetTimeValue();
void ScArcTan2();
void ScLog();
void ScGetDate();
void ScGetTime();
void ScGetDiffDate();
void ScGetDiffDate360();
+void ScGetDateDif();
void ScPower();
void ScAmpersand();
void ScAdd();
void ScSub();
void ScMul();
void ScDiv();
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index f022e9c10a7e..4f159a043f02 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -409,12 +409,103 @@ void ScInterpreter::ScGetDiffDate360()
- (double) aDate1.GetDay() - (double) aDate1.GetMonth() * 30.0
- (double)aDate1.GetYear() * 360.0) );
}
}
}
+//fdo#44456 function DATEDIF as defined in ODF1.2 (Par. 6.10.3)
+void ScInterpreter::ScGetDateDif()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDateDif" );
+ if ( MustHaveParamCount( GetByte(), 3 ) )
+ {
+ String aFormat = GetString();
+ double nDate2 = GetDouble();
+ double nDate1 = GetDouble();
+ int dd = nDate2 - nDate1;
+
+ //split dates in day, month, year for use with formats other than "d"
+ int d1, m1, y1, d2, m2, y2;
+ Date aDate = *( pFormatter->GetNullDate() );
+ aDate += (long) ::rtl::math::approxFloor( nDate1 );
+ y1 = aDate.GetYear();
+ m1 = aDate.GetMonth();
+ d1 = aDate.GetDay();
+ aDate = *( pFormatter->GetNullDate() );
+ aDate += (long) ::rtl::math::approxFloor( nDate2 );
+ y2 = aDate.GetYear();
+ m2 = aDate.GetMonth();
+ d2 = aDate.GetDay();
+
+ if ( dd == 0 )
+ PushInt( 0 ); // nothing to do...
+
+ if ( aFormat.EqualsIgnoreCaseAscii( "d" ) ) // return number of days
+ PushInt( dd );
+ else if ( aFormat.EqualsIgnoreCaseAscii( "m" ) ) // return number of months
+ {
+ int md = m2 - m1 + 12 * (y2 - y1);
+ if ( nDate2 > nDate1 )
+ {
+ if ( d2 < d1 )
+ md -= 1;
+ }
+ else
+ {
+ if ( d2 > d1 )
+ md += 1;
+ }
+ PushInt( md );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "y" ) ) // return number of years
+ {
+ int yd = y2 - y1;
+ if ( y2 > y1 )
+ {
+ if ( ( m2 == m1 and d2 >= d1 ) || ( m2 > m1 ) )
+ yd = y2 - y1 - 1;
+ }
+ else
+ {
+ if ( ( m2 == m1 and d2 <= d1 ) || ( m2 < m1 ) )
+ yd = y2 - y1 + 1;
+ }
+ PushInt( yd );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "md" ) ) // return number of days, ignoring months and years
+ {
+ aDate = Date( d2, m1, y1 );
+ double nd2 = double( aDate - *( pFormatter->GetNullDate() ) );
+ PushInt( nd2 - nDate1 );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "ym" ) ) // return number of months, ignoring years
+ {
+ int md = m2 - m1;
+ if ( m2 > m1 )
+ {
+ if ( d2 < d1 )
+ md -= 1;
+ }
+ else
+ {
+ if ( m2 < m1 && d2 > d1 )
+ md += 1;
+ }
+ PushInt( md );
+ }
+ else if ( aFormat.EqualsIgnoreCaseAscii( "yd" ) ) // return number of days, ignoring years
+ {
+ aDate = Date( d2, m2, y1 );
+ double nd2 = double( aDate - *( pFormatter->GetNullDate() ) );
+ PushInt( nd2 - nDate1 );
+ }
+ else
+ PushIllegalArgument(); // unsupported format
+ }
+}
+
void ScInterpreter::ScGetTimeValue()
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTimeValue" );
String aInputString = GetString();
sal_uInt32 nFIndex = 0; // damit default Land/Spr.
double fVal;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 8764b4569692..e48a5a854788 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3907,12 +3907,13 @@ StackVar ScInterpreter::Interpret()
case ocGCD : ScGCD(); break;
case ocLCM : ScLCM(); break;
case ocGetDate : ScGetDate(); break;
case ocGetTime : ScGetTime(); break;
case ocGetDiffDate : ScGetDiffDate(); break;
case ocGetDiffDate360 : ScGetDiffDate360(); break;
+ case ocGetDateDif : ScGetDateDif(); break;
case ocMin : ScMin( false ); break;
case ocMinA : ScMin( true ); break;
case ocMax : ScMax( false ); break;
case ocMaxA : ScMax( true ); break;
case ocSum : ScSum(); break;
case ocProduct : ScProduct(); break;
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index 8685041aa222..fcd052a7c6b6 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -379,12 +379,13 @@ static const XclFunctionInfo saFuncTable_Odf[] =
EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITOR" ),
EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITRSHIFT" ),
EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITXOR" ),
EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ),
EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ),
EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ),
+ EXC_FUNCENTRY_ODF( ocGetDateDif, 3, 3, 0, "DATEDIF" ),
EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ),
EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ),
EXC_FUNCENTRY_ODF( ocFDist, 3, 4, 0, "FDIST" ),
EXC_FUNCENTRY_ODF( ocFInv, 3, 3, 0, "FINV" ),
EXC_FUNCENTRY_ODF( ocFormula, 1, 1, 0, "FORMULA" ),
EXC_FUNCENTRY_ODF( ocGamma, 1, 1, 0, "GAMMA" ),
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index efc9930feddb..2017e0b54245 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -662,13 +662,12 @@ static const FunctionData saFuncTableBiff5[] =
{ "DEGREES", "DEGREES", 343, 343, 1, 1, V, { VR }, 0 },
{ "SUBTOTAL", "SUBTOTAL", 344, 344, 2, MX, V, { VR, RO }, 0 },
{ "SUMIF", "SUMIF", 345, 345, 2, 3, V, { RO, VR, RO }, 0 },
{ "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { RO, VR }, 0 },
{ "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 },
{ "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 },
- { 0, "DATEDIF", 351, 351, 3, 3, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc
{ 0, "DATESTRING", 352, 352, 1, 1, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec
{ 0, "NUMBERSTRING", 353, 353, 2, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec
{ "ROMAN", "ROMAN", 354, 354, 1, 2, V, { VR }, 0 },
// *** EuroTool add-in ***
@@ -739,12 +738,13 @@ static const FunctionData saFuncTableOdf[] =
{ "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "DATEDIF", 0, NOID, NOID, 3, 3, V, { RR }, FUNCFLAG_MACROCALLODF },
{ "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "FINV", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
{ "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
{ "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index 1363edb456d7..b726685bec63 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -969,12 +969,58 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 5 // Description of Parameter 2
{
Text [ en-US ] = "The start date for calculating the difference in days." ;
};
};
+ // -=*# Resource for function DATEDIF #*=-
+ Resource SC_OPCODE_GET_DATEDIF
+ {
+ String 1 // description
+ {
+ Text [ en-US ] = "Returns the number of whole days, months or years between 'start date' and 'end date'";
+ };
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_DATETIME;
+ U2S( HID_FUNC_DATEDIF );
+ 3; 0; 0; 0;
+ 0;
+ };
+
+ String 2 // name of parameter 1 DateDif
+ {
+ Text [ en-US ] = "Start date";
+ };
+
+ String 3 // description of parameter 1 DateDif
+ {
+ Text [ en-US ] = "The start date";
+ };
+
+ String 4 // name of parameter 2 DateDif
+ {
+ Text [ en-US ] = "End date";
+ };
+
+ String 5 // description of parameter 2 DateDif
+ {
+ Text [ en-US ] = "The end date";
+ };
+
+ String 6 // name of parameter 3 DateDif
+ {
+ Text [ en-US ] = "Format";
+ };
+
+ String 7 // description of parameter 3 DateDif
+ {
+ Text [ en-US ] = "Format of the result";
+ };
+ };
// -=*# Resource for function KALENDERWOCHE #*=-
Resource SC_OPCODE_WEEK
{
String 1 // Description
{
Text [ en-US ] = "Calculates the calendar week corresponding to the given date." ;
diff --git a/sc/util/hidother.src b/sc/util/hidother.src
index 363e08c9b56d..85d36f913977 100644
--- a/sc/util/hidother.src
+++ b/sc/util/hidother.src
@@ -110,12 +110,13 @@ hidspecial HID_FUNC_SEKUNDE { HelpID = HID_FUNC_SEKUNDE; };
hidspecial HID_FUNC_ZEIT { HelpID = HID_FUNC_ZEIT; };
hidspecial HID_FUNC_ZEITWERT { HelpID = HID_FUNC_ZEITWERT; };
hidspecial HID_FUNC_HEUTE { HelpID = HID_FUNC_HEUTE; };
hidspecial HID_FUNC_WOCHENTAG { HelpID = HID_FUNC_WOCHENTAG; };
hidspecial HID_FUNC_JAHR { HelpID = HID_FUNC_JAHR; };
hidspecial HID_FUNC_TAGE { HelpID = HID_FUNC_TAGE; };
+hidspecial HID_FUNC_DATEDIF { HelpID = HID_FUNC_DATEDIF; };
hidspecial HID_FUNC_KALENDERWOCHE { HelpID = HID_FUNC_KALENDERWOCHE; };
hidspecial HID_FUNC_OSTERSONNTAG { HelpID = HID_FUNC_OSTERSONNTAG; };
hidspecial HID_FUNC_BW { HelpID = HID_FUNC_BW; };
hidspecial HID_FUNC_ZW { HelpID = HID_FUNC_ZW; };
hidspecial HID_FUNC_ZZR { HelpID = HID_FUNC_ZZR; };
hidspecial HID_FUNC_RMZ { HelpID = HID_FUNC_RMZ; };