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 | |
parent | 2068144fdcfdee3abe2a90b3b4b3bd49589618f2 (diff) |
fdo#44456 added calc function DATEDIF as in ODF1.2
Change-Id: I082ea20d02bf37d515fc33d627281696fc48fcb6
-rw-r--r-- | formula/inc/formula/compiler.hrc | 7 | ||||
-rw-r--r-- | formula/inc/formula/opcode.hxx | 1 | ||||
-rw-r--r-- | formula/source/core/resource/core_resource.src | 6 | ||||
-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 |
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; }; |