diff options
author | Winfried Donkers <osc@dci-electronics.nl> | 2012-05-09 16:47:13 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2012-05-13 13:51:13 +0200 |
commit | 4e71be498903dee5bf719a73f4976bb5356335dd (patch) | |
tree | be542ccf54df83afe75f56ae341b11c66afedef9 /sc | |
parent | 2068144fdcfdee3abe2a90b3b4b3bd49589618f2 (diff) |
fdo#44456 added calc function DATEDIF as in ODF1.2
Change-Id: I082ea20d02bf37d515fc33d627281696fc48fcb6
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/helpids.h | 1 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/interpr2.cxx | 91 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 1 | ||||
-rw-r--r-- | sc/source/filter/excel/xlformula.cxx | 1 | ||||
-rw-r--r-- | sc/source/filter/oox/formulabase.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/src/scfuncs.src | 46 | ||||
-rw-r--r-- | sc/util/hidother.src | 1 |
9 files changed, 144 insertions, 1 deletions
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 @@ -434,6 +434,7 @@ #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" 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 @@ -3076,6 +3076,7 @@ void Test::testFunctionLists() const char* aDateTime[] = { "DATE", + "DATEDIF", "DATEVALUE", "DAY", "DAYS", 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 { 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 @@ -113,6 +113,7 @@ 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; }; |