diff options
-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 @@ -399,10 +399,11 @@ #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 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 @@ -212,6 +212,7 @@ enum OpCodeEnum 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, 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 @@ -170,6 +170,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF 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" ; }; @@ -502,6 +503,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH 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" ; }; @@ -1175,6 +1177,10 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "DAYS360" ; }; + String SC_OPCODE_GET_DATEDIF + { + Text [ en-US ] = "DATEDIF" ; + }; String SC_OPCODE_MIN { Text [ en-US ] = "MIN" ; 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; }; |