Update ooo320-m1
[ooovba.git] / basic / source / sbx / sbxdate.cxx
blobefa5daef97d38d89545a6d90a9488b0b03c4fc6c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sbxdate.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 #include <vcl/svapp.hxx>
34 #include <svtools/zforlist.hxx>
35 #include <tools/errcode.hxx>
36 #include <tools/color.hxx>
37 #include <i18npool/lang.h>
38 #include <basic/sbx.hxx>
39 #include "sbxconv.hxx"
40 #include "math.h"
41 #include <comphelper/processfactory.hxx>
44 double ImpGetDate( const SbxValues* p )
46 double nRes;
47 switch( +p->eType )
49 case SbxNULL:
50 SbxBase::SetError( SbxERR_CONVERSION );
51 case SbxEMPTY:
52 nRes = 0; break;
53 case SbxCHAR:
54 nRes = p->nChar; break;
55 case SbxBYTE:
56 nRes = p->nByte; break;
57 case SbxINTEGER:
58 case SbxBOOL:
59 nRes = p->nInteger; break;
60 case SbxERROR:
61 case SbxUSHORT:
62 nRes = p->nUShort; break;
63 case SbxLONG:
64 nRes = (double) p->nLong; break;
65 case SbxULONG:
66 nRes = (double) p->nULong; break;
67 case SbxSINGLE:
68 nRes = p->nSingle; break;
69 case SbxDATE:
70 case SbxDOUBLE:
71 nRes = p->nDouble; break;
72 case SbxULONG64:
73 nRes = ImpUINT64ToDouble( p->nULong64 ); break;
74 case SbxLONG64:
75 nRes = ImpINT64ToDouble( p->nLong64 ); break;
76 case SbxCURRENCY:
77 nRes = ImpCurrencyToDouble( p->nLong64 ); break;
78 case SbxSALINT64:
79 nRes = static_cast< double >(p->nInt64); break;
80 case SbxSALUINT64:
81 nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
82 case SbxDECIMAL:
83 case SbxBYREF | SbxDECIMAL:
84 if( p->pDecimal )
85 p->pDecimal->getDouble( nRes );
86 else
87 nRes = 0.0;
88 break;
89 case SbxBYREF | SbxSTRING:
90 case SbxSTRING:
91 case SbxLPSTR:
92 if( !p->pString )
93 nRes = 0;
94 else
96 #ifndef DOS
97 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
99 SvNumberFormatter* pFormatter;
100 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
101 xFactory = comphelper::getProcessServiceFactory();
102 pFormatter = new SvNumberFormatter( xFactory, eLangType );
104 sal_uInt32 nIndex;
105 xub_StrLen nCheckPos = 0;
106 short nType = 127;
108 // Standard-Vorlagen des Formatters haben nur zweistellige
109 // Jahreszahl. Deshalb eigenes Format registrieren
111 // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
112 // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
113 // austauscht. Problem: Print Year(Date) unter engl. BS
114 // siehe auch basic\source\runtime\runtime.cxx
116 SvtSysLocale aSysLocale;
117 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
118 String aDateStr;
119 switch( eDate )
121 case MDY: aDateStr.AssignAscii( "MM.TT.JJJJ" ); break;
122 case DMY: aDateStr.AssignAscii( "TT.MM.JJJJ" ); break;
123 case YMD: aDateStr.AssignAscii( "JJJJ.MM.TT" ); break;
124 default: aDateStr.AssignAscii( "MM.TT.JJJJ" );
127 String aStr( aDateStr );
128 aStr.AppendAscii( " HH:MM:SS" );
130 pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
131 nIndex, LANGUAGE_GERMAN, eLangType );
132 BOOL bSuccess = pFormatter->IsNumberFormat( *p->pString, nIndex, nRes );
133 if ( bSuccess )
135 short nType_ = pFormatter->GetType( nIndex );
136 if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
137 NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
138 bSuccess = FALSE;
141 if ( !bSuccess )
143 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
146 delete pFormatter;
147 #else
148 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
149 #endif
151 break;
152 case SbxOBJECT:
154 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
155 if( pVal )
156 nRes = pVal->GetDate();
157 else
159 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
161 break;
164 case SbxBYREF | SbxCHAR:
165 nRes = *p->pChar; break;
166 case SbxBYREF | SbxBYTE:
167 nRes = *p->pByte; break;
168 case SbxBYREF | SbxINTEGER:
169 case SbxBYREF | SbxBOOL:
170 nRes = *p->pInteger; break;
171 case SbxBYREF | SbxLONG:
172 nRes = *p->pLong; break;
173 case SbxBYREF | SbxULONG:
174 nRes = *p->pULong; break;
175 case SbxBYREF | SbxERROR:
176 case SbxBYREF | SbxUSHORT:
177 nRes = *p->pUShort; break;
178 case SbxBYREF | SbxSINGLE:
179 nRes = *p->pSingle; break;
180 case SbxBYREF | SbxDATE:
181 case SbxBYREF | SbxDOUBLE:
182 nRes = *p->pDouble; break;
183 case SbxBYREF | SbxULONG64:
184 nRes = ImpUINT64ToDouble( *p->pULong64 ); break;
185 case SbxBYREF | SbxLONG64:
186 nRes = ImpINT64ToDouble( *p->pLong64 ); break;
187 case SbxBYREF | SbxCURRENCY:
188 nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
189 case SbxBYREF | SbxSALINT64:
190 nRes = static_cast< double >(*p->pnInt64); break;
191 case SbxBYREF | SbxSALUINT64:
192 nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
194 default:
195 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
197 return nRes;
200 void ImpPutDate( SbxValues* p, double n )
202 SbxValues aTmp;
204 start:
205 switch( +p->eType )
207 case SbxDATE:
208 case SbxDOUBLE:
209 p->nDouble = n; break;
211 // ab hier wird getestet
212 case SbxCHAR:
213 aTmp.pChar = &p->nChar; goto direct;
214 case SbxBYTE:
215 aTmp.pByte = &p->nByte; goto direct;
216 case SbxINTEGER:
217 case SbxBOOL:
218 aTmp.pInteger = &p->nInteger; goto direct;
219 case SbxLONG:
220 aTmp.pLong = &p->nLong; goto direct;
221 case SbxULONG:
222 aTmp.pULong = &p->nULong; goto direct;
223 case SbxERROR:
224 case SbxUSHORT:
225 aTmp.pUShort = &p->nUShort; goto direct;
226 case SbxSINGLE:
227 aTmp.pSingle = &p->nSingle; goto direct;
228 case SbxULONG64:
229 aTmp.pULong64 = &p->nULong64; goto direct;
230 case SbxLONG64:
231 case SbxCURRENCY:
232 aTmp.pLong64 = &p->nLong64; goto direct;
233 case SbxSALINT64:
234 aTmp.pnInt64 = &p->nInt64; goto direct;
235 case SbxSALUINT64:
236 aTmp.puInt64 = &p->uInt64; goto direct;
237 case SbxDECIMAL:
238 case SbxBYREF | SbxDECIMAL:
240 SbxDecimal* pDec = ImpCreateDecimal( p );
241 if( !pDec->setDouble( n ) )
242 SbxBase::SetError( SbxERR_OVERFLOW );
243 break;
245 direct:
246 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
247 p = &aTmp; goto start;
249 case SbxBYREF | SbxSTRING:
250 case SbxSTRING:
251 case SbxLPSTR:
252 #ifndef DOS
254 if( !p->pString )
255 p->pString = new XubString;
256 Color* pColor;
258 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
259 SvNumberFormatter* pFormatter;
260 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
261 xFactory = comphelper::getProcessServiceFactory();
262 pFormatter = new SvNumberFormatter( xFactory, eLangType );
264 sal_uInt32 nIndex;
265 xub_StrLen nCheckPos = 0;
266 short nType;
268 SvtSysLocale aSysLocale;
269 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
270 String aStr;
271 // ist der ganzzahlige Teil 0, wollen wir kein Jahr!
272 if( n <= -1.0 || n >= 1.0 )
274 // Time only if != 00:00:00
275 if( floor( n ) == n )
277 switch( eDate )
279 case MDY: aStr.AssignAscii( "MM.TT.JJJJ" ); break;
280 case DMY: aStr.AssignAscii( "TT.MM.JJJJ" ); break;
281 case YMD: aStr.AssignAscii( "JJJJ.MM.TT" ); break;
282 default: aStr.AssignAscii( "MM.TT.JJJJ" );
285 else
287 switch( eDate )
289 case MDY: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); break;
290 case DMY: aStr.AssignAscii( "TT.MM.JJJJ HH:MM:SS" ); break;
291 case YMD: aStr.AssignAscii( "JJJJ.MM.TT HH:MM:SS" ); break;
292 default: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" );
296 else
297 aStr.AppendAscii( "HH:MM:SS" );
299 pFormatter->PutandConvertEntry( aStr,
300 nCheckPos,
301 nType,
302 nIndex,
303 LANGUAGE_GERMAN,
304 eLangType );
305 pFormatter->GetOutputString( n, nIndex, *p->pString, &pColor );
306 delete pFormatter;
307 #endif
308 break;
309 #ifndef DOS
311 #endif
312 case SbxOBJECT:
314 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
315 if( pVal )
316 pVal->PutDate( n );
317 else
318 SbxBase::SetError( SbxERR_NO_OBJECT );
319 break;
321 case SbxBYREF | SbxCHAR:
322 if( n > SbxMAXCHAR )
324 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
326 else if( n < SbxMINCHAR )
328 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
330 *p->pChar = (xub_Unicode) n; break;
331 case SbxBYREF | SbxBYTE:
332 if( n > SbxMAXBYTE )
334 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
336 else if( n < 0 )
338 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
340 *p->pByte = (BYTE) n; break;
341 case SbxBYREF | SbxINTEGER:
342 case SbxBYREF | SbxBOOL:
343 if( n > SbxMAXINT )
345 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
347 else if( n < SbxMININT )
349 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
351 *p->pInteger = (INT16) n; break;
352 case SbxBYREF | SbxERROR:
353 case SbxBYREF | SbxUSHORT:
354 if( n > SbxMAXUINT )
356 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
358 else if( n < 0 )
360 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
362 *p->pUShort = (UINT16) n; break;
363 case SbxBYREF | SbxLONG:
364 if( n > SbxMAXLNG )
366 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
368 else if( n < SbxMINLNG )
370 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
372 *p->pLong = (INT32) n; break;
373 case SbxBYREF | SbxULONG:
374 if( n > SbxMAXULNG )
376 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
378 else if( n < 0 )
380 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
382 *p->pULong = (UINT32) n; break;
383 case SbxBYREF | SbxSINGLE:
384 if( n > SbxMAXSNG )
386 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
388 else if( n < SbxMINSNG )
390 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
392 *p->pSingle = (float) n; break;
393 case SbxBYREF | SbxSALINT64:
394 *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
395 case SbxBYREF | SbxSALUINT64:
396 *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
397 case SbxBYREF | SbxDATE:
398 case SbxBYREF | SbxDOUBLE:
399 *p->pDouble = (double) n; break;
400 case SbxBYREF | SbxCURRENCY:
401 if( n > SbxMAXCURR )
403 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
405 else if( n < SbxMINCURR )
407 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
409 *p->pLong64 = ImpDoubleToCurrency( n ); break;
411 default:
412 SbxBase::SetError( SbxERR_CONVERSION );