bump product version to 6.3.0.0.beta1
[LibreOffice.git] / scaddins / source / datefunc / datefunc.cxx
blob3011ccb324805c23b55daa05d7b32af9994da0e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <strings.hrc>
23 #include <com/sun/star/util/Date.hpp>
24 #include <cppuhelper/factory.hxx>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
27 #include <rtl/ustrbuf.hxx>
28 #include <unotools/resmgr.hxx>
29 #include <i18nlangtag/languagetag.hxx>
30 #include <algorithm>
31 #include "deffuncname.hxx"
33 using namespace ::com::sun::star;
35 #define ADDIN_SERVICE "com.sun.star.sheet.AddIn"
36 #define MY_SERVICE "com.sun.star.sheet.addin.DateFunctions"
37 #define MY_IMPLNAME "com.sun.star.sheet.addin.DateFunctionsImpl"
39 #define UNIQUE false // function name does not exist in Calc
41 #define STDPAR false // all parameters are described
42 #define INTPAR true // first parameter is internal
44 #define FUNCDATA( FuncName, ParamCount, Category, Double, IntPar ) \
45 { "get" #FuncName, DATE_FUNCNAME_##FuncName, DATE_FUNCDESC_##FuncName, DATE_DEFFUNCNAME_##FuncName, ParamCount, Category, Double, IntPar }
47 const ScaFuncDataBase pFuncDataArr[] =
49 FUNCDATA( DiffWeeks, 3, ScaCategory::DateTime, UNIQUE, INTPAR ),
50 FUNCDATA( DiffMonths, 3, ScaCategory::DateTime, UNIQUE, INTPAR ),
51 FUNCDATA( DiffYears, 3, ScaCategory::DateTime, UNIQUE, INTPAR ),
52 FUNCDATA( IsLeapYear, 1, ScaCategory::DateTime, UNIQUE, INTPAR ),
53 FUNCDATA( DaysInMonth, 1, ScaCategory::DateTime, UNIQUE, INTPAR ),
54 FUNCDATA( DaysInYear, 1, ScaCategory::DateTime, UNIQUE, INTPAR ),
55 FUNCDATA( WeeksInYear, 1, ScaCategory::DateTime, UNIQUE, INTPAR ),
56 FUNCDATA( Rot13, 1, ScaCategory::Text, UNIQUE, STDPAR )
59 #undef FUNCDATA
61 ScaFuncData::ScaFuncData(const ScaFuncDataBase& rBaseData) :
62 aIntName( OUString::createFromAscii( rBaseData.pIntName ) ),
63 pUINameID( rBaseData.pUINameID ),
64 pDescrID( rBaseData.pDescrID ),
65 nParamCount( rBaseData.nParamCount ),
66 eCat( rBaseData.eCat ),
67 bDouble( rBaseData.bDouble ),
68 bWithOpt( rBaseData.bWithOpt )
70 aCompList.push_back(OUString::createFromAscii(rBaseData.pCompListID[0]));
71 aCompList.push_back(OUString::createFromAscii(rBaseData.pCompListID[1]));
74 ScaFuncData::~ScaFuncData()
78 sal_uInt16 ScaFuncData::GetStrIndex( sal_uInt16 nParam ) const
80 if( !bWithOpt )
81 nParam++;
82 return (nParam > nParamCount) ? (nParamCount * 2) : (nParam * 2);
85 static void InitScaFuncDataList(ScaFuncDataList& rList)
87 for (const auto & nIndex : pFuncDataArr)
88 rList.push_back(ScaFuncData(nIndex));
91 // entry points for service registration / instantiation
92 static uno::Reference< uno::XInterface > ScaDateAddIn_CreateInstance(
93 const uno::Reference< lang::XMultiServiceFactory >& )
95 return static_cast<cppu::OWeakObject*>(new ScaDateAddIn());
98 extern "C" {
100 SAL_DLLPUBLIC_EXPORT void * date_component_getFactory(
101 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
103 void* pRet = nullptr;
105 if ( pServiceManager &&
106 OUString::createFromAscii( pImplName ) == ScaDateAddIn::getImplementationName_Static() )
108 uno::Reference< lang::XSingleServiceFactory > xFactory( cppu::createOneInstanceFactory(
109 static_cast< lang::XMultiServiceFactory* >( pServiceManager ),
110 ScaDateAddIn::getImplementationName_Static(),
111 ScaDateAddIn_CreateInstance,
112 ScaDateAddIn::getSupportedServiceNames_Static() ) );
114 if (xFactory.is())
116 xFactory->acquire();
117 pRet = xFactory.get();
121 return pRet;
124 } // extern C
126 // "normal" service implementation
127 ScaDateAddIn::ScaDateAddIn()
131 static const sal_Char* pLang[] = { "de", "en" };
132 static const sal_Char* pCoun[] = { "DE", "US" };
133 static const sal_uInt32 nNumOfLoc = SAL_N_ELEMENTS( pLang );
135 void ScaDateAddIn::InitDefLocales()
137 pDefLocales.reset(new lang::Locale[ nNumOfLoc ]);
139 for( sal_uInt32 nIndex = 0; nIndex < nNumOfLoc; nIndex++ )
141 pDefLocales[ nIndex ].Language = OUString::createFromAscii( pLang[ nIndex ] );
142 pDefLocales[ nIndex ].Country = OUString::createFromAscii( pCoun[ nIndex ] );
146 const lang::Locale& ScaDateAddIn::GetLocale( sal_uInt32 nIndex )
148 if( !pDefLocales )
149 InitDefLocales();
151 return (nIndex < sizeof( pLang )) ? pDefLocales[ nIndex ] : aFuncLoc;
154 void ScaDateAddIn::InitData()
156 aResLocale = Translate::Create("sca", LanguageTag(aFuncLoc));
157 pFuncDataList.reset();
159 pFuncDataList.reset(new ScaFuncDataList);
160 InitScaFuncDataList(*pFuncDataList);
162 if( pDefLocales )
164 pDefLocales.reset();
168 OUString ScaDateAddIn::GetFuncDescrStr(const char** pResId, sal_uInt16 nStrIndex)
170 return ScaResId(pResId[nStrIndex - 1]);
173 OUString ScaDateAddIn::getImplementationName_Static()
175 return OUString( MY_IMPLNAME );
178 uno::Sequence< OUString > ScaDateAddIn::getSupportedServiceNames_Static()
180 uno::Sequence< OUString > aRet( 2 );
181 OUString* pArray = aRet.getArray();
182 pArray[0] = ADDIN_SERVICE;
183 pArray[1] = MY_SERVICE;
184 return aRet;
187 // XServiceName
188 OUString SAL_CALL ScaDateAddIn::getServiceName()
190 // name of specific AddIn service
191 return OUString( MY_SERVICE );
194 // XServiceInfo
195 OUString SAL_CALL ScaDateAddIn::getImplementationName()
197 return getImplementationName_Static();
200 sal_Bool SAL_CALL ScaDateAddIn::supportsService( const OUString& aServiceName )
202 return cppu::supportsService(this, aServiceName);
205 uno::Sequence< OUString > SAL_CALL ScaDateAddIn::getSupportedServiceNames()
207 return getSupportedServiceNames_Static();
210 // XLocalizable
211 void SAL_CALL ScaDateAddIn::setLocale( const lang::Locale& eLocale )
213 aFuncLoc = eLocale;
214 InitData(); // change of locale invalidates resources!
217 lang::Locale SAL_CALL ScaDateAddIn::getLocale()
219 return aFuncLoc;
222 OUString SAL_CALL ScaDateAddIn::getProgrammaticFuntionName( const OUString& )
224 // not used by calc
225 // (but should be implemented for other uses of the AddIn service)
226 return OUString();
229 OUString SAL_CALL ScaDateAddIn::getDisplayFunctionName( const OUString& aProgrammaticName )
231 OUString aRet;
233 auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
234 FindScaFuncData( aProgrammaticName ) );
235 if( fDataIt != pFuncDataList->end() )
237 aRet = ScaResId(fDataIt->GetUINameID());
238 if( fDataIt->IsDouble() )
239 aRet += "_ADD";
241 else
243 aRet = "UNKNOWNFUNC_";
244 aRet += aProgrammaticName;
247 return aRet;
250 OUString SAL_CALL ScaDateAddIn::getFunctionDescription( const OUString& aProgrammaticName )
252 OUString aRet;
254 auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
255 FindScaFuncData( aProgrammaticName ) );
256 if( fDataIt != pFuncDataList->end() )
257 aRet = GetFuncDescrStr( fDataIt->GetDescrID(), 1 );
259 return aRet;
262 OUString SAL_CALL ScaDateAddIn::getDisplayArgumentName(
263 const OUString& aProgrammaticName, sal_Int32 nArgument )
265 OUString aRet;
267 auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
268 FindScaFuncData( aProgrammaticName ) );
269 if( fDataIt != pFuncDataList->end() && (nArgument <= 0xFFFF) )
271 sal_uInt16 nStr = fDataIt->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
272 if( nStr )
273 aRet = GetFuncDescrStr( fDataIt->GetDescrID(), nStr );
274 else
275 aRet = "internal";
278 return aRet;
281 OUString SAL_CALL ScaDateAddIn::getArgumentDescription(
282 const OUString& aProgrammaticName, sal_Int32 nArgument )
284 OUString aRet;
286 auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
287 FindScaFuncData( aProgrammaticName ) );
288 if( fDataIt != pFuncDataList->end() && (nArgument <= 0xFFFF) )
290 sal_uInt16 nStr = fDataIt->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
291 if( nStr )
292 aRet = GetFuncDescrStr( fDataIt->GetDescrID(), nStr + 1 );
293 else
294 aRet = "for internal use only";
297 return aRet;
300 OUString SAL_CALL ScaDateAddIn::getProgrammaticCategoryName(
301 const OUString& aProgrammaticName )
303 OUString aRet;
305 auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
306 FindScaFuncData( aProgrammaticName ) );
307 if( fDataIt != pFuncDataList->end() )
309 switch( fDataIt->GetCategory() )
311 case ScaCategory::DateTime: aRet = "Date&Time"; break;
312 case ScaCategory::Text: aRet = "Text"; break;
313 case ScaCategory::Finance: aRet = "Financial"; break;
314 case ScaCategory::Inf: aRet = "Information"; break;
315 case ScaCategory::Math: aRet = "Mathematical"; break;
316 case ScaCategory::Tech: aRet = "Technical"; break;
320 if( aRet.isEmpty() )
321 aRet = "Add-In";
322 return aRet;
325 OUString SAL_CALL ScaDateAddIn::getDisplayCategoryName(
326 const OUString& aProgrammaticName )
328 return getProgrammaticCategoryName( aProgrammaticName );
331 // XCompatibilityNames
332 uno::Sequence< sheet::LocalizedName > SAL_CALL ScaDateAddIn::getCompatibilityNames(
333 const OUString& aProgrammaticName )
335 auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
336 FindScaFuncData( aProgrammaticName ) );
337 if( fDataIt == pFuncDataList->end() )
338 return uno::Sequence< sheet::LocalizedName >( 0 );
340 const std::vector<OUString>& rStrList = fDataIt->GetCompNameList();
341 sal_uInt32 nCount = rStrList.size();
343 uno::Sequence< sheet::LocalizedName > aRet( nCount );
344 sheet::LocalizedName* pArray = aRet.getArray();
346 for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
347 pArray[ nIndex ] = sheet::LocalizedName( GetLocale( nIndex ), rStrList.at( nIndex ) );
349 return aRet;
352 namespace {
354 // auxiliary functions
355 bool IsLeapYear( sal_uInt16 nYear )
357 return ((((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0));
360 sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
362 static const sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
363 31, 31, 30, 31, 30, 31 };
365 if ( nMonth != 2 )
366 return aDaysInMonth[nMonth-1];
367 else
369 if ( IsLeapYear(nYear) )
370 return aDaysInMonth[nMonth-1] + 1;
371 else
372 return aDaysInMonth[nMonth-1];
377 * Convert a date to a count of days starting from 01/01/0001
379 * The internal representation of a Date used in this Addin
380 * is the number of days between 01/01/0001 and the date
381 * this function converts a Day , Month, Year representation
382 * to this internal Date value.
385 sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear )
387 sal_Int32 nDays = (static_cast<sal_Int32>(nYear)-1) * 365;
388 nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
390 for( sal_uInt16 i = 1; i < nMonth; i++ )
391 nDays += DaysInMonth(i,nYear);
392 nDays += nDay;
394 return nDays;
398 * Convert a count of days starting from 01/01/0001 to a date
400 * The internal representation of a Date used in this Addin
401 * is the number of days between 01/01/0001 and the date
402 * this function converts this internal Date value
403 * to a Day , Month, Year representation of a Date.
405 * @throws lang::IllegalArgumentException
408 void DaysToDate( sal_Int32 nDays,
409 sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear )
411 if( nDays < 0 )
412 throw lang::IllegalArgumentException();
414 sal_Int32 nTempDays;
415 sal_Int32 i = 0;
416 bool bCalc;
420 nTempDays = nDays;
421 rYear = static_cast<sal_uInt16>((nTempDays / 365) - i);
422 nTempDays -= (static_cast<sal_Int32>(rYear) -1) * 365;
423 nTempDays -= (( rYear -1) / 4) - (( rYear -1) / 100) + ((rYear -1) / 400);
424 bCalc = false;
425 if ( nTempDays < 1 )
427 i++;
428 bCalc = true;
430 else
432 if ( nTempDays > 365 )
434 if ( (nTempDays != 366) || !IsLeapYear( rYear ) )
436 i--;
437 bCalc = true;
442 while ( bCalc );
444 rMonth = 1;
445 while ( nTempDays > DaysInMonth( rMonth, rYear ) )
447 nTempDays -= DaysInMonth( rMonth, rYear );
448 rMonth++;
450 rDay = static_cast<sal_uInt16>(nTempDays);
454 * Get the null date used by the spreadsheet document
456 * The internal representation of a Date used in this Addin
457 * is the number of days between 01/01/0001 and the date
458 * this function returns this internal Date value for the document null date
460 * @throws uno::RuntimeException
462 sal_Int32 GetNullDate( const uno::Reference< beans::XPropertySet >& xOptions )
464 if (xOptions.is())
468 uno::Any aAny = xOptions->getPropertyValue( "NullDate" );
469 util::Date aDate;
470 if ( aAny >>= aDate )
471 return DateToDays( aDate.Day, aDate.Month, aDate.Year );
473 catch (uno::Exception&)
478 // no null date available -> no calculations possible
479 throw uno::RuntimeException();
483 // XDateFunctions
486 * Get week difference between 2 dates
488 * new Weeks(date1,date2,mode) function for StarCalc
490 * Two modes of operation are provided.
491 * The first is just a simple division by 7 calculation.
493 * The second calculates the difference by week of year.
495 * The International Standard IS-8601 has decreed that Monday
496 * shall be the first day of the week.
498 * A week that lies partly in one year and partly in another
499 * is assigned a number in the year in which most of its days lie.
501 * That means that week 1 of any year is the week that contains the 4. January
503 * The internal representation of a Date used in the Addin is the number of days based on 01/01/0001
505 * A WeekDay can be then calculated by subtracting 1 and calculating the rest of
506 * a division by 7, which gives a 0 - 6 value for Monday - Sunday
508 * Using the 4. January rule explained above the formula
510 * nWeek1= ( nDays1 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
512 * calculates a number between 0-53 for each day which is in the same year as nJan4
513 * where 0 means that this week belonged to the year before.
515 * If a day in the same or another year is used in this formula this calculates
516 * an calendar week offset from a given 4. January
518 * nWeek2 = ( nDays2 - nJan4 + ( (nJan4-1) % 7 ) ) / 7 + 1;
520 * The 4.January of first Date Argument can thus be used to calculate
521 * the week difference by calendar weeks which is then nWeek = nWeek2 - nWeek1
523 * which can be optimized to
525 * nWeek = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 )
527 * Note: All calculations are operating on the long integer data type
528 * % is the modulo operator in C which calculates the rest of an Integer division
531 * mode 0 is the interval between the dates in month, that is days / 7
533 * mode 1 is the difference by week of year
537 sal_Int32 SAL_CALL ScaDateAddIn::getDiffWeeks(
538 const uno::Reference< beans::XPropertySet >& xOptions,
539 sal_Int32 nStartDate, sal_Int32 nEndDate,
540 sal_Int32 nMode )
542 if (nMode != 0 && nMode != 1)
543 throw lang::IllegalArgumentException();
545 sal_Int32 nNullDate = GetNullDate( xOptions );
547 sal_Int32 nDays1 = nStartDate + nNullDate;
548 sal_Int32 nDays2 = nEndDate + nNullDate;
550 sal_Int32 nRet;
552 if ( nMode == 1 )
554 sal_uInt16 nDay,nMonth,nYear;
555 DaysToDate( nDays1, nDay, nMonth, nYear );
556 sal_Int32 nJan4 = DateToDays( 4, 1, nYear );
558 nRet = ( (nDays2-nJan4+((nJan4-1)%7))/7 ) - ( (nDays1-nJan4+((nJan4-1)%7))/7 );
560 else
562 nRet = (nDays2 - nDays1) / 7;
564 return nRet;
568 * Get month difference between 2 dates
569 * =Month(start, end, mode) Function for StarCalc
571 * two modes are provided
573 * mode 0 is the interval between the dates in month
575 * mode 1 is the difference in calendar month
577 sal_Int32 SAL_CALL ScaDateAddIn::getDiffMonths(
578 const uno::Reference< beans::XPropertySet >& xOptions,
579 sal_Int32 nStartDate, sal_Int32 nEndDate,
580 sal_Int32 nMode )
582 if (nMode != 0 && nMode != 1)
583 throw lang::IllegalArgumentException();
585 sal_Int32 nNullDate = GetNullDate( xOptions );
587 sal_Int32 nDays1 = nStartDate + nNullDate;
588 sal_Int32 nDays2 = nEndDate + nNullDate;
590 sal_uInt16 nDay1,nMonth1,nYear1;
591 sal_uInt16 nDay2,nMonth2,nYear2;
592 DaysToDate(nDays1,nDay1,nMonth1,nYear1);
593 DaysToDate(nDays2,nDay2,nMonth2,nYear2);
595 sal_Int32 nRet = nMonth2 - nMonth1 + (nYear2 - nYear1) * 12;
596 if ( nMode == 1 || nDays1 == nDays2 ) return nRet;
598 if ( nDays1 < nDays2 )
600 if ( nDay1 > nDay2 )
602 nRet -= 1;
605 else
607 if ( nDay1 < nDay2 )
609 nRet += 1;
613 return nRet;
617 * Get Year difference between 2 dates
619 * two modes are provided
621 * mode 0 is the interval between the dates in years
623 * mode 1 is the difference in calendar years
625 sal_Int32 SAL_CALL ScaDateAddIn::getDiffYears(
626 const uno::Reference< beans::XPropertySet >& xOptions,
627 sal_Int32 nStartDate, sal_Int32 nEndDate,
628 sal_Int32 nMode )
630 if (nMode != 0 && nMode != 1)
631 throw lang::IllegalArgumentException();
633 if ( nMode != 1 )
634 return getDiffMonths( xOptions, nStartDate, nEndDate, nMode ) / 12;
636 sal_Int32 nNullDate = GetNullDate( xOptions );
638 sal_Int32 nDays1 = nStartDate + nNullDate;
639 sal_Int32 nDays2 = nEndDate + nNullDate;
641 sal_uInt16 nDay1,nMonth1,nYear1;
642 sal_uInt16 nDay2,nMonth2,nYear2;
643 DaysToDate(nDays1,nDay1,nMonth1,nYear1);
644 DaysToDate(nDays2,nDay2,nMonth2,nYear2);
646 return nYear2 - nYear1;
650 * Check if a Date is in a leap year in the Gregorian calendar
652 sal_Int32 SAL_CALL ScaDateAddIn::getIsLeapYear(
653 const uno::Reference< beans::XPropertySet >& xOptions,
654 sal_Int32 nDate )
656 sal_Int32 nNullDate = GetNullDate( xOptions );
657 sal_Int32 nDays = nDate + nNullDate;
659 sal_uInt16 nDay, nMonth, nYear;
660 DaysToDate(nDays,nDay,nMonth,nYear);
662 return static_cast<sal_Int32>(IsLeapYear(nYear));
666 * Get the Number of Days in the month for a date
668 sal_Int32 SAL_CALL ScaDateAddIn::getDaysInMonth(
669 const uno::Reference<beans::XPropertySet>& xOptions,
670 sal_Int32 nDate )
672 sal_Int32 nNullDate = GetNullDate( xOptions );
673 sal_Int32 nDays = nDate + nNullDate;
675 sal_uInt16 nDay, nMonth, nYear;
676 DaysToDate(nDays,nDay,nMonth,nYear);
678 return DaysInMonth( nMonth, nYear );
682 * Get number of days in the year of a date specified
684 sal_Int32 SAL_CALL ScaDateAddIn::getDaysInYear(
685 const uno::Reference< beans::XPropertySet >& xOptions,
686 sal_Int32 nDate )
688 sal_Int32 nNullDate = GetNullDate( xOptions );
689 sal_Int32 nDays = nDate + nNullDate;
691 sal_uInt16 nDay, nMonth, nYear;
692 DaysToDate(nDays,nDay,nMonth,nYear);
694 return ( IsLeapYear(nYear) ? 366 : 365 );
698 * Get number of weeks in the year for a date
700 * Most years have 52 weeks, but years that start on a Thursday
701 * and leap years that start on a Wednesday have 53 weeks
703 * The International Standard IS-8601 has decreed that Monday
704 * shall be the first day of the week.
706 * A WeekDay can be calculated by subtracting 1 and calculating the rest of
707 * a division by 7 from the internal date represention
708 * which gives a 0 - 6 value for Monday - Sunday
710 * @see #IsLeapYear #WeekNumber
712 sal_Int32 SAL_CALL ScaDateAddIn::getWeeksInYear(
713 const uno::Reference< beans::XPropertySet >& xOptions,
714 sal_Int32 nDate )
716 sal_Int32 nNullDate = GetNullDate( xOptions );
717 sal_Int32 nDays = nDate + nNullDate;
719 sal_uInt16 nDay, nMonth, nYear;
720 DaysToDate(nDays,nDay,nMonth,nYear);
722 sal_Int32 nJan1WeekDay = ( DateToDays(1,1,nYear) - 1) % 7;
724 sal_Int32 nRet;
725 if ( nJan1WeekDay == 3 ) /* Thursday */
726 nRet = 53;
727 else if ( nJan1WeekDay == 2 ) /* Wednesday */
728 nRet = ( IsLeapYear(nYear) ? 53 : 52 );
729 else
730 nRet = 52;
732 return nRet;
736 * Encrypt or decrypt a string using ROT13 algorithm
738 * This function rotates each character by 13 in the alphabet.
739 * Only the characters 'a' ... 'z' and 'A' ... 'Z' are modified.
741 OUString SAL_CALL ScaDateAddIn::getRot13( const OUString& aSrcString )
743 OUStringBuffer aBuffer( aSrcString );
744 for( sal_Int32 nIndex = 0; nIndex < aBuffer.getLength(); nIndex++ )
746 sal_Unicode cChar = aBuffer[nIndex];
747 if( ((cChar >= 'a') && (cChar <= 'z') && ((cChar += 13) > 'z')) ||
748 ((cChar >= 'A') && (cChar <= 'Z') && ((cChar += 13) > 'Z')) )
749 cChar -= 26;
750 aBuffer[nIndex] = cChar;
752 return aBuffer.makeStringAndClear();
755 OUString ScaDateAddIn::ScaResId(const char* pId)
757 return Translate::get(pId, aResLocale);
760 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */