summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source')
-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
6 files changed, 141 insertions, 1 deletions
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
@@ -591,6 +591,7 @@ void ScGetDate();
void ScGetTime();
void ScGetDiffDate();
void ScGetDiffDate360();
+void ScGetDateDif();
void ScPower();
void ScAmpersand();
void ScAdd();
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
@@ -412,6 +412,97 @@ void ScInterpreter::ScGetDiffDate360()
}
}
+//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" );
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
@@ -3910,6 +3910,7 @@ StackVar ScInterpreter::Interpret()
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;
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
@@ -382,6 +382,7 @@ static const XclFunctionInfo saFuncTable_Odf[] =
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" ),
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
@@ -665,7 +665,6 @@ static const FunctionData saFuncTableBiff5[] =
{ "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 },
@@ -742,6 +741,7 @@ static const FunctionData saFuncTableOdf[] =
{ "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 },
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
@@ -972,6 +972,52 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
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
{