This is an automated email from the ASF dual-hosted git repository. jimjag pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 33eb97adfc8d007cf8b9afdb6a8e64d35fe0aeb0 Author: Jim Jagielski <[email protected]> AuthorDate: Tue Nov 3 06:13:45 2026 -0500 ODF 1.4 Part 4: EASTERSUNDAY without a year and with a year range check, CONVERT unit SI_at --- main/formula/source/core/api/FormulaCompiler.cxx | 3 + main/sc/source/core/tool/interpr2.cxx | 75 +++++++++++++++++------- main/sc/source/ui/src/scfuncs.src | 4 +- main/scaddins/source/analysis/analysishelper.cxx | 1 + 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/main/formula/source/core/api/FormulaCompiler.cxx b/main/formula/source/core/api/FormulaCompiler.cxx index a60d450ffa..08aee41d6b 100644 --- a/main/formula/source/core/api/FormulaCompiler.cxx +++ b/main/formula/source/core/api/FormulaCompiler.cxx @@ -1065,6 +1065,9 @@ void FormulaCompiler::Factor() pFacToken = new FormulaFAPToken( pFacToken->GetOpCode(), nSepCount, pFacToken ); else pFacToken->SetByte( nSepCount ); + // EASTERSUNDAY() without a year depends on today's date + if ( bNoParam && pFacToken->GetOpCode() == ocEasterSunday ) + pArr->SetRecalcModeAlways(); PutCode( pFacToken ); } else if (eOp == ocIf || eOp == ocChose) diff --git a/main/sc/source/core/tool/interpr2.cxx b/main/sc/source/core/tool/interpr2.cxx index 32ac4abf4b..3624f73dd1 100644 --- a/main/sc/source/core/tool/interpr2.cxx +++ b/main/sc/source/core/tool/interpr2.cxx @@ -237,34 +237,65 @@ void ScInterpreter::ScGetWeekOfYear() } } +static void lcl_EasterSunday( sal_Int16 nYear, sal_Int16& rDay, sal_Int16& rMonth ) +{ + // don't worry, be happy :) + int B,C,D,E,F,G,H,I,K,L,M,N,O; + N = nYear % 19; + B = int(nYear / 100); + C = nYear % 100; + D = int(B / 4); + E = B % 4; + F = int((B + 8) / 25); + G = int((B - F + 1) / 3); + H = (19 * N + B - D - G + 15) % 30; + I = int(C / 4); + K = C % 4; + L = (32 + 2 * E + 2 * I - H - K) % 7; + M = int((N + 11 * H + 22 * L) / 451); + O = H + L - 7 * M + 114; + rDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 ); + rMonth = sal::static_int_cast<sal_Int16>( int(O / 31) ); +} + void ScInterpreter::ScEasterSunday() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEasterSunday" ); nFuncFmtType = NUMBERFORMAT_DATE; - if ( MustHaveParamCount( GetByte(), 1 ) ) + sal_uInt8 nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 0, 1 ) ) { sal_Int16 nDay, nMonth, nYear; - nYear = (sal_Int16) ::rtl::math::approxFloor( GetDouble() ); - if ( nYear < 100 ) - nYear = pFormatter->ExpandTwoDigitYear( nYear ); - // don't worry, be happy :) - int B,C,D,E,F,G,H,I,K,L,M,N,O; - N = nYear % 19; - B = int(nYear / 100); - C = nYear % 100; - D = int(B / 4); - E = B % 4; - F = int((B + 8) / 25); - G = int((B - F + 1) / 3); - H = (19 * N + B - D - G + 15) % 30; - I = int(C / 4); - K = C % 4; - L = (32 + 2 * E + 2 * I - H - K) % 7; - M = int((N + 11 * H + 22 * L) / 451); - O = H + L - 7 * M + 114; - nDay = sal::static_int_cast<sal_Int16>( O % 31 + 1 ); - nMonth = sal::static_int_cast<sal_Int16>( int(O / 31) ); - PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) ); + if ( nParamCount == 1 ) + { + double fYear = ::rtl::math::approxFloor( GetDouble() ); + // ODF 1.4 Part 4 6.10.8: 1583 <= Year <= 9956; checked before the cast to sal_Int16, which would wrap + if ( fYear < 0.0 || fYear > 9956.0 ) + { + PushIllegalArgument(); + return; + } + nYear = (sal_Int16) fYear; + if ( nYear < 100 ) + nYear = pFormatter->ExpandTwoDigitYear( nYear ); + lcl_EasterSunday( nYear, nDay, nMonth ); + PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) ); + } + else + { + // no Year: the next Easter Sunday on or after today + Date aActDate; + double fToday = (double) ( aActDate - *(pFormatter->GetNullDate()) ); + nYear = aActDate.GetYear(); + lcl_EasterSunday( nYear, nDay, nMonth ); + double fEaster = GetDateSerial( nYear, nMonth, nDay, true ); + if ( fEaster < fToday ) + { + lcl_EasterSunday( ++nYear, nDay, nMonth ); + fEaster = GetDateSerial( nYear, nMonth, nDay, true ); + } + PushDouble( fEaster ); + } } } diff --git a/main/sc/source/ui/src/scfuncs.src b/main/sc/source/ui/src/scfuncs.src index 9817aa7510..1a1e5dc059 100644 --- a/main/sc/source/ui/src/scfuncs.src +++ b/main/sc/source/ui/src/scfuncs.src @@ -1012,7 +1012,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 0; ID_FUNCTION_GRP_DATETIME; U2S( HID_FUNC_OSTERSONNTAG ); - 1; 0; + 1; 1; 0; }; String 2 // Name of Parameter 1 @@ -1021,7 +1021,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 }; String 3 // Description of Parameter 1 { - Text [ en-US ] = "An integer between 1583 and 9956, or 0 and 99 (19xx or 20xx depending on the option set)." ; + Text [ en-US ] = "An integer between 1583 and 9956, or 0 and 99 (19xx or 20xx depending on the option set). If omitted, the next Easter Sunday on or after today is returned." ; }; }; // -=*# Resource for function BW #*=- diff --git a/main/scaddins/source/analysis/analysishelper.cxx b/main/scaddins/source/analysis/analysishelper.cxx index ba09d389d3..22cc27ad15 100644 --- a/main/scaddins/source/analysis/analysishelper.cxx +++ b/main/scaddins/source/analysis/analysishelper.cxx @@ -2452,6 +2452,7 @@ ConvertDataList::ConvertDataList( void ) NEWDP( "Pa", 1.0000000000000000E00, CDC_Pressure ); // Pascal NEWDP( "atm", 9.8692329999819300E-06, CDC_Pressure ); // Atmosphere NEWDP( "at", 9.8692329999819300E-06, CDC_Pressure ); // Atmosphere also + NEWDP( "SI_at", 1.0197162129779282E-05, CDC_Pressure ); // Technical atmosphere (ODF 1.4) NEWDP( "mmHg", 7.5006170799862700E-03, CDC_Pressure ); // mm Hg (Mercury) NEWD( "Torr", 7.5006380000000000E-03, CDC_Pressure ); // *** Torr NEWD( "psi", 1.4503770000000000E-04, CDC_Pressure ); // *** Psi
