1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "datefunc.hxx"
21 #include "datefunc.hrc"
22 #include <com/sun/star/util/Date.hpp>
23 #include <cppuhelper/factory.hxx>
24 #include <cppuhelper/supportsservice.hxx>
25 #include <osl/diagnose.h>
26 #include <rtl/ustrbuf.hxx>
27 #include <tools/rcid.h>
28 #include <tools/resmgr.hxx>
30 using namespace ::com::sun::star
;
32 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
33 #define MY_SERVICE "com.sun.star.sheet.addin.DateFunctions"
34 #define MY_IMPLNAME "com.sun.star.sheet.addin.DateFunctionsImpl"
36 #define STR_FROM_ANSI( s ) OUString( s, strlen( s ), RTL_TEXTENCODING_MS_1252 )
38 const sal_uInt32
ScaList::nStartSize
= 16;
39 const sal_uInt32
ScaList::nIncrSize
= 16;
42 pData( new void*[ nStartSize
] ),
58 void** pNewData
= new void*[ nSize
];
59 memcpy( pNewData
, pData
, nCount
* sizeof( void* ) );
65 ScaStringList::~ScaStringList()
67 for( OUString
* pStr
= First(); pStr
; pStr
= Next() )
71 ScaResId::ScaResId( sal_uInt16 nId
, ResMgr
& rResMgr
) :
76 #define UNIQUE false // function name does not exist in Calc
78 #define STDPAR false // all parameters are described
79 #define INTPAR true // first parameter is internal
81 #define FUNCDATA( FuncName, ParamCount, Category, Double, IntPar ) \
82 { "get" #FuncName, DATE_FUNCNAME_##FuncName, DATE_FUNCDESC_##FuncName, DATE_DEFFUNCNAME_##FuncName, ParamCount, Category, Double, IntPar }
84 const ScaFuncDataBase pFuncDataArr
[] =
86 FUNCDATA( DiffWeeks
, 3, ScaCat_DateTime
, UNIQUE
, INTPAR
),
87 FUNCDATA( DiffMonths
, 3, ScaCat_DateTime
, UNIQUE
, INTPAR
),
88 FUNCDATA( DiffYears
, 3, ScaCat_DateTime
, UNIQUE
, INTPAR
),
89 FUNCDATA( IsLeapYear
, 1, ScaCat_DateTime
, UNIQUE
, INTPAR
),
90 FUNCDATA( DaysInMonth
, 1, ScaCat_DateTime
, UNIQUE
, INTPAR
),
91 FUNCDATA( DaysInYear
, 1, ScaCat_DateTime
, UNIQUE
, INTPAR
),
92 FUNCDATA( WeeksInYear
, 1, ScaCat_DateTime
, UNIQUE
, INTPAR
),
93 FUNCDATA( Rot13
, 1, ScaCat_Text
, UNIQUE
, STDPAR
)
98 ScaFuncData::ScaFuncData( const ScaFuncDataBase
& rBaseData
, ResMgr
& rResMgr
) :
99 aIntName( OUString::createFromAscii( rBaseData
.pIntName
) ),
100 nUINameID( rBaseData
.nUINameID
),
101 nDescrID( rBaseData
.nDescrID
),
102 nCompListID( rBaseData
.nCompListID
),
103 nParamCount( rBaseData
.nParamCount
),
104 eCat( rBaseData
.eCat
),
105 bDouble( rBaseData
.bDouble
),
106 bWithOpt( rBaseData
.bWithOpt
)
108 ScaResStringArrLoader
aArrLoader( RID_DATE_DEFFUNCTION_NAMES
, nCompListID
, rResMgr
);
109 const ResStringArray
& rArr
= aArrLoader
.GetStringArray();
111 for( sal_uInt16 nIndex
= 0; nIndex
< rArr
.Count(); nIndex
++ )
112 aCompList
.Append( rArr
.GetString( nIndex
) );
115 ScaFuncData::~ScaFuncData()
119 sal_uInt16
ScaFuncData::GetStrIndex( sal_uInt16 nParam
) const
123 return (nParam
> nParamCount
) ? (nParamCount
* 2) : (nParam
* 2);
127 ScaFuncDataList::ScaFuncDataList( ResMgr
& rResMgr
) :
130 for( sal_uInt16 nIndex
= 0; nIndex
< SAL_N_ELEMENTS(pFuncDataArr
); nIndex
++ )
131 Append( new ScaFuncData( pFuncDataArr
[ nIndex
], rResMgr
) );
134 ScaFuncDataList::~ScaFuncDataList()
136 for( ScaFuncData
* pFData
= First(); pFData
; pFData
= Next() )
140 const ScaFuncData
* ScaFuncDataList::Get( const OUString
& rProgrammaticName
) const
142 if( aLastName
== rProgrammaticName
)
145 for( sal_uInt32 nIndex
= 0; nIndex
< Count(); nIndex
++ )
147 const ScaFuncData
* pCurr
= Get( nIndex
);
148 if( pCurr
->Is( rProgrammaticName
) )
150 const_cast< ScaFuncDataList
* >( this )->aLastName
= rProgrammaticName
;
151 const_cast< ScaFuncDataList
* >( this )->nLast
= nIndex
;
158 ScaFuncRes::ScaFuncRes( ResId
& rResId
, ResMgr
& rResMgr
, sal_uInt16 nIndex
, OUString
& rRet
) :
161 rRet
= ScaResId(nIndex
, rResMgr
).toString();
165 // entry points for service registration / instantiation
166 uno::Reference
< uno::XInterface
> SAL_CALL
ScaDateAddIn_CreateInstance(
167 const uno::Reference
< lang::XMultiServiceFactory
>& )
169 return (cppu::OWeakObject
*) new ScaDateAddIn();
174 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
date_component_getFactory(
175 const sal_Char
* pImplName
, void * pServiceManager
, void * /*pRegistryKey*/ )
179 if ( pServiceManager
&&
180 OUString::createFromAscii( pImplName
) == ScaDateAddIn::getImplementationName_Static() )
182 uno::Reference
< lang::XSingleServiceFactory
> xFactory( cppu::createOneInstanceFactory(
183 static_cast< lang::XMultiServiceFactory
* >( pServiceManager
),
184 ScaDateAddIn::getImplementationName_Static(),
185 ScaDateAddIn_CreateInstance
,
186 ScaDateAddIn::getSupportedServiceNames_Static() ) );
191 pRet
= xFactory
.get();
200 // "normal" service implementation
201 ScaDateAddIn::ScaDateAddIn() :
204 pFuncDataList( NULL
)
208 ScaDateAddIn::~ScaDateAddIn()
210 delete pFuncDataList
;
212 delete[] pDefLocales
;
215 static const sal_Char
* pLang
[] = { "de", "en" };
216 static const sal_Char
* pCoun
[] = { "DE", "US" };
217 static const sal_uInt32 nNumOfLoc
= SAL_N_ELEMENTS( pLang
);
219 void ScaDateAddIn::InitDefLocales()
221 pDefLocales
= new lang::Locale
[ nNumOfLoc
];
223 for( sal_uInt32 nIndex
= 0; nIndex
< nNumOfLoc
; nIndex
++ )
225 pDefLocales
[ nIndex
].Language
= OUString::createFromAscii( pLang
[ nIndex
] );
226 pDefLocales
[ nIndex
].Country
= OUString::createFromAscii( pCoun
[ nIndex
] );
230 const lang::Locale
& ScaDateAddIn::GetLocale( sal_uInt32 nIndex
)
235 return (nIndex
< sizeof( pLang
)) ? pDefLocales
[ nIndex
] : aFuncLoc
;
238 ResMgr
& ScaDateAddIn::GetResMgr() throw( uno::RuntimeException
)
242 InitData(); // try to get resource manager
244 throw uno::RuntimeException();
249 void ScaDateAddIn::InitData()
252 pResMgr
= ResMgr::CreateResMgr("date", LanguageTag(aFuncLoc
));
253 delete pFuncDataList
;
255 pFuncDataList
= pResMgr
? new ScaFuncDataList( *pResMgr
) : NULL
;
264 OUString
ScaDateAddIn::GetDisplFuncStr( sal_uInt16 nResId
) throw( uno::RuntimeException
)
266 return ScaResStringLoader( RID_DATE_FUNCTION_NAMES
, nResId
, GetResMgr() ).GetString();
269 OUString
ScaDateAddIn::GetFuncDescrStr( sal_uInt16 nResId
, sal_uInt16 nStrIndex
) throw( uno::RuntimeException
)
273 ScaResPublisher
aResPubl( ScaResId( RID_DATE_FUNCTION_DESCRIPTIONS
, GetResMgr() ) );
274 ScaResId
aResId( nResId
, GetResMgr() );
275 aResId
.SetRT( RSC_RESOURCE
);
277 if( aResPubl
.IsAvailableRes( aResId
) )
278 ScaFuncRes
aSubRes( aResId
, GetResMgr(), nStrIndex
, aRet
);
280 aResPubl
.FreeResource();
284 OUString
ScaDateAddIn::getImplementationName_Static()
286 return OUString( MY_IMPLNAME
);
289 uno::Sequence
< OUString
> ScaDateAddIn::getSupportedServiceNames_Static()
291 uno::Sequence
< OUString
> aRet( 2 );
292 OUString
* pArray
= aRet
.getArray();
293 pArray
[0] = ADDIN_SERVICE
;
294 pArray
[1] = MY_SERVICE
;
299 OUString SAL_CALL
ScaDateAddIn::getServiceName() throw( uno::RuntimeException
, std::exception
)
301 // name of specific AddIn service
302 return OUString( MY_SERVICE
);
306 OUString SAL_CALL
ScaDateAddIn::getImplementationName() throw( uno::RuntimeException
, std::exception
)
308 return getImplementationName_Static();
311 sal_Bool SAL_CALL
ScaDateAddIn::supportsService( const OUString
& aServiceName
) throw( uno::RuntimeException
, std::exception
)
313 return cppu::supportsService(this, aServiceName
);
316 uno::Sequence
< OUString
> SAL_CALL
ScaDateAddIn::getSupportedServiceNames() throw( uno::RuntimeException
, std::exception
)
318 return getSupportedServiceNames_Static();
322 void SAL_CALL
ScaDateAddIn::setLocale( const lang::Locale
& eLocale
) throw( uno::RuntimeException
, std::exception
)
325 InitData(); // change of locale invalidates resources!
328 lang::Locale SAL_CALL
ScaDateAddIn::getLocale() throw( uno::RuntimeException
, std::exception
)
333 OUString SAL_CALL
ScaDateAddIn::getProgrammaticFuntionName( const OUString
& ) throw( uno::RuntimeException
, std::exception
)
336 // (but should be implemented for other uses of the AddIn service)
340 OUString SAL_CALL
ScaDateAddIn::getDisplayFunctionName( const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
344 const ScaFuncData
* pFData
= pFuncDataList
->Get( aProgrammaticName
);
347 aRet
= GetDisplFuncStr( pFData
->GetUINameID() );
348 if( pFData
->IsDouble() )
349 aRet
+= STR_FROM_ANSI( "_ADD" );
353 aRet
= STR_FROM_ANSI( "UNKNOWNFUNC_" );
354 aRet
+= aProgrammaticName
;
360 OUString SAL_CALL
ScaDateAddIn::getFunctionDescription( const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
364 const ScaFuncData
* pFData
= pFuncDataList
->Get( aProgrammaticName
);
366 aRet
= GetFuncDescrStr( pFData
->GetDescrID(), 1 );
371 OUString SAL_CALL
ScaDateAddIn::getDisplayArgumentName(
372 const OUString
& aProgrammaticName
, sal_Int32 nArgument
) throw( uno::RuntimeException
, std::exception
)
376 const ScaFuncData
* pFData
= pFuncDataList
->Get( aProgrammaticName
);
377 if( pFData
&& (nArgument
<= 0xFFFF) )
379 sal_uInt16 nStr
= pFData
->GetStrIndex( static_cast< sal_uInt16
>( nArgument
) );
381 aRet
= GetFuncDescrStr( pFData
->GetDescrID(), nStr
);
383 aRet
= STR_FROM_ANSI( "internal" );
389 OUString SAL_CALL
ScaDateAddIn::getArgumentDescription(
390 const OUString
& aProgrammaticName
, sal_Int32 nArgument
) throw( uno::RuntimeException
, std::exception
)
394 const ScaFuncData
* pFData
= pFuncDataList
->Get( aProgrammaticName
);
395 if( pFData
&& (nArgument
<= 0xFFFF) )
397 sal_uInt16 nStr
= pFData
->GetStrIndex( static_cast< sal_uInt16
>( nArgument
) );
399 aRet
= GetFuncDescrStr( pFData
->GetDescrID(), nStr
+ 1 );
401 aRet
= STR_FROM_ANSI( "for internal use only" );
407 OUString SAL_CALL
ScaDateAddIn::getProgrammaticCategoryName(
408 const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
412 const ScaFuncData
* pFData
= pFuncDataList
->Get( aProgrammaticName
);
415 switch( pFData
->GetCategory() )
417 case ScaCat_DateTime
: aRet
= STR_FROM_ANSI( "Date&Time" ); break;
418 case ScaCat_Text
: aRet
= STR_FROM_ANSI( "Text" ); break;
419 case ScaCat_Finance
: aRet
= STR_FROM_ANSI( "Financial" ); break;
420 case ScaCat_Inf
: aRet
= STR_FROM_ANSI( "Information" ); break;
421 case ScaCat_Math
: aRet
= STR_FROM_ANSI( "Mathematical" ); break;
422 case ScaCat_Tech
: aRet
= STR_FROM_ANSI( "Technical" ); break;
423 // coverity[dead_error_begin] - following conditions exist to avoid compiler warning
430 aRet
= STR_FROM_ANSI( "Add-In" );
434 OUString SAL_CALL
ScaDateAddIn::getDisplayCategoryName(
435 const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
437 return getProgrammaticCategoryName( aProgrammaticName
);
440 // XCompatibilityNames
441 uno::Sequence
< sheet::LocalizedName
> SAL_CALL
ScaDateAddIn::getCompatibilityNames(
442 const OUString
& aProgrammaticName
) throw( uno::RuntimeException
, std::exception
)
444 const ScaFuncData
* pFData
= pFuncDataList
->Get( aProgrammaticName
);
446 return uno::Sequence
< sheet::LocalizedName
>( 0 );
448 const ScaStringList
& rStrList
= pFData
->GetCompNameList();
449 sal_uInt32 nCount
= rStrList
.Count();
451 uno::Sequence
< sheet::LocalizedName
> aRet( nCount
);
452 sheet::LocalizedName
* pArray
= aRet
.getArray();
454 for( sal_uInt32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
455 pArray
[ nIndex
] = sheet::LocalizedName( GetLocale( nIndex
), *rStrList
.Get( nIndex
) );
462 // auxiliary functions
463 bool IsLeapYear( sal_uInt16 nYear
)
465 return ((((nYear
% 4) == 0) && ((nYear
% 100) != 0)) || ((nYear
% 400) == 0));
468 sal_uInt16
DaysInMonth( sal_uInt16 nMonth
, sal_uInt16 nYear
)
470 static const sal_uInt16 aDaysInMonth
[12] = { 31, 28, 31, 30, 31, 30,
471 31, 31, 30, 31, 30, 31 };
474 return aDaysInMonth
[nMonth
-1];
477 if ( IsLeapYear(nYear
) )
478 return aDaysInMonth
[nMonth
-1] + 1;
480 return aDaysInMonth
[nMonth
-1];
485 * Convert a date to a count of days starting from 01/01/0001
487 * The internal representation of a Date used in this Addin
488 * is the number of days between 01/01/0001 and the date
489 * this function converts a Day , Month, Year representation
490 * to this internal Date value.
493 sal_Int32
DateToDays( sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_uInt16 nYear
)
495 sal_Int32 nDays
= ((sal_Int32
)nYear
-1) * 365;
496 nDays
+= ((nYear
-1) / 4) - ((nYear
-1) / 100) + ((nYear
-1) / 400);
498 for( sal_uInt16 i
= 1; i
< nMonth
; i
++ )
499 nDays
+= DaysInMonth(i
,nYear
);
506 * Convert a count of days starting from 01/01/0001 to a date
508 * The internal representation of a Date used in this Addin
509 * is the number of days between 01/01/0001 and the date
510 * this function converts this internal Date value
511 * to a Day , Month, Year representation of a Date.
514 void DaysToDate( sal_Int32 nDays
,
515 sal_uInt16
& rDay
, sal_uInt16
& rMonth
, sal_uInt16
& rYear
)
516 throw( lang::IllegalArgumentException
)
519 throw lang::IllegalArgumentException();
528 rYear
= (sal_uInt16
)((nTempDays
/ 365) - i
);
529 nTempDays
-= ((sal_Int32
) rYear
-1) * 365;
530 nTempDays
-= (( rYear
-1) / 4) - (( rYear
-1) / 100) + ((rYear
-1) / 400);
539 if ( nTempDays
> 365 )
541 if ( (nTempDays
!= 366) || !IsLeapYear( rYear
) )
552 while ( (sal_Int32
)nTempDays
> DaysInMonth( rMonth
, rYear
) )
554 nTempDays
-= DaysInMonth( rMonth
, rYear
);
557 rDay
= (sal_uInt16
)nTempDays
;
561 * Get the null date used by the spreadsheet document
563 * The internal representation of a Date used in this Addin
564 * is the number of days between 01/01/0001 and the date
565 * this function returns this internal Date value for the document null date
568 sal_Int32
GetNullDate( const uno::Reference
< beans::XPropertySet
>& xOptions
)
569 throw( uno::RuntimeException
)
575 uno::Any aAny
= xOptions
->getPropertyValue(
576 OUString( "NullDate" ) );
578 if ( aAny
>>= aDate
)
579 return DateToDays( aDate
.Day
, aDate
.Month
, aDate
.Year
);
581 catch (uno::Exception
&)
586 // no null date available -> no calculations possible
587 throw uno::RuntimeException();
594 * Get week difference between 2 dates
596 * new Weeks(date1,date2,mode) function for StarCalc
598 * Two modes of operation are provided.
599 * The first is just a simple division by 7 calculation.
601 * The second calculates the diffence by week of year.
603 * The International Standard IS-8601 has decreed that Monday
604 * shall be the first day of the week.
606 * A week that lies partly in one year and partly in annother
607 * is assigned a number in the year in which most of its days lie.
609 * That means that week 1 of any year is the week that contains the 4. January
611 * The internal representation of a Date used in the Addin is the number of days based on 01/01/0001
613 * A WeekDay can be then calculated by subtracting 1 and calculating the rest of
614 * a division by 7, which gives a 0 - 6 value for Monday - Sunday
616 * Using the 4. January rule explained above the formula
618 * nWeek1= ( nDays1 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
620 * calculates a number between 0-53 for each day which is in the same year as nJan4
621 * where 0 means that this week belonged to the year before.
623 * If a day in the same or another year is used in this formula this calculates
624 * an calendar week offset from a given 4. January
626 * nWeek2 = ( nDays2 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
628 * The 4.January of first Date Argument can thus be used to calculate
629 * the week difference by calendar weeks which is then nWeek = nWeek2 - nWeek1
631 * which can be optimized to
633 * nWeek = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 )
635 * Note: All calculations are operating on the long integer data type
636 * % is the modulo operator in C which calculates the rest of an Integer division
639 * mode 0 is the interval between the dates in month, that is days / 7
641 * mode 1 is the difference by week of year
645 sal_Int32 SAL_CALL
ScaDateAddIn::getDiffWeeks(
646 const uno::Reference
< beans::XPropertySet
>& xOptions
,
647 sal_Int32 nStartDate
, sal_Int32 nEndDate
,
648 sal_Int32 nMode
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
650 sal_Int32 nNullDate
= GetNullDate( xOptions
);
652 sal_Int32 nDays1
= nStartDate
+ nNullDate
;
653 sal_Int32 nDays2
= nEndDate
+ nNullDate
;
659 sal_uInt16 nDay
,nMonth
,nYear
;
660 DaysToDate( nDays1
, nDay
, nMonth
, nYear
);
661 sal_Int32 nJan4
= DateToDays( 4, 1, nYear
);
663 nRet
= ( (nDays2
-nJan4
+((nJan4
-1)%7))/7 ) - ( (nDays1
-nJan4
+((nJan4
-1)%7))/7 );
667 nRet
= (nDays2
- nDays1
) / 7;
673 * Get month difference between 2 dates
674 * =Month(start, end, mode) Function for StarCalc
676 * two modes are provided
678 * mode 0 is the interval between the dates in month
680 * mode 1 is the difference in calendar month
682 sal_Int32 SAL_CALL
ScaDateAddIn::getDiffMonths(
683 const uno::Reference
< beans::XPropertySet
>& xOptions
,
684 sal_Int32 nStartDate
, sal_Int32 nEndDate
,
685 sal_Int32 nMode
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
687 sal_Int32 nNullDate
= GetNullDate( xOptions
);
689 sal_Int32 nDays1
= nStartDate
+ nNullDate
;
690 sal_Int32 nDays2
= nEndDate
+ nNullDate
;
692 sal_uInt16 nDay1
,nMonth1
,nYear1
;
693 sal_uInt16 nDay2
,nMonth2
,nYear2
;
694 DaysToDate(nDays1
,nDay1
,nMonth1
,nYear1
);
695 DaysToDate(nDays2
,nDay2
,nMonth2
,nYear2
);
697 sal_Int32 nRet
= nMonth2
- nMonth1
+ (nYear2
- nYear1
) * 12;
698 if ( nMode
== 1 || nDays1
== nDays2
) return nRet
;
700 if ( nDays1
< nDays2
)
719 * Get Year difference between 2 dates
721 * two modes are provided
723 * mode 0 is the interval between the dates in years
725 * mode 1 is the difference in calendar years
727 sal_Int32 SAL_CALL
ScaDateAddIn::getDiffYears(
728 const uno::Reference
< beans::XPropertySet
>& xOptions
,
729 sal_Int32 nStartDate
, sal_Int32 nEndDate
,
730 sal_Int32 nMode
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
733 return getDiffMonths( xOptions
, nStartDate
, nEndDate
, nMode
) / 12;
735 sal_Int32 nNullDate
= GetNullDate( xOptions
);
737 sal_Int32 nDays1
= nStartDate
+ nNullDate
;
738 sal_Int32 nDays2
= nEndDate
+ nNullDate
;
740 sal_uInt16 nDay1
,nMonth1
,nYear1
;
741 sal_uInt16 nDay2
,nMonth2
,nYear2
;
742 DaysToDate(nDays1
,nDay1
,nMonth1
,nYear1
);
743 DaysToDate(nDays2
,nDay2
,nMonth2
,nYear2
);
745 return nYear2
- nYear1
;
749 * Check if a Date is in a leap year in the Gregorian calendar
751 sal_Int32 SAL_CALL
ScaDateAddIn::getIsLeapYear(
752 const uno::Reference
< beans::XPropertySet
>& xOptions
,
753 sal_Int32 nDate
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
755 sal_Int32 nNullDate
= GetNullDate( xOptions
);
756 sal_Int32 nDays
= nDate
+ nNullDate
;
758 sal_uInt16 nDay
, nMonth
, nYear
;
759 DaysToDate(nDays
,nDay
,nMonth
,nYear
);
761 return (sal_Int32
)IsLeapYear(nYear
);
765 * Get the Number of Days in the month for a date
767 sal_Int32 SAL_CALL
ScaDateAddIn::getDaysInMonth(
768 const uno::Reference
<beans::XPropertySet
>& xOptions
,
769 sal_Int32 nDate
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
771 sal_Int32 nNullDate
= GetNullDate( xOptions
);
772 sal_Int32 nDays
= nDate
+ nNullDate
;
774 sal_uInt16 nDay
, nMonth
, nYear
;
775 DaysToDate(nDays
,nDay
,nMonth
,nYear
);
777 return DaysInMonth( nMonth
, nYear
);
781 * Get number of days in the year of a date specified
783 sal_Int32 SAL_CALL
ScaDateAddIn::getDaysInYear(
784 const uno::Reference
< beans::XPropertySet
>& xOptions
,
785 sal_Int32 nDate
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
787 sal_Int32 nNullDate
= GetNullDate( xOptions
);
788 sal_Int32 nDays
= nDate
+ nNullDate
;
790 sal_uInt16 nDay
, nMonth
, nYear
;
791 DaysToDate(nDays
,nDay
,nMonth
,nYear
);
793 return ( IsLeapYear(nYear
) ? 366 : 365 );
797 * Get number of weeks in the year for a date
799 * Most years have 52 weeks, but years that start on a Thursday
800 * and leep years that start on a Wednesday have 53 weeks
802 * The International Standard IS-8601 has decreed that Monday
803 * shall be the first day of the week.
805 * A WeekDay can be calculated by subtracting 1 and calculating the rest of
806 * a division by 7 from the internal date represention
807 * which gives a 0 - 6 value for Monday - Sunday
809 * @see #IsLeapYear #WeekNumber
811 sal_Int32 SAL_CALL
ScaDateAddIn::getWeeksInYear(
812 const uno::Reference
< beans::XPropertySet
>& xOptions
,
813 sal_Int32 nDate
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
815 sal_Int32 nNullDate
= GetNullDate( xOptions
);
816 sal_Int32 nDays
= nDate
+ nNullDate
;
818 sal_uInt16 nDay
, nMonth
, nYear
;
819 DaysToDate(nDays
,nDay
,nMonth
,nYear
);
821 sal_Int32 nJan1WeekDay
= ( DateToDays(1,1,nYear
) - 1) % 7;
824 if ( nJan1WeekDay
== 3 ) /* Thursday */
826 else if ( nJan1WeekDay
== 2 ) /* Wednesday */
827 nRet
= ( IsLeapYear(nYear
) ? 53 : 52 );
835 * Encrypt or decrypt a string using ROT13 algorithm
837 * This function rotates each character by 13 in the alphabet.
838 * Only the characters 'a' ... 'z' and 'A' ... 'Z' are modified.
840 OUString SAL_CALL
ScaDateAddIn::getRot13( const OUString
& aSrcString
) throw( uno::RuntimeException
, lang::IllegalArgumentException
, std::exception
)
842 OUStringBuffer
aBuffer( aSrcString
);
843 for( sal_Int32 nIndex
= 0; nIndex
< aBuffer
.getLength(); nIndex
++ )
845 sal_Unicode cChar
= aBuffer
[nIndex
];
846 if( ((cChar
>= 'a') && (cChar
<= 'z') && ((cChar
+= 13) > 'z')) ||
847 ((cChar
>= 'A') && (cChar
<= 'Z') && ((cChar
+= 13) > 'Z')) )
849 aBuffer
[nIndex
] = cChar
;
851 return aBuffer
.makeStringAndClear();
854 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */