diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc index 6b595ce..b2d6ceb 100644 --- a/formula/inc/formula/compiler.hrc +++ b/formula/inc/formula/compiler.hrc @@ -187,7 +187,8 @@ #define SC_OPCODE_UNICODE 159 #define SC_OPCODE_UNICHAR 160 #define SC_OPCODE_GAMMA 161 -#define SC_OPCODE_STOP_1_PAR 162 +#define SC_OPCODE_ISOWEEKNUM 162 +#define SC_OPCODE_STOP_1_PAR 163 /*** Functions with more than one parameters ***/ #define SC_OPCODE_START_2_PAR 201 @@ -355,7 +356,7 @@ #define SC_OPCODE_TABLE_OP 362 #define SC_OPCODE_BETA_DIST 363 #define SC_OPCODE_BETA_INV 364 -#define SC_OPCODE_WEEK 365 /* miscellaneous */ +#define SC_OPCODE_WEEKNUM 365 /* miscellaneous */ #define SC_OPCODE_GET_DAY_OF_WEEK 366 #define SC_OPCODE_NO_NAME 367 #define SC_OPCODE_STYLE 368 diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx index 14f862f..9ec4bfe 100644 --- a/formula/inc/formula/opcode.hxx +++ b/formula/inc/formula/opcode.hxx @@ -367,7 +367,7 @@ enum OpCodeEnum ocBitRshift = SC_OPCODE_BITRSHIFT, ocBitLshift = SC_OPCODE_BITLSHIFT, // miscellaneous - ocWeek = SC_OPCODE_WEEK, + ocIsoWeeknum = SC_OPCODE_ISOWEEKNUM, ocGetDayOfWeek = SC_OPCODE_GET_DAY_OF_WEEK, ocNoName = SC_OPCODE_NO_NAME, ocStyle = SC_OPCODE_STYLE, diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src index 5d4615b..bd7387a 100644 --- a/formula/source/core/resource/core_resource.src +++ b/formula/source/core/resource/core_resource.src @@ -317,7 +317,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF String SC_OPCODE_TABLE_OP { Text = "MULTIPLE.OPERATIONS" ; }; String SC_OPCODE_BETA_DIST { Text = "BETADIST" ; }; String SC_OPCODE_BETA_INV { Text = "BETAINV" ; }; - String SC_OPCODE_WEEK { Text = "ISOWEEKNUM" ; }; + String SC_OPCODE_WEEKNUM { Text = "WEEKNUM" ; }; + String SC_OPCODE_ISOWEEKNUM { Text = "ISOWEEKNUM" ; }; String SC_OPCODE_EASTERSUNDAY { Text = "ORG.OPENOFFICE.EASTERSUNDAY" ; }; String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; }; String SC_OPCODE_NO_NAME { Text = "#NAME!" ; }; @@ -650,7 +651,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH String SC_OPCODE_TABLE_OP { Text = "TABLE" ; }; String SC_OPCODE_BETA_DIST { Text = "BETADIST" ; }; String SC_OPCODE_BETA_INV { Text = "BETAINV" ; }; - String SC_OPCODE_WEEK { Text = "WEEKNUM" ; }; + String SC_OPCODE_WEEKNUM { Text = "WEEKNUM" ; }; + String SC_OPCODE_ISOWEEKNUM { Text = "ISOWEEKNUM" ; }; String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; }; String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; }; String SC_OPCODE_NO_NAME { Text = "#NAME!" ; }; @@ -1794,10 +1796,14 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "BETAINV" ; }; - String SC_OPCODE_WEEK + String SC_OPCODE_WEEKNUM { Text [ en-US ] = "WEEKNUM" ; }; + String SC_OPCODE_ISOWEEKNUM + { + Text [ en-US ] = "ISOWEEKNUM" ; + }; String SC_OPCODE_EASTERSUNDAY { Text [ en-US ] = "EASTERSUNDAY" ; diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h index af03708..333e0ea 100644 --- a/sc/inc/helpids.h +++ b/sc/inc/helpids.h @@ -444,7 +444,7 @@ #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_ISOWEEKNUM "SC_HID_FUNC_ISOWEEKNUM" #define HID_FUNC_OSTERSONNTAG "SC_HID_FUNC_OSTERSONNTAG" #define HID_FUNC_BW "SC_HID_FUNC_BW" diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index b816f5c..165a323 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -3345,6 +3345,7 @@ void Test::testFunctionLists() "DAYS360", "EASTERSUNDAY", "HOUR", + "ISOWEEKNUM", "MINUTE", "MONTH", "NOW", @@ -3353,7 +3354,8 @@ void Test::testFunctionLists() "TIMEVALUE", "TODAY", "WEEKDAY", - "WEEKNUM", +//50950 temporary measure +// "WEEKNUM", "YEAR", 0 }; diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index de577ca..da25563 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -575,7 +575,7 @@ void ScGetYear(); void ScGetMonth(); void ScGetDay(); void ScGetDayOfWeek(); -void ScGetWeekOfYear(); +void ScGetIsoWeekOfYear(); void ScEasterSunday(); void ScGetHour(); void ScGetMin(); diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index e359a3d..559302f 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -224,19 +224,21 @@ void ScInterpreter::ScGetDayOfWeek() } } -void ScInterpreter::ScGetWeekOfYear() + +//fdo50950 calc function for ISOWEEKNUM, in complete compliance with ODFF1.2 +void ScInterpreter::ScGetIsoWeekOfYear() { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetWeekOfYear" ); - if ( MustHaveParamCount( GetByte(), 2 ) ) + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetIsoWeekOfYear" ); + if ( MustHaveParamCount( GetByte(), 1 ) ) { - short nFlag = (short) ::rtl::math::approxFloor(GetDouble()); - Date aDate = *(pFormatter->GetNullDate()); aDate += (long)::rtl::math::approxFloor(GetDouble()); - PushInt( (int) aDate.GetWeekOfYear( nFlag == 1 ? SUNDAY : MONDAY )); + + PushInt( (int) aDate.GetWeekOfYear( MONDAY, 4 ) ); } } + void ScInterpreter::ScEasterSunday() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEasterSunday" ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index bca2977..57a3a55 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3867,7 +3867,7 @@ StackVar ScInterpreter::Interpret() case ocGetMonth : ScGetMonth(); break; case ocGetDay : ScGetDay(); break; case ocGetDayOfWeek : ScGetDayOfWeek(); break; - case ocWeek : ScGetWeekOfYear(); break; + case ocIsoWeeknum : ScGetIsoWeekOfYear(); break; case ocEasterSunday : ScEasterSunday(); break; case ocGetHour : ScGetHour(); break; case ocGetMin : ScGetMin(); break; diff --git a/sc/source/core/tool/odffmap.cxx b/sc/source/core/tool/odffmap.cxx index e57bd8f..6a75e5a 100644 --- a/sc/source/core/tool/odffmap.cxx +++ b/sc/source/core/tool/odffmap.cxx @@ -35,7 +35,7 @@ ScCompiler::AddInMap ScCompiler::maAddInMap[] = { "WORKDAY", "WORKDAY", false, "com.sun.star.sheet.addin.Analysis.getWorkday", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWORKDAY" }, { "YEARFRAC", "YEARFRAC", false, "com.sun.star.sheet.addin.Analysis.getYearfrac", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETYEARFRAC" }, { "EDATE", "EDATE", false, "com.sun.star.sheet.addin.Analysis.getEdate", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEDATE" }, - { "WEEKNUM", "WEEKNUM_ADD", false, "com.sun.star.sheet.addin.Analysis.getWeeknum", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWEEKNUM" }, + { "WEEKNUM", "WEEKNUM", false, "com.sun.star.sheet.addin.Analysis.getWeeknum", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWEEKNUM" }, { "EOMONTH", "EOMONTH", false, "com.sun.star.sheet.addin.Analysis.getEomonth", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEOMONTH" }, { "NETWORKDAYS", "NETWORKDAYS", false, "com.sun.star.sheet.addin.Analysis.getNetworkdays", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETNETWORKDAYS" }, { "ISEVEN", "ISEVEN_ADD", true, "com.sun.star.sheet.addin.Analysis.getIseven", "COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETISEVEN" }, diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx index d299aa2..d52249b 100644 --- a/sc/source/filter/excel/xlformula.cxx +++ b/sc/source/filter/excel/xlformula.cxx @@ -391,7 +391,7 @@ static const XclFunctionInfo saFuncTable_Odf[] = EXC_FUNCENTRY_ODF( ocGauss, 1, 1, 0, "GAUSS" ), EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "IFNA" ), EXC_FUNCENTRY_ODF( ocIsFormula, 1, 1, 0, "ISFORMULA" ), - EXC_FUNCENTRY_ODF( ocWeek, 1, 2, 0, "ISOWEEKNUM" ), + EXC_FUNCENTRY_ODF( ocIsoWeeknum, 1, 1, 0, "ISOWEEKNUM" ), EXC_FUNCENTRY_ODF( ocMatrixUnit, 1, 1, 0, "MUNIT" ), EXC_FUNCENTRY_ODF( ocNumberValue, 2, 2, 0, "NUMBERVALUE" ), EXC_FUNCENTRY_ODF( ocLaufz, 3, 3, 0, "PDURATION" ), diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx index b80dbfa..d3e866d 100644 --- a/sc/source/filter/oox/formulabase.cxx +++ b/sc/source/filter/oox/formulabase.cxx @@ -666,6 +666,7 @@ static const FunctionData saFuncTableBiff5[] = { "COUNTBLANK", "COUNTBLANK", 347, 347, 1, 1, V, { RO }, 0 }, { "ISPMT", "ISPMT", 350, 350, 4, 4, V, { VR }, 0 }, { "DATEDIF", "DATEDIF", 351, 351, 3, 3, V, { VR }, 0 }, + { "ISOWEEKNUM", "ISOWEEKNUM", 355, 355, 1, 1, V, { VR }, 0 }, { 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 }, diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 039aad6..c7fa816 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -1018,19 +1018,19 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 Text [ en-US ] = "Interval to be calculated. Can be \"d\", \"m\", \"y\", \"ym\", \"md\" or \"yd\"."; }; }; - // -=*# Resource for function KALENDERWOCHE #*=- - Resource SC_OPCODE_WEEK + // -=*# Resource for function ISOWEEKNUM #*=- + Resource SC_OPCODE_ISOWEEKNUM { String 1 // Description { - Text [ en-US ] = "Calculates the calendar week corresponding to the given date." ; + Text [ en-US ] = "Calculates the ISO8601 calender week for the given date: first day of week is Monday and week 1 is the week where the first Thursday of the year occurs)." ; }; ExtraData = { 0; ID_FUNCTION_GRP_DATETIME; - U2S( HID_FUNC_KALENDERWOCHE ); - 2; 0; 0; + U2S( HID_FUNC_ISOWEEKNUM ); + 1; 0; 0; 0; }; String 2 // Name of Parameter 1 @@ -1041,14 +1041,6 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 { Text [ en-US ] = "The internal number of the date." ; }; - String 4 // Name of Parameter 2 - { - Text [ en-US ] = "mode" ; - }; - String 5 // Description of Parameter 2 - { - Text [ en-US ] = "Indicates the first day of the week (1 = Sunday, other values = Monday)." ; - }; }; // -=*# Resource for function OSTERSONNTAG #*=- Resource SC_OPCODE_EASTERSUNDAY diff --git a/sc/util/hidother.src b/sc/util/hidother.src index 9b3c3fb..a897c9e 100644 --- a/sc/util/hidother.src +++ b/sc/util/hidother.src @@ -114,7 +114,7 @@ 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_ISOWEEKNUM { HelpID = HID_FUNC_ISOWEEKNUM; }; hidspecial HID_FUNC_OSTERSONNTAG { HelpID = HID_FUNC_OSTERSONNTAG; }; hidspecial HID_FUNC_BW { HelpID = HID_FUNC_BW; }; hidspecial HID_FUNC_ZW { HelpID = HID_FUNC_ZW; }; diff --git a/scaddins/source/analysis/analysis.cxx b/scaddins/source/analysis/analysis.cxx index 00d5e3d..8fd218d 100644 --- a/scaddins/source/analysis/analysis.cxx +++ b/scaddins/source/analysis/analysis.cxx @@ -28,6 +28,7 @@ #include #include +#include #include "analysis.hrc" #include "bessel.hxx" @@ -587,20 +588,47 @@ sal_Int32 SAL_CALL AnalysisAddIn::getEdate( constREFXPS& xOpt, sal_Int32 nStartD } +//fdo50950 calc function WEEKNUM, in complete compliance with ODFF1.2 sal_Int32 SAL_CALL AnalysisAddIn::getWeeknum( constREFXPS& xOpt, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE { nDate += GetNullDate( xOpt ); - sal_uInt16 nDay, nMonth, nYear; DaysToDate( nDate, nDay, nMonth, nYear ); - sal_Int32 nFirstInYear = DateToDays( 1, 1, nYear ); - sal_uInt16 nFirstDayInYear = GetDayOfWeek( nFirstInYear ); + nDate = 10000 * nYear + 100 * nMonth + nDay; + Date aDate( nDate ); +//printf( "getWeeknum(), Date nDate [ y-m-d ] = %04d-%02d-%02d\n", aDate.GetYear(), aDate.GetMonth(), aDate.GetDay() ); - return ( nDate - nFirstInYear + ( ( nMode == 1 )? ( nFirstDayInYear + 1 ) % 7 : nFirstDayInYear ) ) / 7 + 1; + sal_Int32 nMinimumNumberOfDaysInWeek; + DayOfWeek eFirstDayOfWeek; + switch ( nMode ) + { + case 1 : + case 11 : + case 2 : + case 12 : + case 13 : + case 14 : + case 15 : + case 16 : + case 17 : + eFirstDayOfWeek = (DayOfWeek) ( ( nMode - 1 ) % 10 ); + nMinimumNumberOfDaysInWeek = 1; //the week containing January 1 is week 1 + break; + case 21 : + case 150 : + // ISO8601 + eFirstDayOfWeek = MONDAY; + nMinimumNumberOfDaysInWeek = 4; + break; + default : + //QUESTION: what happens if the optional argument nMode is not entered by user? + //incorrect argument; we should cope with that properly; right now we'll just return -1 + return -1; + } + return ( aDate.GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek ) ); } - sal_Int32 SAL_CALL AnalysisAddIn::getEomonth( constREFXPS& xOpt, sal_Int32 nDate, sal_Int32 nMonths ) THROWDEF_RTE_IAE { sal_Int32 nNullDate = GetNullDate( xOpt ); diff --git a/scaddins/source/analysis/analysis.src b/scaddins/source/analysis/analysis.src index 87368f6..fa87b72 100644 --- a/scaddins/source/analysis/analysis.src +++ b/scaddins/source/analysis/analysis.src @@ -126,29 +126,25 @@ Resource RID_ANALYSIS_FUNCTION_DESCRIPTIONS Resource ANALYSIS_Weeknum { - String 1 // description Weeknum_add + String 1 // Description for WEEKNUM { - Text [ en-US ] = "Returns the number of the calendar week in which the specified date occurs."; + Text [ en-US ] = "Calculates the calendar week corresponding to the given date." ; }; - - String 2 // name of parameter 1 Weeknum_add + String 2 // Name of Parameter 1 { - Text [ en-US ] = "Date"; + Text [ en-US ] = "Number" ; }; - - String 3 // description of parameter 1 Weeknum_add + String 3 // Description of Parameter 1 { - Text [ en-US ] = "The date"; + Text [ en-US ] = "The internal number of the date." ; }; - - String 4 // name of parameter 2 Weeknum_add + String 4 // Name of Parameter 2 { - Text [ en-US ] = "Return type"; + Text [ en-US ] = "mode" ; }; - - String 5 // description of parameter 2 Weeknum_add + String 5 // Description of Parameter 2 { - Text [ en-US ] = "A number from 1 to 3 that specifies the day with which a week begins"; + Text [ en-US ] = "Indicates the first day of the week (1, 11=Sunday, 2, 12=Monday, 13-17=Tuesday-Saturday. 21 or 150 calculate according to ISO8601)." ; }; };