xref: /AOO41X/main/basic/source/sbx/sbxdate.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 #include <vcl/svapp.hxx>
27 #include <svl/zforlist.hxx>
28 #include <tools/errcode.hxx>
29 #include <tools/color.hxx>
30 #include <i18npool/lang.h>
31 #include <basic/sbx.hxx>
32 #include "sbxconv.hxx"
33 #include "math.h"
34 #include <comphelper/processfactory.hxx>
35 
36 
ImpGetDate(const SbxValues * p)37 double ImpGetDate( const SbxValues* p )
38 {
39     double nRes;
40     switch( +p->eType )
41     {
42         case SbxNULL:
43             SbxBase::SetError( SbxERR_CONVERSION );
44         case SbxEMPTY:
45             nRes = 0; break;
46         case SbxCHAR:
47             nRes = p->nChar; break;
48         case SbxBYTE:
49             nRes = p->nByte; break;
50         case SbxINTEGER:
51         case SbxBOOL:
52             nRes = p->nInteger; break;
53         case SbxERROR:
54         case SbxUSHORT:
55             nRes = p->nUShort; break;
56         case SbxLONG:
57             nRes = (double) p->nLong; break;
58         case SbxULONG:
59             nRes = (double) p->nULong; break;
60         case SbxSINGLE:
61             nRes = p->nSingle; break;
62         case SbxDATE:
63         case SbxDOUBLE:
64             nRes = p->nDouble; break;
65         case SbxULONG64:
66             nRes = ImpUINT64ToDouble( p->nULong64 ); break;
67         case SbxLONG64:
68             nRes = ImpINT64ToDouble( p->nLong64 ); break;
69         case SbxCURRENCY:
70             nRes = ImpCurrencyToDouble( p->nLong64 ); break;
71         case SbxSALINT64:
72             nRes = static_cast< double >(p->nInt64); break;
73         case SbxSALUINT64:
74             nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
75         case SbxDECIMAL:
76         case SbxBYREF | SbxDECIMAL:
77             if( p->pDecimal )
78                 p->pDecimal->getDouble( nRes );
79             else
80                 nRes = 0.0;
81             break;
82         case SbxBYREF | SbxSTRING:
83         case SbxSTRING:
84         case SbxLPSTR:
85             if( !p->pOUString )
86                 nRes = 0;
87             else
88             {
89                 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
90 
91                 SvNumberFormatter* pFormatter;
92                 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
93                     xFactory = comphelper::getProcessServiceFactory();
94                 pFormatter = new SvNumberFormatter( xFactory, eLangType );
95 
96                 sal_uInt32 nIndex;
97                 xub_StrLen nCheckPos = 0;
98                 short nType = 127;
99 
100                 // Standard-Vorlagen des Formatters haben nur zweistellige
101                 // Jahreszahl. Deshalb eigenes Format registrieren
102 
103                 // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
104                 // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
105                 // austauscht. Problem: Print Year(Date) unter engl. BS
106                 // siehe auch basic\source\runtime\runtime.cxx
107 
108                 SvtSysLocale aSysLocale;
109                 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
110                 String aDateStr;
111                 switch( eDate )
112                 {
113                     case MDY: aDateStr.AssignAscii( "MM.TT.JJJJ" ); break;
114                     case DMY: aDateStr.AssignAscii( "TT.MM.JJJJ" ); break;
115                     case YMD: aDateStr.AssignAscii( "JJJJ.MM.TT" ); break;
116                     default:  aDateStr.AssignAscii( "MM.TT.JJJJ" );
117                 }
118 
119                 String aStr( aDateStr );
120                 aStr.AppendAscii( " HH:MM:SS" );
121 
122                 pFormatter->PutandConvertEntry( aStr, nCheckPos,    nType,
123                     nIndex, LANGUAGE_GERMAN, eLangType );
124                 sal_Bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes );
125                 if ( bSuccess )
126                 {
127                     short nType_ = pFormatter->GetType( nIndex );
128                     if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
129                                     NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
130                         bSuccess = sal_False;
131                 }
132 
133                 if ( !bSuccess )
134                 {
135                     SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
136                 }
137 
138                 delete pFormatter;
139             }
140             break;
141         case SbxOBJECT:
142         {
143             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
144             if( pVal )
145                 nRes = pVal->GetDate();
146             else
147             {
148                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
149             }
150             break;
151         }
152 
153         case SbxBYREF | SbxCHAR:
154             nRes = *p->pChar; break;
155         case SbxBYREF | SbxBYTE:
156             nRes = *p->pByte; break;
157         case SbxBYREF | SbxINTEGER:
158         case SbxBYREF | SbxBOOL:
159             nRes = *p->pInteger; break;
160         case SbxBYREF | SbxLONG:
161             nRes = *p->pLong; break;
162         case SbxBYREF | SbxULONG:
163             nRes = *p->pULong; break;
164         case SbxBYREF | SbxERROR:
165         case SbxBYREF | SbxUSHORT:
166             nRes = *p->pUShort; break;
167         case SbxBYREF | SbxSINGLE:
168             nRes = *p->pSingle; break;
169         case SbxBYREF | SbxDATE:
170         case SbxBYREF | SbxDOUBLE:
171             nRes = *p->pDouble; break;
172         case SbxBYREF | SbxULONG64:
173             nRes = ImpUINT64ToDouble( *p->pULong64 ); break;
174         case SbxBYREF | SbxLONG64:
175             nRes = ImpINT64ToDouble( *p->pLong64 ); break;
176         case SbxBYREF | SbxCURRENCY:
177             nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
178         case SbxBYREF | SbxSALINT64:
179             nRes = static_cast< double >(*p->pnInt64); break;
180         case SbxBYREF | SbxSALUINT64:
181             nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
182 
183         default:
184             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
185     }
186     return nRes;
187 }
188 
ImpPutDate(SbxValues * p,double n)189 void ImpPutDate( SbxValues* p, double n )
190 {
191     SbxValues aTmp;
192 
193 start:
194     switch( +p->eType )
195     {
196         case SbxDATE:
197         case SbxDOUBLE:
198             p->nDouble = n; break;
199 
200         // ab hier wird getestet
201         case SbxCHAR:
202             aTmp.pChar = &p->nChar; goto direct;
203         case SbxBYTE:
204             aTmp.pByte = &p->nByte; goto direct;
205         case SbxINTEGER:
206         case SbxBOOL:
207             aTmp.pInteger = &p->nInteger; goto direct;
208         case SbxLONG:
209             aTmp.pLong = &p->nLong; goto direct;
210         case SbxULONG:
211             aTmp.pULong = &p->nULong; goto direct;
212         case SbxERROR:
213         case SbxUSHORT:
214             aTmp.pUShort = &p->nUShort; goto direct;
215         case SbxSINGLE:
216             aTmp.pSingle = &p->nSingle; goto direct;
217         case SbxULONG64:
218             aTmp.pULong64 = &p->nULong64; goto direct;
219         case SbxLONG64:
220         case SbxCURRENCY:
221             aTmp.pLong64 = &p->nLong64; goto direct;
222         case SbxSALINT64:
223             aTmp.pnInt64 = &p->nInt64; goto direct;
224         case SbxSALUINT64:
225             aTmp.puInt64 = &p->uInt64; goto direct;
226         case SbxDECIMAL:
227         case SbxBYREF | SbxDECIMAL:
228             {
229             SbxDecimal* pDec = ImpCreateDecimal( p );
230             if( !pDec->setDouble( n ) )
231                 SbxBase::SetError( SbxERR_OVERFLOW );
232             break;
233             }
234         direct:
235             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
236             p = &aTmp; goto start;
237 
238         case SbxBYREF | SbxSTRING:
239         case SbxSTRING:
240         case SbxLPSTR:
241         {
242             if( !p->pOUString )
243                 p->pOUString = new ::rtl::OUString;
244             Color* pColor;
245 
246             LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
247             SvNumberFormatter* pFormatter;
248             com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
249                 xFactory = comphelper::getProcessServiceFactory();
250             pFormatter = new SvNumberFormatter( xFactory, eLangType );
251 
252             sal_uInt32 nIndex;
253             xub_StrLen nCheckPos = 0;
254             short nType;
255 
256             SvtSysLocale aSysLocale;
257             DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
258             String aStr;
259             // ist der ganzzahlige Teil 0, wollen wir kein Jahr!
260             if( n <= -1.0 || n >= 1.0 )
261             {
262                 // Time only if != 00:00:00
263                 if( floor( n ) == n )
264                 {
265                     switch( eDate )
266                     {
267                         case MDY: aStr.AssignAscii( "MM.TT.JJJJ" ); break;
268                         case DMY: aStr.AssignAscii( "TT.MM.JJJJ" ); break;
269                         case YMD: aStr.AssignAscii( "JJJJ.MM.TT" ); break;
270                         default:  aStr.AssignAscii( "MM.TT.JJJJ" );
271                     }
272                 }
273                 else
274                 {
275                     switch( eDate )
276                     {
277                         case MDY: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); break;
278                         case DMY: aStr.AssignAscii( "TT.MM.JJJJ HH:MM:SS" ); break;
279                         case YMD: aStr.AssignAscii( "JJJJ.MM.TT HH:MM:SS" ); break;
280                         default:  aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" );
281                     }
282                 }
283             }
284             else
285                 aStr.AppendAscii( "HH:MM:SS" );
286 
287             pFormatter->PutandConvertEntry( aStr,
288                 nCheckPos,
289                 nType,
290                 nIndex,
291                 LANGUAGE_GERMAN,
292                 eLangType );
293             String aTmpString;
294             pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor );
295             *p->pOUString = aTmpString;
296             delete pFormatter;
297             break;
298         }
299         case SbxOBJECT:
300         {
301             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
302             if( pVal )
303                 pVal->PutDate( n );
304             else
305                 SbxBase::SetError( SbxERR_NO_OBJECT );
306             break;
307         }
308         case SbxBYREF | SbxCHAR:
309             if( n > SbxMAXCHAR )
310             {
311                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
312             }
313             else if( n < SbxMINCHAR )
314             {
315                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
316             }
317             *p->pChar = (xub_Unicode) n; break;
318         case SbxBYREF | SbxBYTE:
319             if( n > SbxMAXBYTE )
320             {
321                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
322             }
323             else if( n < 0 )
324             {
325                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
326             }
327             *p->pByte = (sal_uInt8) n; break;
328         case SbxBYREF | SbxINTEGER:
329         case SbxBYREF | SbxBOOL:
330             if( n > SbxMAXINT )
331             {
332                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
333             }
334             else if( n < SbxMININT )
335             {
336                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
337             }
338             *p->pInteger = (sal_Int16) n; break;
339         case SbxBYREF | SbxERROR:
340         case SbxBYREF | SbxUSHORT:
341             if( n > SbxMAXUINT )
342             {
343                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
344             }
345             else if( n < 0 )
346             {
347                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
348             }
349             *p->pUShort = (sal_uInt16) n; break;
350         case SbxBYREF | SbxLONG:
351             if( n > SbxMAXLNG )
352             {
353                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
354             }
355             else if( n < SbxMINLNG )
356             {
357                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
358             }
359             *p->pLong = (sal_Int32) n; break;
360         case SbxBYREF | SbxULONG:
361             if( n > SbxMAXULNG )
362             {
363                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
364             }
365             else if( n < 0 )
366             {
367                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
368             }
369             *p->pULong = (sal_uInt32) n; break;
370         case SbxBYREF | SbxSINGLE:
371             if( n > SbxMAXSNG )
372             {
373                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
374             }
375             else if( n < SbxMINSNG )
376             {
377                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
378             }
379             *p->pSingle = (float) n; break;
380         case SbxBYREF | SbxSALINT64:
381             *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
382         case SbxBYREF | SbxSALUINT64:
383             *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
384         case SbxBYREF | SbxDATE:
385         case SbxBYREF | SbxDOUBLE:
386             *p->pDouble = (double) n; break;
387         case SbxBYREF | SbxCURRENCY:
388             if( n > SbxMAXCURR )
389             {
390                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
391             }
392             else if( n < SbxMINCURR )
393             {
394                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
395             }
396             *p->pLong64 = ImpDoubleToCurrency( n ); break;
397 
398         default:
399             SbxBase::SetError( SbxERR_CONVERSION );
400     }
401 }
402 
403