1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir //------------------------------------------------------------------ 29*cdf0e10cSrcweir // 30*cdf0e10cSrcweir // date functions add in 31*cdf0e10cSrcweir // 32*cdf0e10cSrcweir //------------------------------------------------------------------ 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include "datefunc.hxx" 35*cdf0e10cSrcweir #ifndef _SCA_DATEFUNC_HRC 36*cdf0e10cSrcweir #include "datefunc.hrc" 37*cdf0e10cSrcweir #endif 38*cdf0e10cSrcweir #include <cppuhelper/factory.hxx> 39*cdf0e10cSrcweir #include <osl/diagnose.h> 40*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 41*cdf0e10cSrcweir #include <tools/resmgr.hxx> 42*cdf0e10cSrcweir #include <tools/rcid.h> 43*cdf0e10cSrcweir #include <com/sun/star/util/Date.hpp> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir using namespace ::com::sun::star; 46*cdf0e10cSrcweir using namespace ::rtl; 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir //------------------------------------------------------------------ 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir #define ADDIN_SERVICE "com.sun.star.sheet.AddIn" 51*cdf0e10cSrcweir #define MY_SERVICE "com.sun.star.sheet.addin.DateFunctions" 52*cdf0e10cSrcweir #define MY_IMPLNAME "com.sun.star.sheet.addin.DateFunctionsImpl" 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir //------------------------------------------------------------------ 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #define STR_FROM_ANSI( s ) OUString( s, strlen( s ), RTL_TEXTENCODING_MS_1252 ) 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir //------------------------------------------------------------------ 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir const sal_uInt32 ScaList::nStartSize = 16; 61*cdf0e10cSrcweir const sal_uInt32 ScaList::nIncrSize = 16; 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir ScaList::ScaList() : 64*cdf0e10cSrcweir pData( new void*[ nStartSize ] ), 65*cdf0e10cSrcweir nSize( nStartSize ), 66*cdf0e10cSrcweir nCount( 0 ), 67*cdf0e10cSrcweir nCurr( 0 ) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir } 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir ScaList::~ScaList() 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir delete[] pData; 74*cdf0e10cSrcweir } 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir void ScaList::_Grow() 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir nSize += nIncrSize; 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir void** pNewData = new void*[ nSize ]; 81*cdf0e10cSrcweir memcpy( pNewData, pData, nCount * sizeof( void* ) ); 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir delete[] pData; 84*cdf0e10cSrcweir pData = pNewData; 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir void ScaList::Insert( void* pNew, sal_uInt32 nIndex ) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir if( nIndex >= nCount ) 90*cdf0e10cSrcweir Append( pNew ); 91*cdf0e10cSrcweir else 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir Grow(); 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir void** pIns = pData + nIndex; 96*cdf0e10cSrcweir memmove( pIns + 1, pIns, (nCount - nIndex) * sizeof( void* ) ); 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir *pIns = pNew; 99*cdf0e10cSrcweir nCount++; 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir //------------------------------------------------------------------ 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir ScaStringList::~ScaStringList() 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir for( OUString* pStr = First(); pStr; pStr = Next() ) 109*cdf0e10cSrcweir delete pStr; 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir //------------------------------------------------------------------ 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir ScaResId::ScaResId( sal_uInt16 nId, ResMgr& rResMgr ) : 115*cdf0e10cSrcweir ResId( nId, rResMgr ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir //------------------------------------------------------------------ 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir #define UNIQUE sal_False // function name does not exist in Calc 123*cdf0e10cSrcweir #define DOUBLE sal_True // function name exists in Calc 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir #define STDPAR sal_False // all parameters are described 126*cdf0e10cSrcweir #define INTPAR sal_True // first parameter is internal 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir #define FUNCDATA( FuncName, ParamCount, Category, Double, IntPar ) \ 129*cdf0e10cSrcweir { "get" #FuncName, DATE_FUNCNAME_##FuncName, DATE_FUNCDESC_##FuncName, DATE_DEFFUNCNAME_##FuncName, ParamCount, Category, Double, IntPar } 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir const ScaFuncDataBase pFuncDataArr[] = 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir FUNCDATA( DiffWeeks, 3, ScaCat_DateTime, UNIQUE, INTPAR ), 134*cdf0e10cSrcweir FUNCDATA( DiffMonths, 3, ScaCat_DateTime, UNIQUE, INTPAR ), 135*cdf0e10cSrcweir FUNCDATA( DiffYears, 3, ScaCat_DateTime, UNIQUE, INTPAR ), 136*cdf0e10cSrcweir FUNCDATA( IsLeapYear, 1, ScaCat_DateTime, UNIQUE, INTPAR ), 137*cdf0e10cSrcweir FUNCDATA( DaysInMonth, 1, ScaCat_DateTime, UNIQUE, INTPAR ), 138*cdf0e10cSrcweir FUNCDATA( DaysInYear, 1, ScaCat_DateTime, UNIQUE, INTPAR ), 139*cdf0e10cSrcweir FUNCDATA( WeeksInYear, 1, ScaCat_DateTime, UNIQUE, INTPAR ), 140*cdf0e10cSrcweir FUNCDATA( Rot13, 1, ScaCat_Text, UNIQUE, STDPAR ) 141*cdf0e10cSrcweir }; 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir #undef FUNCDATA 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir //------------------------------------------------------------------ 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir ScaFuncData::ScaFuncData( const ScaFuncDataBase& rBaseData, ResMgr& rResMgr ) : 149*cdf0e10cSrcweir aIntName( OUString::createFromAscii( rBaseData.pIntName ) ), 150*cdf0e10cSrcweir nUINameID( rBaseData.nUINameID ), 151*cdf0e10cSrcweir nDescrID( rBaseData.nDescrID ), 152*cdf0e10cSrcweir nCompListID( rBaseData.nCompListID ), 153*cdf0e10cSrcweir nParamCount( rBaseData.nParamCount ), 154*cdf0e10cSrcweir eCat( rBaseData.eCat ), 155*cdf0e10cSrcweir bDouble( rBaseData.bDouble ), 156*cdf0e10cSrcweir bWithOpt( rBaseData.bWithOpt ) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir ScaResStringArrLoader aArrLoader( RID_DATE_DEFFUNCTION_NAMES, nCompListID, rResMgr ); 159*cdf0e10cSrcweir const ResStringArray& rArr = aArrLoader.GetStringArray(); 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir for( sal_uInt16 nIndex = 0; nIndex < rArr.Count(); nIndex++ ) 162*cdf0e10cSrcweir aCompList.Append( rArr.GetString( nIndex ) ); 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir ScaFuncData::~ScaFuncData() 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir } 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir sal_uInt16 ScaFuncData::GetStrIndex( sal_uInt16 nParam ) const 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir if( !bWithOpt ) 172*cdf0e10cSrcweir nParam++; 173*cdf0e10cSrcweir return (nParam > nParamCount) ? (nParamCount * 2) : (nParam * 2); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir //------------------------------------------------------------------ 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir ScaFuncDataList::ScaFuncDataList( ResMgr& rResMgr ) : 180*cdf0e10cSrcweir nLast( 0xFFFFFFFF ) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir const sal_uInt32 nCnt = sizeof( pFuncDataArr ) / sizeof( ScaFuncDataBase ); 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir for( sal_uInt16 nIndex = 0; nIndex < nCnt; nIndex++ ) 185*cdf0e10cSrcweir Append( new ScaFuncData( pFuncDataArr[ nIndex ], rResMgr ) ); 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir ScaFuncDataList::~ScaFuncDataList() 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir for( ScaFuncData* pFData = First(); pFData; pFData = Next() ) 191*cdf0e10cSrcweir delete pFData; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir const ScaFuncData* ScaFuncDataList::Get( const OUString& rProgrammaticName ) const 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir if( aLastName == rProgrammaticName ) 197*cdf0e10cSrcweir return Get( nLast ); 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir for( sal_uInt32 nIndex = 0; nIndex < Count(); nIndex++ ) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir const ScaFuncData* pCurr = Get( nIndex ); 202*cdf0e10cSrcweir if( pCurr->Is( rProgrammaticName ) ) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir const_cast< ScaFuncDataList* >( this )->aLastName = rProgrammaticName; 205*cdf0e10cSrcweir const_cast< ScaFuncDataList* >( this )->nLast = nIndex; 206*cdf0e10cSrcweir return pCurr; 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir return NULL; 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir //------------------------------------------------------------------ 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir ScaFuncRes::ScaFuncRes( ResId& rResId, ResMgr& rResMgr, sal_uInt16 nIndex, OUString& rRet ) : 216*cdf0e10cSrcweir Resource( rResId ) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir rRet = String( ScaResId( nIndex, rResMgr ) ); 219*cdf0e10cSrcweir FreeResource(); 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir //------------------------------------------------------------------ 224*cdf0e10cSrcweir // 225*cdf0e10cSrcweir // entry points for service registration / instantiation 226*cdf0e10cSrcweir // 227*cdf0e10cSrcweir //------------------------------------------------------------------ 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL ScaDateAddIn_CreateInstance( 230*cdf0e10cSrcweir const uno::Reference< lang::XMultiServiceFactory >& ) 231*cdf0e10cSrcweir { 232*cdf0e10cSrcweir static uno::Reference< uno::XInterface > xInst = (cppu::OWeakObject*) new ScaDateAddIn(); 233*cdf0e10cSrcweir return xInst; 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir //------------------------------------------------------------------------ 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir extern "C" { 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir void SAL_CALL component_getImplementationEnvironment( 242*cdf0e10cSrcweir const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir void * SAL_CALL component_getFactory( 248*cdf0e10cSrcweir const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir void* pRet = 0; 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir if ( pServiceManager && 253*cdf0e10cSrcweir OUString::createFromAscii( pImplName ) == ScaDateAddIn::getImplementationName_Static() ) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir uno::Reference< lang::XSingleServiceFactory > xFactory( cppu::createOneInstanceFactory( 256*cdf0e10cSrcweir reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ), 257*cdf0e10cSrcweir ScaDateAddIn::getImplementationName_Static(), 258*cdf0e10cSrcweir ScaDateAddIn_CreateInstance, 259*cdf0e10cSrcweir ScaDateAddIn::getSupportedServiceNames_Static() ) ); 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir if (xFactory.is()) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir xFactory->acquire(); 264*cdf0e10cSrcweir pRet = xFactory.get(); 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir return pRet; 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir } // extern C 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir //------------------------------------------------------------------------ 274*cdf0e10cSrcweir // 275*cdf0e10cSrcweir // "normal" service implementation 276*cdf0e10cSrcweir // 277*cdf0e10cSrcweir //------------------------------------------------------------------------ 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir ScaDateAddIn::ScaDateAddIn() : 280*cdf0e10cSrcweir pDefLocales( NULL ), 281*cdf0e10cSrcweir pResMgr( NULL ), 282*cdf0e10cSrcweir pFuncDataList( NULL ) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir ScaDateAddIn::~ScaDateAddIn() 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir if( pFuncDataList ) 289*cdf0e10cSrcweir delete pFuncDataList; 290*cdf0e10cSrcweir if( pDefLocales ) 291*cdf0e10cSrcweir delete[] pDefLocales; 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir // pResMgr already deleted (_all_ resource managers are deleted _before_ this dtor is called) 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir static const sal_Char* pLang[] = { "de", "en" }; 297*cdf0e10cSrcweir static const sal_Char* pCoun[] = { "DE", "US" }; 298*cdf0e10cSrcweir static const sal_uInt32 nNumOfLoc = sizeof( pLang ) / sizeof( sal_Char* ); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir void ScaDateAddIn::InitDefLocales() 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir pDefLocales = new lang::Locale[ nNumOfLoc ]; 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir for( sal_uInt32 nIndex = 0; nIndex < nNumOfLoc; nIndex++ ) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir pDefLocales[ nIndex ].Language = OUString::createFromAscii( pLang[ nIndex ] ); 307*cdf0e10cSrcweir pDefLocales[ nIndex ].Country = OUString::createFromAscii( pCoun[ nIndex ] ); 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir const lang::Locale& ScaDateAddIn::GetLocale( sal_uInt32 nIndex ) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir if( !pDefLocales ) 314*cdf0e10cSrcweir InitDefLocales(); 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir return (nIndex < sizeof( pLang )) ? pDefLocales[ nIndex ] : aFuncLoc; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir ResMgr& ScaDateAddIn::GetResMgr() throw( uno::RuntimeException ) 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir if( !pResMgr ) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir InitData(); // try to get resource manager 324*cdf0e10cSrcweir if( !pResMgr ) 325*cdf0e10cSrcweir throw uno::RuntimeException(); 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir return *pResMgr; 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir void ScaDateAddIn::InitData() 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir if( pResMgr ) 333*cdf0e10cSrcweir delete pResMgr; 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir OString aModName( "date" ); 336*cdf0e10cSrcweir pResMgr = ResMgr::CreateResMgr( (const sal_Char*) aModName, 337*cdf0e10cSrcweir aFuncLoc ); 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir if( pFuncDataList ) 340*cdf0e10cSrcweir delete pFuncDataList; 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir pFuncDataList = pResMgr ? new ScaFuncDataList( *pResMgr ) : NULL; 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir if( pDefLocales ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir delete pDefLocales; 347*cdf0e10cSrcweir pDefLocales = NULL; 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir OUString ScaDateAddIn::GetDisplFuncStr( sal_uInt16 nResId ) throw( uno::RuntimeException ) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir return ScaResStringLoader( RID_DATE_FUNCTION_NAMES, nResId, GetResMgr() ).GetString(); 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir OUString ScaDateAddIn::GetFuncDescrStr( sal_uInt16 nResId, sal_uInt16 nStrIndex ) throw( uno::RuntimeException ) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir OUString aRet; 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir ScaResPublisher aResPubl( ScaResId( RID_DATE_FUNCTION_DESCRIPTIONS, GetResMgr() ) ); 361*cdf0e10cSrcweir ScaResId aResId( nResId, GetResMgr() ); 362*cdf0e10cSrcweir aResId.SetRT( RSC_RESOURCE ); 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir if( aResPubl.IsAvailableRes( aResId ) ) 365*cdf0e10cSrcweir ScaFuncRes aSubRes( aResId, GetResMgr(), nStrIndex, aRet ); 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir aResPubl.FreeResource(); 368*cdf0e10cSrcweir return aRet; 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir //------------------------------------------------------------------------ 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir OUString ScaDateAddIn::getImplementationName_Static() 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir return OUString::createFromAscii( MY_IMPLNAME ); 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir uno::Sequence< OUString > ScaDateAddIn::getSupportedServiceNames_Static() 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir uno::Sequence< OUString > aRet( 2 ); 382*cdf0e10cSrcweir OUString* pArray = aRet.getArray(); 383*cdf0e10cSrcweir pArray[0] = OUString::createFromAscii( ADDIN_SERVICE ); 384*cdf0e10cSrcweir pArray[1] = OUString::createFromAscii( MY_SERVICE ); 385*cdf0e10cSrcweir return aRet; 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir // XServiceName 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getServiceName() throw( uno::RuntimeException ) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir // name of specific AddIn service 393*cdf0e10cSrcweir return OUString::createFromAscii( MY_SERVICE ); 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir // XServiceInfo 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getImplementationName() throw( uno::RuntimeException ) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir return getImplementationName_Static(); 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir sal_Bool SAL_CALL ScaDateAddIn::supportsService( const OUString& aServiceName ) throw( uno::RuntimeException ) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir return aServiceName.equalsAscii( ADDIN_SERVICE ) || 406*cdf0e10cSrcweir aServiceName.equalsAscii( MY_SERVICE ); 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL ScaDateAddIn::getSupportedServiceNames() throw( uno::RuntimeException ) 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir return getSupportedServiceNames_Static(); 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir // XLocalizable 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir void SAL_CALL ScaDateAddIn::setLocale( const lang::Locale& eLocale ) throw( uno::RuntimeException ) 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir aFuncLoc = eLocale; 419*cdf0e10cSrcweir InitData(); // change of locale invalidates resources! 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir lang::Locale SAL_CALL ScaDateAddIn::getLocale() throw( uno::RuntimeException ) 423*cdf0e10cSrcweir { 424*cdf0e10cSrcweir return aFuncLoc; 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir //------------------------------------------------------------------ 428*cdf0e10cSrcweir // 429*cdf0e10cSrcweir // function descriptions start here 430*cdf0e10cSrcweir // 431*cdf0e10cSrcweir //------------------------------------------------------------------ 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir // XAddIn 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getProgrammaticFuntionName( const OUString& ) throw( uno::RuntimeException ) 436*cdf0e10cSrcweir { 437*cdf0e10cSrcweir // not used by calc 438*cdf0e10cSrcweir // (but should be implemented for other uses of the AddIn service) 439*cdf0e10cSrcweir return OUString(); 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir OUString aRet; 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName ); 447*cdf0e10cSrcweir if( pFData ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir aRet = GetDisplFuncStr( pFData->GetUINameID() ); 450*cdf0e10cSrcweir if( pFData->IsDouble() ) 451*cdf0e10cSrcweir aRet += STR_FROM_ANSI( "_ADD" ); 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir else 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir aRet = STR_FROM_ANSI( "UNKNOWNFUNC_" ); 456*cdf0e10cSrcweir aRet += aProgrammaticName; 457*cdf0e10cSrcweir } 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir return aRet; 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException ) 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir OUString aRet; 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName ); 467*cdf0e10cSrcweir if( pFData ) 468*cdf0e10cSrcweir aRet = GetFuncDescrStr( pFData->GetDescrID(), 1 ); 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir return aRet; 471*cdf0e10cSrcweir } 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getDisplayArgumentName( 474*cdf0e10cSrcweir const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException ) 475*cdf0e10cSrcweir { 476*cdf0e10cSrcweir OUString aRet; 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName ); 479*cdf0e10cSrcweir if( pFData && (nArgument <= 0xFFFF) ) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir sal_uInt16 nStr = pFData->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) ); 482*cdf0e10cSrcweir if( nStr ) 483*cdf0e10cSrcweir aRet = GetFuncDescrStr( pFData->GetDescrID(), nStr ); 484*cdf0e10cSrcweir else 485*cdf0e10cSrcweir aRet = STR_FROM_ANSI( "internal" ); 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir return aRet; 489*cdf0e10cSrcweir } 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getArgumentDescription( 492*cdf0e10cSrcweir const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException ) 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir OUString aRet; 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName ); 497*cdf0e10cSrcweir if( pFData && (nArgument <= 0xFFFF) ) 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir sal_uInt16 nStr = pFData->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) ); 500*cdf0e10cSrcweir if( nStr ) 501*cdf0e10cSrcweir aRet = GetFuncDescrStr( pFData->GetDescrID(), nStr + 1 ); 502*cdf0e10cSrcweir else 503*cdf0e10cSrcweir aRet = STR_FROM_ANSI( "for internal use only" ); 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir return aRet; 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getProgrammaticCategoryName( 510*cdf0e10cSrcweir const OUString& aProgrammaticName ) throw( uno::RuntimeException ) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir OUString aRet; 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName ); 515*cdf0e10cSrcweir if( pFData ) 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir switch( pFData->GetCategory() ) 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir case ScaCat_DateTime: aRet = STR_FROM_ANSI( "Date&Time" ); break; 520*cdf0e10cSrcweir case ScaCat_Text: aRet = STR_FROM_ANSI( "Text" ); break; 521*cdf0e10cSrcweir case ScaCat_Finance: aRet = STR_FROM_ANSI( "Financial" ); break; 522*cdf0e10cSrcweir case ScaCat_Inf: aRet = STR_FROM_ANSI( "Information" ); break; 523*cdf0e10cSrcweir case ScaCat_Math: aRet = STR_FROM_ANSI( "Mathematical" ); break; 524*cdf0e10cSrcweir case ScaCat_Tech: aRet = STR_FROM_ANSI( "Technical" ); break; 525*cdf0e10cSrcweir default: // to prevent compiler warnings 526*cdf0e10cSrcweir break; 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir if( !aRet.getLength() ) 531*cdf0e10cSrcweir aRet = STR_FROM_ANSI( "Add-In" ); 532*cdf0e10cSrcweir return aRet; 533*cdf0e10cSrcweir } 534*cdf0e10cSrcweir 535*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getDisplayCategoryName( 536*cdf0e10cSrcweir const OUString& aProgrammaticName ) throw( uno::RuntimeException ) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir return getProgrammaticCategoryName( aProgrammaticName ); 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir // XCompatibilityNames 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir uno::Sequence< sheet::LocalizedName > SAL_CALL ScaDateAddIn::getCompatibilityNames( 545*cdf0e10cSrcweir const OUString& aProgrammaticName ) throw( uno::RuntimeException ) 546*cdf0e10cSrcweir { 547*cdf0e10cSrcweir const ScaFuncData* pFData = pFuncDataList->Get( aProgrammaticName ); 548*cdf0e10cSrcweir if( !pFData ) 549*cdf0e10cSrcweir return uno::Sequence< sheet::LocalizedName >( 0 ); 550*cdf0e10cSrcweir 551*cdf0e10cSrcweir const ScaStringList& rStrList = pFData->GetCompNameList(); 552*cdf0e10cSrcweir sal_uInt32 nCount = rStrList.Count(); 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir uno::Sequence< sheet::LocalizedName > aRet( nCount ); 555*cdf0e10cSrcweir sheet::LocalizedName* pArray = aRet.getArray(); 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ ) 558*cdf0e10cSrcweir pArray[ nIndex ] = sheet::LocalizedName( GetLocale( nIndex ), *rStrList.Get( nIndex ) ); 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir return aRet; 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir //------------------------------------------------------------------ 565*cdf0e10cSrcweir // 566*cdf0e10cSrcweir // function implementation starts here 567*cdf0e10cSrcweir // 568*cdf0e10cSrcweir //------------------------------------------------------------------ 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir // auxiliary functions 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir sal_Bool IsLeapYear( sal_uInt16 nYear ) 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir return ((((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0)); 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear ) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir static sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30, 580*cdf0e10cSrcweir 31, 31, 30, 31, 30, 31 }; 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir if ( nMonth != 2 ) 583*cdf0e10cSrcweir return aDaysInMonth[nMonth-1]; 584*cdf0e10cSrcweir else 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir if ( IsLeapYear(nYear) ) 587*cdf0e10cSrcweir return aDaysInMonth[nMonth-1] + 1; 588*cdf0e10cSrcweir else 589*cdf0e10cSrcweir return aDaysInMonth[nMonth-1]; 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir /** 594*cdf0e10cSrcweir * Convert a date to a count of days starting from 01/01/0001 595*cdf0e10cSrcweir * 596*cdf0e10cSrcweir * The internal representation of a Date used in this Addin 597*cdf0e10cSrcweir * is the number of days between 01/01/0001 and the date 598*cdf0e10cSrcweir * this function converts a Day , Month, Year representation 599*cdf0e10cSrcweir * to this internal Date value. 600*cdf0e10cSrcweir */ 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ) 603*cdf0e10cSrcweir { 604*cdf0e10cSrcweir sal_Int32 nDays = ((sal_Int32)nYear-1) * 365; 605*cdf0e10cSrcweir nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400); 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir for( sal_uInt16 i = 1; i < nMonth; i++ ) 608*cdf0e10cSrcweir nDays += DaysInMonth(i,nYear); 609*cdf0e10cSrcweir nDays += nDay; 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir return nDays; 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir /** 615*cdf0e10cSrcweir * Convert a count of days starting from 01/01/0001 to a date 616*cdf0e10cSrcweir * 617*cdf0e10cSrcweir * The internal representation of a Date used in this Addin 618*cdf0e10cSrcweir * is the number of days between 01/01/0001 and the date 619*cdf0e10cSrcweir * this function converts this internal Date value 620*cdf0e10cSrcweir * to a Day , Month, Year representation of a Date. 621*cdf0e10cSrcweir */ 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir void DaysToDate( sal_Int32 nDays, 624*cdf0e10cSrcweir sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear ) 625*cdf0e10cSrcweir throw( lang::IllegalArgumentException ) 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir if( nDays < 0 ) 628*cdf0e10cSrcweir throw lang::IllegalArgumentException(); 629*cdf0e10cSrcweir 630*cdf0e10cSrcweir sal_Int32 nTempDays; 631*cdf0e10cSrcweir sal_Int32 i = 0; 632*cdf0e10cSrcweir sal_Bool bCalc; 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir do 635*cdf0e10cSrcweir { 636*cdf0e10cSrcweir nTempDays = nDays; 637*cdf0e10cSrcweir rYear = (sal_uInt16)((nTempDays / 365) - i); 638*cdf0e10cSrcweir nTempDays -= ((sal_Int32) rYear -1) * 365; 639*cdf0e10cSrcweir nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400); 640*cdf0e10cSrcweir bCalc = sal_False; 641*cdf0e10cSrcweir if ( nTempDays < 1 ) 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir i++; 644*cdf0e10cSrcweir bCalc = sal_True; 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir else 647*cdf0e10cSrcweir { 648*cdf0e10cSrcweir if ( nTempDays > 365 ) 649*cdf0e10cSrcweir { 650*cdf0e10cSrcweir if ( (nTempDays != 366) || !IsLeapYear( rYear ) ) 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir i--; 653*cdf0e10cSrcweir bCalc = sal_True; 654*cdf0e10cSrcweir } 655*cdf0e10cSrcweir } 656*cdf0e10cSrcweir } 657*cdf0e10cSrcweir } 658*cdf0e10cSrcweir while ( bCalc ); 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir rMonth = 1; 661*cdf0e10cSrcweir while ( (sal_Int32)nTempDays > DaysInMonth( rMonth, rYear ) ) 662*cdf0e10cSrcweir { 663*cdf0e10cSrcweir nTempDays -= DaysInMonth( rMonth, rYear ); 664*cdf0e10cSrcweir rMonth++; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir rDay = (sal_uInt16)nTempDays; 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir /** 670*cdf0e10cSrcweir * Get the null date used by the spreadsheet document 671*cdf0e10cSrcweir * 672*cdf0e10cSrcweir * The internal representation of a Date used in this Addin 673*cdf0e10cSrcweir * is the number of days between 01/01/0001 and the date 674*cdf0e10cSrcweir * this function returns this internal Date value for the document null date 675*cdf0e10cSrcweir * 676*cdf0e10cSrcweir */ 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir sal_Int32 GetNullDate( const uno::Reference< beans::XPropertySet >& xOptions ) 679*cdf0e10cSrcweir throw( uno::RuntimeException ) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir if (xOptions.is()) 682*cdf0e10cSrcweir { 683*cdf0e10cSrcweir try 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir uno::Any aAny = xOptions->getPropertyValue( 686*cdf0e10cSrcweir OUString::createFromAscii( "NullDate" ) ); 687*cdf0e10cSrcweir util::Date aDate; 688*cdf0e10cSrcweir if ( aAny >>= aDate ) 689*cdf0e10cSrcweir return DateToDays( aDate.Day, aDate.Month, aDate.Year ); 690*cdf0e10cSrcweir } 691*cdf0e10cSrcweir catch (uno::Exception&) 692*cdf0e10cSrcweir { 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir } 695*cdf0e10cSrcweir 696*cdf0e10cSrcweir // no null date available -> no calculations possible 697*cdf0e10cSrcweir throw uno::RuntimeException(); 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir // XDateFunctions 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir /** 703*cdf0e10cSrcweir * Get week difference between 2 dates 704*cdf0e10cSrcweir * 705*cdf0e10cSrcweir * new Weeks(date1,date2,mode) function for StarCalc 706*cdf0e10cSrcweir * 707*cdf0e10cSrcweir * Two modes of operation are provided. 708*cdf0e10cSrcweir * The first is just a simple division by 7 calculation. 709*cdf0e10cSrcweir * 710*cdf0e10cSrcweir * The second calculates the diffence by week of year. 711*cdf0e10cSrcweir * 712*cdf0e10cSrcweir * The International Standard IS-8601 has decreed that Monday 713*cdf0e10cSrcweir * shall be the first day of the week. 714*cdf0e10cSrcweir * 715*cdf0e10cSrcweir * A week that lies partly in one year and partly in annother 716*cdf0e10cSrcweir * is assigned a number in the the year in which most of its days lie. 717*cdf0e10cSrcweir * 718*cdf0e10cSrcweir * That means that week 1 of any year is the week that contains the 4. January 719*cdf0e10cSrcweir * 720*cdf0e10cSrcweir * The internal representation of a Date used in the Addin is the number of days based on 01/01/0001 721*cdf0e10cSrcweir * 722*cdf0e10cSrcweir * A WeekDay can be then calculated by substracting 1 and calculating the rest of 723*cdf0e10cSrcweir * a division by 7, which gives a 0 - 6 value for Monday - Sunday 724*cdf0e10cSrcweir * 725*cdf0e10cSrcweir * Using the 4. January rule explained above the formula 726*cdf0e10cSrcweir * 727*cdf0e10cSrcweir * nWeek1= ( nDays1 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1; 728*cdf0e10cSrcweir * 729*cdf0e10cSrcweir * calculates a number between 0-53 for each day which is in the same year as nJan4 730*cdf0e10cSrcweir * where 0 means that this week belonged to the year before. 731*cdf0e10cSrcweir * 732*cdf0e10cSrcweir * If a day in the same or annother year is used in this formula this calculates 733*cdf0e10cSrcweir * an calendar week offset from a given 4. January 734*cdf0e10cSrcweir * 735*cdf0e10cSrcweir * nWeek2 = ( nDays2 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1; 736*cdf0e10cSrcweir * 737*cdf0e10cSrcweir * The 4.January of first Date Argument can thus be used to calculate 738*cdf0e10cSrcweir * the week difference by calendar weeks which is then nWeek = nWeek2 - nWeek1 739*cdf0e10cSrcweir * 740*cdf0e10cSrcweir * which can be optimized to 741*cdf0e10cSrcweir * 742*cdf0e10cSrcweir * nWeek = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 ) 743*cdf0e10cSrcweir * 744*cdf0e10cSrcweir * Note: All calculations are operating on the long integer data type 745*cdf0e10cSrcweir * % is the modulo operator in C which calculates the rest of an Integer division 746*cdf0e10cSrcweir * 747*cdf0e10cSrcweir * 748*cdf0e10cSrcweir * mode 0 is the interval between the dates in month, that is days / 7 749*cdf0e10cSrcweir * 750*cdf0e10cSrcweir * mode 1 is the difference by week of year 751*cdf0e10cSrcweir * 752*cdf0e10cSrcweir */ 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getDiffWeeks( 755*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet >& xOptions, 756*cdf0e10cSrcweir sal_Int32 nStartDate, sal_Int32 nEndDate, 757*cdf0e10cSrcweir sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 758*cdf0e10cSrcweir { 759*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 760*cdf0e10cSrcweir 761*cdf0e10cSrcweir sal_Int32 nDays1 = nStartDate + nNullDate; 762*cdf0e10cSrcweir sal_Int32 nDays2 = nEndDate + nNullDate; 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir sal_Int32 nRet; 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir if ( nMode == 1 ) 767*cdf0e10cSrcweir { 768*cdf0e10cSrcweir sal_uInt16 nDay,nMonth,nYear; 769*cdf0e10cSrcweir DaysToDate( nDays1, nDay, nMonth, nYear ); 770*cdf0e10cSrcweir sal_Int32 nJan4 = DateToDays( 4, 1, nYear ); 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir nRet = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 ); 773*cdf0e10cSrcweir } 774*cdf0e10cSrcweir else 775*cdf0e10cSrcweir { 776*cdf0e10cSrcweir nRet = (nDays2 - nDays1) / 7; 777*cdf0e10cSrcweir } 778*cdf0e10cSrcweir return nRet; 779*cdf0e10cSrcweir } 780*cdf0e10cSrcweir 781*cdf0e10cSrcweir /** 782*cdf0e10cSrcweir * Get month difference between 2 dates 783*cdf0e10cSrcweir * =Month(start, end, mode) Function for StarCalc 784*cdf0e10cSrcweir * 785*cdf0e10cSrcweir * two modes are provided 786*cdf0e10cSrcweir * 787*cdf0e10cSrcweir * mode 0 is the interval between the dates in month 788*cdf0e10cSrcweir * 789*cdf0e10cSrcweir * mode 1 is the difference in calendar month 790*cdf0e10cSrcweir */ 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getDiffMonths( 793*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet >& xOptions, 794*cdf0e10cSrcweir sal_Int32 nStartDate, sal_Int32 nEndDate, 795*cdf0e10cSrcweir sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 796*cdf0e10cSrcweir { 797*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir sal_Int32 nDays1 = nStartDate + nNullDate; 800*cdf0e10cSrcweir sal_Int32 nDays2 = nEndDate + nNullDate; 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir sal_uInt16 nDay1,nMonth1,nYear1; 803*cdf0e10cSrcweir sal_uInt16 nDay2,nMonth2,nYear2; 804*cdf0e10cSrcweir DaysToDate(nDays1,nDay1,nMonth1,nYear1); 805*cdf0e10cSrcweir DaysToDate(nDays2,nDay2,nMonth2,nYear2); 806*cdf0e10cSrcweir 807*cdf0e10cSrcweir sal_Int32 nRet = nMonth2 - nMonth1 + (nYear2 - nYear1) * 12; 808*cdf0e10cSrcweir if ( nMode == 1 || nDays1 == nDays2 ) return nRet; 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir if ( nDays1 < nDays2 ) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir if ( nDay1 > nDay2 ) 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir nRet -= 1; 815*cdf0e10cSrcweir } 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir else 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir if ( nDay1 < nDay2 ) 820*cdf0e10cSrcweir { 821*cdf0e10cSrcweir nRet += 1; 822*cdf0e10cSrcweir } 823*cdf0e10cSrcweir } 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir return nRet; 826*cdf0e10cSrcweir } 827*cdf0e10cSrcweir 828*cdf0e10cSrcweir /** 829*cdf0e10cSrcweir * Get Year difference between 2 dates 830*cdf0e10cSrcweir * 831*cdf0e10cSrcweir * two modes are provided 832*cdf0e10cSrcweir * 833*cdf0e10cSrcweir * mode 0 is the interval between the dates in years 834*cdf0e10cSrcweir * 835*cdf0e10cSrcweir * mode 1 is the difference in calendar years 836*cdf0e10cSrcweir */ 837*cdf0e10cSrcweir 838*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getDiffYears( 839*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet >& xOptions, 840*cdf0e10cSrcweir sal_Int32 nStartDate, sal_Int32 nEndDate, 841*cdf0e10cSrcweir sal_Int32 nMode ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir if ( nMode != 1 ) 844*cdf0e10cSrcweir return getDiffMonths( xOptions, nStartDate, nEndDate, nMode ) / 12; 845*cdf0e10cSrcweir 846*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 847*cdf0e10cSrcweir 848*cdf0e10cSrcweir sal_Int32 nDays1 = nStartDate + nNullDate; 849*cdf0e10cSrcweir sal_Int32 nDays2 = nEndDate + nNullDate; 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir sal_uInt16 nDay1,nMonth1,nYear1; 852*cdf0e10cSrcweir sal_uInt16 nDay2,nMonth2,nYear2; 853*cdf0e10cSrcweir DaysToDate(nDays1,nDay1,nMonth1,nYear1); 854*cdf0e10cSrcweir DaysToDate(nDays2,nDay2,nMonth2,nYear2); 855*cdf0e10cSrcweir 856*cdf0e10cSrcweir return nYear2 - nYear1; 857*cdf0e10cSrcweir } 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir /** 860*cdf0e10cSrcweir * Check if a Date is in a leap year in the Gregorian calendar 861*cdf0e10cSrcweir */ 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getIsLeapYear( 864*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet >& xOptions, 865*cdf0e10cSrcweir sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 866*cdf0e10cSrcweir { 867*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 868*cdf0e10cSrcweir sal_Int32 nDays = nDate + nNullDate; 869*cdf0e10cSrcweir 870*cdf0e10cSrcweir sal_uInt16 nDay, nMonth, nYear; 871*cdf0e10cSrcweir DaysToDate(nDays,nDay,nMonth,nYear); 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir return (sal_Int32)IsLeapYear(nYear); 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir /** 877*cdf0e10cSrcweir * Get the Number of Days in the month for a date 878*cdf0e10cSrcweir */ 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getDaysInMonth( 881*cdf0e10cSrcweir const uno::Reference<beans::XPropertySet>& xOptions, 882*cdf0e10cSrcweir sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 883*cdf0e10cSrcweir { 884*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 885*cdf0e10cSrcweir sal_Int32 nDays = nDate + nNullDate; 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir sal_uInt16 nDay, nMonth, nYear; 888*cdf0e10cSrcweir DaysToDate(nDays,nDay,nMonth,nYear); 889*cdf0e10cSrcweir 890*cdf0e10cSrcweir return DaysInMonth( nMonth, nYear ); 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir 893*cdf0e10cSrcweir /** 894*cdf0e10cSrcweir * Get number of days in the year of a date specified 895*cdf0e10cSrcweir */ 896*cdf0e10cSrcweir 897*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getDaysInYear( 898*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet >& xOptions, 899*cdf0e10cSrcweir sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 900*cdf0e10cSrcweir { 901*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 902*cdf0e10cSrcweir sal_Int32 nDays = nDate + nNullDate; 903*cdf0e10cSrcweir 904*cdf0e10cSrcweir sal_uInt16 nDay, nMonth, nYear; 905*cdf0e10cSrcweir DaysToDate(nDays,nDay,nMonth,nYear); 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir return ( IsLeapYear(nYear) ? 366 : 365 ); 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir /** 911*cdf0e10cSrcweir * Get number of weeks in the year for a date 912*cdf0e10cSrcweir * 913*cdf0e10cSrcweir * Most years have 52 weeks, but years that start on a Thursday 914*cdf0e10cSrcweir * and leep years that start on a Wednesday have 53 weeks 915*cdf0e10cSrcweir * 916*cdf0e10cSrcweir * The International Standard IS-8601 has decreed that Monday 917*cdf0e10cSrcweir * shall be the first day of the week. 918*cdf0e10cSrcweir * 919*cdf0e10cSrcweir * A WeekDay can be calculated by substracting 1 and calculating the rest of 920*cdf0e10cSrcweir * a division by 7 from the internal date represention 921*cdf0e10cSrcweir * which gives a 0 - 6 value for Monday - Sunday 922*cdf0e10cSrcweir * 923*cdf0e10cSrcweir * @see #IsLeapYear #WeekNumber 924*cdf0e10cSrcweir */ 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir sal_Int32 SAL_CALL ScaDateAddIn::getWeeksInYear( 927*cdf0e10cSrcweir const uno::Reference< beans::XPropertySet >& xOptions, 928*cdf0e10cSrcweir sal_Int32 nDate ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 929*cdf0e10cSrcweir { 930*cdf0e10cSrcweir sal_Int32 nNullDate = GetNullDate( xOptions ); 931*cdf0e10cSrcweir sal_Int32 nDays = nDate + nNullDate; 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir sal_uInt16 nDay, nMonth, nYear; 934*cdf0e10cSrcweir DaysToDate(nDays,nDay,nMonth,nYear); 935*cdf0e10cSrcweir 936*cdf0e10cSrcweir sal_Int32 nJan1WeekDay = ( DateToDays(1,1,nYear) - 1) % 7; 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir sal_Int32 nRet; 939*cdf0e10cSrcweir if ( nJan1WeekDay == 3 ) /* Thursday */ 940*cdf0e10cSrcweir nRet = 53; 941*cdf0e10cSrcweir else if ( nJan1WeekDay == 2 ) /* Wednesday */ 942*cdf0e10cSrcweir nRet = ( IsLeapYear(nYear) ? 53 : 52 ); 943*cdf0e10cSrcweir else 944*cdf0e10cSrcweir nRet = 52; 945*cdf0e10cSrcweir 946*cdf0e10cSrcweir return nRet; 947*cdf0e10cSrcweir } 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir /** 950*cdf0e10cSrcweir * Encrypt or decrypt a string using ROT13 algorithm 951*cdf0e10cSrcweir * 952*cdf0e10cSrcweir * This function rotates each character by 13 in the alphabet. 953*cdf0e10cSrcweir * Only the characters 'a' ... 'z' and 'A' ... 'Z' are modified. 954*cdf0e10cSrcweir */ 955*cdf0e10cSrcweir 956*cdf0e10cSrcweir OUString SAL_CALL ScaDateAddIn::getRot13( const OUString& aSrcString ) throw( uno::RuntimeException, lang::IllegalArgumentException ) 957*cdf0e10cSrcweir { 958*cdf0e10cSrcweir OUStringBuffer aBuffer( aSrcString ); 959*cdf0e10cSrcweir for( sal_Int32 nIndex = 0; nIndex < aBuffer.getLength(); nIndex++ ) 960*cdf0e10cSrcweir { 961*cdf0e10cSrcweir sal_Unicode cChar = aBuffer.charAt( nIndex ); 962*cdf0e10cSrcweir if( ((cChar >= 'a') && (cChar <= 'z') && ((cChar += 13) > 'z')) || 963*cdf0e10cSrcweir ((cChar >= 'A') && (cChar <= 'Z') && ((cChar += 13) > 'Z')) ) 964*cdf0e10cSrcweir cChar -= 26; 965*cdf0e10cSrcweir aBuffer.setCharAt( nIndex, cChar ); 966*cdf0e10cSrcweir } 967*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 968*cdf0e10cSrcweir } 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir //------------------------------------------------------------------ 971*cdf0e10cSrcweir 972