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
@@ -399,10 +399,11 @@
399#define SC_OPCODE_BITXOR 397 399#define SC_OPCODE_BITXOR 397
400#define SC_OPCODE_BITRSHIFT 398 400#define SC_OPCODE_BITRSHIFT 398
401#define SC_OPCODE_BITLSHIFT 399 401#define SC_OPCODE_BITLSHIFT 399
402#define SC_OPCODE_STOP_2_PAR 400 402#define SC_OPCODE_GET_DATEDIF 400
403#define SC_OPCODE_LAST_OPCODE_ID 399 /* last OpCode */ 403#define SC_OPCODE_STOP_2_PAR 401
404#define SC_OPCODE_LAST_OPCODE_ID 401 /* last OpCode */
404 405
405/*** Interna ***/ 406/*** Internal ***/
406#define SC_OPCODE_INTERNAL_BEGIN 9999 407#define SC_OPCODE_INTERNAL_BEGIN 9999
407#define SC_OPCODE_TTT 9999 408#define SC_OPCODE_TTT 9999
408#define SC_OPCODE_INTERNAL_END 9999 409#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
212 ocGetTime = SC_OPCODE_GET_TIME, 212 ocGetTime = SC_OPCODE_GET_TIME,
213 ocGetDiffDate = SC_OPCODE_GET_DIFF_DATE, 213 ocGetDiffDate = SC_OPCODE_GET_DIFF_DATE,
214 ocGetDiffDate360 = SC_OPCODE_GET_DIFF_DATE_360, 214 ocGetDiffDate360 = SC_OPCODE_GET_DIFF_DATE_360,
215 ocGetDateDif = SC_OPCODE_GET_DATEDIF,
215 ocMin = SC_OPCODE_MIN, 216 ocMin = SC_OPCODE_MIN,
216 ocMax = SC_OPCODE_MAX, 217 ocMax = SC_OPCODE_MAX,
217 ocSum = SC_OPCODE_SUM, 218 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
170 String SC_OPCODE_GET_TIME { Text = "TIME" ; }; 170 String SC_OPCODE_GET_TIME { Text = "TIME" ; };
171 String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; }; 171 String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; };
172 String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; }; 172 String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; };
173 String SC_OPCODE_GET_DATEDIF { Text = "DATEDIF" ; };
173 String SC_OPCODE_MIN { Text = "MIN" ; }; 174 String SC_OPCODE_MIN { Text = "MIN" ; };
174 String SC_OPCODE_MIN_A { Text = "MINA" ; }; 175 String SC_OPCODE_MIN_A { Text = "MINA" ; };
175 String SC_OPCODE_MAX { Text = "MAX" ; }; 176 String SC_OPCODE_MAX { Text = "MAX" ; };
@@ -502,6 +503,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
502 String SC_OPCODE_GET_TIME { Text = "TIME" ; }; 503 String SC_OPCODE_GET_TIME { Text = "TIME" ; };
503 String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; }; 504 String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; };
504 String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; }; 505 String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; };
506 String SC_OPCODE_GET_DATEDIF { Text = "DATEDIF" ; };
505 String SC_OPCODE_MIN { Text = "MIN" ; }; 507 String SC_OPCODE_MIN { Text = "MIN" ; };
506 String SC_OPCODE_MIN_A { Text = "MINA" ; }; 508 String SC_OPCODE_MIN_A { Text = "MINA" ; };
507 String SC_OPCODE_MAX { Text = "MAX" ; }; 509 String SC_OPCODE_MAX { Text = "MAX" ; };
@@ -1175,6 +1177,10 @@ Resource RID_STRLIST_FUNCTION_NAMES
1175 { 1177 {
1176 Text [ en-US ] = "DAYS360" ; 1178 Text [ en-US ] = "DAYS360" ;
1177 }; 1179 };
1180 String SC_OPCODE_GET_DATEDIF
1181 {
1182 Text [ en-US ] = "DATEDIF" ;
1183 };
1178 String SC_OPCODE_MIN 1184 String SC_OPCODE_MIN
1179 { 1185 {
1180 Text [ en-US ] = "MIN" ; 1186 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 @@
434#define HID_FUNC_WOCHENTAG "SC_HID_FUNC_WOCHENTAG" 434#define HID_FUNC_WOCHENTAG "SC_HID_FUNC_WOCHENTAG"
435#define HID_FUNC_JAHR "SC_HID_FUNC_JAHR" 435#define HID_FUNC_JAHR "SC_HID_FUNC_JAHR"
436#define HID_FUNC_TAGE "SC_HID_FUNC_TAGE" 436#define HID_FUNC_TAGE "SC_HID_FUNC_TAGE"
437#define HID_FUNC_DATEDIF "SC_HID_FUNC_DATEDIF"
437#define HID_FUNC_KALENDERWOCHE "SC_HID_FUNC_KALENDERWOCHE" 438#define HID_FUNC_KALENDERWOCHE "SC_HID_FUNC_KALENDERWOCHE"
438#define HID_FUNC_OSTERSONNTAG "SC_HID_FUNC_OSTERSONNTAG" 439#define HID_FUNC_OSTERSONNTAG "SC_HID_FUNC_OSTERSONNTAG"
439 440
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()
3076 3076
3077 const char* aDateTime[] = { 3077 const char* aDateTime[] = {
3078 "DATE", 3078 "DATE",
3079 "DATEDIF",
3079 "DATEVALUE", 3080 "DATEVALUE",
3080 "DAY", 3081 "DAY",
3081 "DAYS", 3082 "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();
591void ScGetTime(); 591void ScGetTime();
592void ScGetDiffDate(); 592void ScGetDiffDate();
593void ScGetDiffDate360(); 593void ScGetDiffDate360();
594void ScGetDateDif();
594void ScPower(); 595void ScPower();
595void ScAmpersand(); 596void ScAmpersand();
596void ScAdd(); 597void 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()
412 } 412 }
413} 413}
414 414
415//fdo#44456 function DATEDIF as defined in ODF1.2 (Par. 6.10.3)
416void ScInterpreter::ScGetDateDif()
417{
418 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDateDif" );
419 if ( MustHaveParamCount( GetByte(), 3 ) )
420 {
421 String aFormat = GetString();
422 double nDate2 = GetDouble();
423 double nDate1 = GetDouble();
424 int dd = nDate2 - nDate1;
425
426 //split dates in day, month, year for use with formats other than "d"
427 int d1, m1, y1, d2, m2, y2;
428 Date aDate = *( pFormatter->GetNullDate() );
429 aDate += (long) ::rtl::math::approxFloor( nDate1 );
430 y1 = aDate.GetYear();
431 m1 = aDate.GetMonth();
432 d1 = aDate.GetDay();
433 aDate = *( pFormatter->GetNullDate() );
434 aDate += (long) ::rtl::math::approxFloor( nDate2 );
435 y2 = aDate.GetYear();
436 m2 = aDate.GetMonth();
437 d2 = aDate.GetDay();
438
439 if ( dd == 0 )
440 PushInt( 0 ); // nothing to do...
441
442 if ( aFormat.EqualsIgnoreCaseAscii( "d" ) ) // return number of days
443 PushInt( dd );
444 else if ( aFormat.EqualsIgnoreCaseAscii( "m" ) ) // return number of months
445 {
446 int md = m2 - m1 + 12 * (y2 - y1);
447 if ( nDate2 > nDate1 )
448 {
449 if ( d2 < d1 )
450 md -= 1;
451 }
452 else
453 {
454 if ( d2 > d1 )
455 md += 1;
456 }
457 PushInt( md );
458 }
459 else if ( aFormat.EqualsIgnoreCaseAscii( "y" ) ) // return number of years
460 {
461 int yd = y2 - y1;
462 if ( y2 > y1 )
463 {
464 if ( ( m2 == m1 and d2 >= d1 ) || ( m2 > m1 ) )
465 yd = y2 - y1 - 1;
466 }
467 else
468 {
469 if ( ( m2 == m1 and d2 <= d1 ) || ( m2 < m1 ) )
470 yd = y2 - y1 + 1;
471 }
472 PushInt( yd );
473 }
474 else if ( aFormat.EqualsIgnoreCaseAscii( "md" ) ) // return number of days, ignoring months and years
475 {
476 aDate = Date( d2, m1, y1 );
477 double nd2 = double( aDate - *( pFormatter->GetNullDate() ) );
478 PushInt( nd2 - nDate1 );
479 }
480 else if ( aFormat.EqualsIgnoreCaseAscii( "ym" ) ) // return number of months, ignoring years
481 {
482 int md = m2 - m1;
483 if ( m2 > m1 )
484 {
485 if ( d2 < d1 )
486 md -= 1;
487 }
488 else
489 {
490 if ( m2 < m1 && d2 > d1 )
491 md += 1;
492 }
493 PushInt( md );
494 }
495 else if ( aFormat.EqualsIgnoreCaseAscii( "yd" ) ) // return number of days, ignoring years
496 {
497 aDate = Date( d2, m2, y1 );
498 double nd2 = double( aDate - *( pFormatter->GetNullDate() ) );
499 PushInt( nd2 - nDate1 );
500 }
501 else
502 PushIllegalArgument(); // unsupported format
503 }
504}
505
415void ScInterpreter::ScGetTimeValue() 506void ScInterpreter::ScGetTimeValue()
416{ 507{
417 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTimeValue" ); 508 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()
3910 case ocGetTime : ScGetTime(); break; 3910 case ocGetTime : ScGetTime(); break;
3911 case ocGetDiffDate : ScGetDiffDate(); break; 3911 case ocGetDiffDate : ScGetDiffDate(); break;
3912 case ocGetDiffDate360 : ScGetDiffDate360(); break; 3912 case ocGetDiffDate360 : ScGetDiffDate360(); break;
3913 case ocGetDateDif : ScGetDateDif(); break;
3913 case ocMin : ScMin( false ); break; 3914 case ocMin : ScMin( false ); break;
3914 case ocMinA : ScMin( true ); break; 3915 case ocMinA : ScMin( true ); break;
3915 case ocMax : ScMax( false ); break; 3916 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[] =
382 EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ), 382 EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ),
383 EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ), 383 EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ),
384 EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ), 384 EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ),
385 EXC_FUNCENTRY_ODF( ocGetDateDif, 3, 3, 0, "DATEDIF" ),
385 EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ), 386 EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ),
386 EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ), 387 EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ),
387 EXC_FUNCENTRY_ODF( ocFDist, 3, 4, 0, "FDIST" ), 388 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[] =
665 { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { RO, VR }, 0 }, 665 { "COUNTIF", "COUNTIF", 346, 346, 2, 2, V, { RO, VR }, 0 },
666 { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 }, 666 { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 },
667 { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 }, 667 { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 },
668 { 0, "DATEDIF", 351, 351, 3, 3, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc
669 { 0, "DATESTRING", 352, 352, 1, 1, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec 668 { 0, "DATESTRING", 352, 352, 1, 1, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec
670 { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec 669 { 0, "NUMBERSTRING", 353, 353, 2, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, // not supported in Calc, missing in OOXML spec
671 { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { VR }, 0 }, 670 { "ROMAN", "ROMAN", 354, 354, 1, 2, V, { VR }, 0 },
@@ -742,6 +741,7 @@ static const FunctionData saFuncTableOdf[] =
742 { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 741 { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
743 { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 742 { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
744 { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 743 { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
744 { "DATEDIF", 0, NOID, NOID, 3, 3, V, { RR }, FUNCFLAG_MACROCALLODF },
745 { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, 745 { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
746 { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF }, 746 { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF },
747 { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, 747 { "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
972 Text [ en-US ] = "The start date for calculating the difference in days." ; 972 Text [ en-US ] = "The start date for calculating the difference in days." ;
973 }; 973 };
974 }; 974 };
975 // -=*# Resource for function DATEDIF #*=-
976 Resource SC_OPCODE_GET_DATEDIF
977 {
978 String 1 // description
979 {
980 Text [ en-US ] = "Returns the number of whole days, months or years between 'start date' and 'end date'";
981 };
982 ExtraData =
983 {
984 0;
985 ID_FUNCTION_GRP_DATETIME;
986 U2S( HID_FUNC_DATEDIF );
987 3; 0; 0; 0;
988 0;
989 };
990
991 String 2 // name of parameter 1 DateDif
992 {
993 Text [ en-US ] = "Start date";
994 };
995
996 String 3 // description of parameter 1 DateDif
997 {
998 Text [ en-US ] = "The start date";
999 };
1000
1001 String 4 // name of parameter 2 DateDif
1002 {
1003 Text [ en-US ] = "End date";
1004 };
1005
1006 String 5 // description of parameter 2 DateDif
1007 {
1008 Text [ en-US ] = "The end date";
1009 };
1010
1011 String 6 // name of parameter 3 DateDif
1012 {
1013 Text [ en-US ] = "Format";
1014 };
1015
1016 String 7 // description of parameter 3 DateDif
1017 {
1018 Text [ en-US ] = "Format of the result";
1019 };
1020 };
975 // -=*# Resource for function KALENDERWOCHE #*=- 1021 // -=*# Resource for function KALENDERWOCHE #*=-
976 Resource SC_OPCODE_WEEK 1022 Resource SC_OPCODE_WEEK
977 { 1023 {
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; };
113hidspecial HID_FUNC_WOCHENTAG { HelpID = HID_FUNC_WOCHENTAG; }; 113hidspecial HID_FUNC_WOCHENTAG { HelpID = HID_FUNC_WOCHENTAG; };
114hidspecial HID_FUNC_JAHR { HelpID = HID_FUNC_JAHR; }; 114hidspecial HID_FUNC_JAHR { HelpID = HID_FUNC_JAHR; };
115hidspecial HID_FUNC_TAGE { HelpID = HID_FUNC_TAGE; }; 115hidspecial HID_FUNC_TAGE { HelpID = HID_FUNC_TAGE; };
116hidspecial HID_FUNC_DATEDIF { HelpID = HID_FUNC_DATEDIF; };
116hidspecial HID_FUNC_KALENDERWOCHE { HelpID = HID_FUNC_KALENDERWOCHE; }; 117hidspecial HID_FUNC_KALENDERWOCHE { HelpID = HID_FUNC_KALENDERWOCHE; };
117hidspecial HID_FUNC_OSTERSONNTAG { HelpID = HID_FUNC_OSTERSONNTAG; }; 118hidspecial HID_FUNC_OSTERSONNTAG { HelpID = HID_FUNC_OSTERSONNTAG; };
118hidspecial HID_FUNC_BW { HelpID = HID_FUNC_BW; }; 119hidspecial HID_FUNC_BW { HelpID = HID_FUNC_BW; };