Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / basic / source / sbx / sbxdate.cxx
blob6d0a4073a64ae33db03b39500a0b339c63a02c22
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 <vcl/svapp.hxx>
21 #include <svl/zforlist.hxx>
22 #include <tools/errcode.hxx>
23 #include <tools/color.hxx>
24 #include <i18npool/lang.h>
25 #include <basic/sbx.hxx>
26 #include "sbxconv.hxx"
27 #include "math.h"
28 #include <comphelper/processfactory.hxx>
31 double ImpGetDate( const SbxValues* p )
33 double nRes;
34 SbxValue* pVal;
36 switch( +p->eType )
38 case SbxNULL:
39 SbxBase::SetError( SbxERR_CONVERSION );
40 case SbxEMPTY:
41 nRes = 0;
42 break;
43 case SbxCHAR:
44 nRes = p->nChar;
45 break;
46 case SbxBYTE:
47 nRes = p->nByte;
48 break;
49 case SbxINTEGER:
50 case SbxBOOL:
51 nRes = p->nInteger;
52 break;
53 case SbxERROR:
54 case SbxUSHORT:
55 nRes = p->nUShort;
56 break;
57 case SbxLONG:
58 nRes = (double) p->nLong;
59 break;
60 case SbxULONG:
61 nRes = (double) p->nULong;
62 break;
63 case SbxSINGLE:
64 nRes = p->nSingle;
65 break;
66 case SbxDATE:
67 case SbxDOUBLE:
68 nRes = p->nDouble;
69 break;
70 case SbxCURRENCY:
71 nRes = ImpCurrencyToDouble( p->nInt64 );
72 break;
73 case SbxSALINT64:
74 nRes = static_cast< double >(p->nInt64);
75 break;
76 case SbxSALUINT64:
77 nRes = ImpSalUInt64ToDouble( p->uInt64 );
78 break;
79 case SbxDECIMAL:
80 case SbxBYREF | SbxDECIMAL:
81 if( p->pDecimal )
83 p->pDecimal->getDouble( nRes );
85 else
87 nRes = 0.0;
89 break;
90 case SbxBYREF | SbxSTRING:
91 case SbxSTRING:
92 case SbxLPSTR:
93 if( !p->pOUString )
95 nRes = 0;
97 else
99 LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
101 SvNumberFormatter* pFormatter;
102 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
103 xFactory = comphelper::getProcessServiceFactory();
104 pFormatter = new SvNumberFormatter( xFactory, eLangType );
106 sal_uInt32 nIndex;
107 sal_Int32 nCheckPos = 0;
108 short nType = 127;
110 // Default templates of the formatter have only two-digit
111 // date. Therefore register an own format.
113 // HACK, because the number formatter in PutandConvertEntry replace the wildcard
114 // for month, day, year not according to the configuration.
115 // Problem: Print Year(Date) under Engl. OS
116 // quod vide basic\source\runtime\runtime.cxx
118 SvtSysLocale aSysLocale;
119 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
120 OUString aDateStr;
121 switch( eDate )
123 case MDY: aDateStr = "MM.TT.JJJJ"; break;
124 case DMY: aDateStr = "TT.MM.JJJJ"; break;
125 case YMD: aDateStr = "JJJJ.MM.TT"; break;
126 default: aDateStr = "MM.TT.JJJJ";
129 OUString aStr( aDateStr );
130 aStr += " HH:MM:SS";
132 pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
133 nIndex, LANGUAGE_GERMAN, eLangType );
134 sal_Bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes );
135 if ( bSuccess )
137 short nType_ = pFormatter->GetType( nIndex );
138 if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
139 NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
141 bSuccess = sal_False;
145 if ( !bSuccess )
147 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
150 delete pFormatter;
152 break;
153 case SbxOBJECT:
154 pVal = PTR_CAST(SbxValue,p->pObj);
155 if( pVal )
157 nRes = pVal->GetDate();
159 else
161 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
163 break;
164 case SbxBYREF | SbxCHAR:
165 nRes = *p->pChar;
166 break;
167 case SbxBYREF | SbxBYTE:
168 nRes = *p->pByte;
169 break;
170 case SbxBYREF | SbxINTEGER:
171 case SbxBYREF | SbxBOOL:
172 nRes = *p->pInteger;
173 break;
174 case SbxBYREF | SbxLONG:
175 nRes = *p->pLong;
176 break;
177 case SbxBYREF | SbxULONG:
178 nRes = *p->pULong;
179 break;
180 case SbxBYREF | SbxERROR:
181 case SbxBYREF | SbxUSHORT:
182 nRes = *p->pUShort;
183 break;
184 case SbxBYREF | SbxSINGLE:
185 nRes = *p->pSingle;
186 break;
187 case SbxBYREF | SbxDATE:
188 case SbxBYREF | SbxDOUBLE:
189 nRes = *p->pDouble;
190 break;
191 case SbxBYREF | SbxCURRENCY:
192 nRes = ImpCurrencyToDouble( *p->pnInt64 );
193 break;
194 case SbxBYREF | SbxSALINT64:
195 nRes = static_cast< double >(*p->pnInt64);
196 break;
197 case SbxBYREF | SbxSALUINT64:
198 nRes = ImpSalUInt64ToDouble( *p->puInt64 );
199 break;
200 default:
201 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
202 break;
204 return nRes;
207 void ImpPutDate( SbxValues* p, double n )
209 SbxValues aTmp;
210 SbxDecimal* pDec;
211 SbxValue* pVal;
213 start:
214 switch( +p->eType )
216 case SbxDATE:
217 case SbxDOUBLE:
218 p->nDouble = n;
219 break;
220 // from here will be tested
221 case SbxCHAR:
222 aTmp.pChar = &p->nChar;
223 goto direct;
224 case SbxBYTE:
225 aTmp.pByte = &p->nByte;
226 goto direct;
227 case SbxINTEGER:
228 case SbxBOOL:
229 aTmp.pInteger = &p->nInteger;
230 goto direct;
231 case SbxLONG:
232 aTmp.pLong = &p->nLong;
233 goto direct;
234 case SbxULONG:
235 aTmp.pULong = &p->nULong;
236 goto direct;
237 case SbxERROR:
238 case SbxUSHORT:
239 aTmp.pUShort = &p->nUShort;
240 goto direct;
241 case SbxSINGLE:
242 aTmp.pSingle = &p->nSingle;
243 goto direct;
244 case SbxCURRENCY:
245 case SbxSALINT64:
246 aTmp.pnInt64 = &p->nInt64;
247 goto direct;
248 case SbxSALUINT64:
249 aTmp.puInt64 = &p->uInt64;
250 goto direct;
251 case SbxDECIMAL:
252 case SbxBYREF | SbxDECIMAL:
253 pDec = ImpCreateDecimal( p );
254 if( !pDec->setDouble( n ) )
256 SbxBase::SetError( SbxERR_OVERFLOW );
258 break;
259 direct:
260 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
261 p = &aTmp; goto start;
263 case SbxBYREF | SbxSTRING:
264 case SbxSTRING:
265 case SbxLPSTR:
267 if( !p->pOUString )
269 p->pOUString = new OUString;
271 Color* pColor;
273 LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
274 SvNumberFormatter* pFormatter;
275 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
276 xFactory = comphelper::getProcessServiceFactory();
277 pFormatter = new SvNumberFormatter( xFactory, eLangType );
279 sal_uInt32 nIndex;
280 sal_Int32 nCheckPos = 0;
281 short nType;
283 SvtSysLocale aSysLocale;
284 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
285 OUString aStr;
286 // if the whole-number part is 0, we want no year!
287 if( n <= -1.0 || n >= 1.0 )
289 // Time only if != 00:00:00
290 if( floor( n ) == n )
292 switch( eDate )
294 case MDY: aStr = "MM.TT.JJJJ"; break;
295 case DMY: aStr = "TT.MM.JJJJ"; break;
296 case YMD: aStr = "JJJJ.MM.TT"; break;
297 default: aStr = "MM.TT.JJJJ";
300 else
302 switch( eDate )
304 case MDY: aStr = "MM.TT.JJJJ HH:MM:SS"; break;
305 case DMY: aStr = "TT.MM.JJJJ HH:MM:SS"; break;
306 case YMD: aStr = "JJJJ.MM.TT HH:MM:SS"; break;
307 default: aStr = "MM.TT.JJJJ HH:MM:SS";
311 else
313 aStr = "HH:MM:SS";
315 pFormatter->PutandConvertEntry( aStr,
316 nCheckPos,
317 nType,
318 nIndex,
319 LANGUAGE_GERMAN,
320 eLangType );
321 OUString aTmpString;
322 pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor );
323 *p->pOUString = aTmpString;
324 delete pFormatter;
325 break;
327 case SbxOBJECT:
328 pVal = PTR_CAST(SbxValue,p->pObj);
329 if( pVal )
331 pVal->PutDate( n );
333 else
335 SbxBase::SetError( SbxERR_NO_OBJECT );
337 break;
338 case SbxBYREF | SbxCHAR:
339 if( n > SbxMAXCHAR )
341 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
343 else if( n < SbxMINCHAR )
345 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
347 *p->pChar = (sal_Unicode) n;
348 break;
349 case SbxBYREF | SbxBYTE:
350 if( n > SbxMAXBYTE )
352 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
354 else if( n < 0 )
356 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
358 *p->pByte = (sal_uInt8) n;
359 break;
360 case SbxBYREF | SbxINTEGER:
361 case SbxBYREF | SbxBOOL:
362 if( n > SbxMAXINT )
364 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
366 else if( n < SbxMININT )
368 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
370 *p->pInteger = (sal_Int16) n;
371 break;
372 case SbxBYREF | SbxERROR:
373 case SbxBYREF | SbxUSHORT:
374 if( n > SbxMAXUINT )
376 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
378 else if( n < 0 )
380 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
382 *p->pUShort = (sal_uInt16) n;
383 break;
384 case SbxBYREF | SbxLONG:
385 if( n > SbxMAXLNG )
387 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
389 else if( n < SbxMINLNG )
391 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
393 *p->pLong = (sal_Int32) n;
394 break;
395 case SbxBYREF | SbxULONG:
396 if( n > SbxMAXULNG )
398 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
400 else if( n < 0 )
402 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
404 *p->pULong = (sal_uInt32) n;
405 break;
406 case SbxBYREF | SbxSINGLE:
407 if( n > SbxMAXSNG )
409 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
411 else if( n < SbxMINSNG )
413 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
415 *p->pSingle = (float) n;
416 break;
417 case SbxBYREF | SbxSALINT64:
418 *p->pnInt64 = ImpDoubleToSalInt64( n );
419 break;
420 case SbxBYREF | SbxSALUINT64:
421 *p->puInt64 = ImpDoubleToSalUInt64( n );
422 break;
423 case SbxBYREF | SbxDATE:
424 case SbxBYREF | SbxDOUBLE:
425 *p->pDouble = (double) n;
426 break;
427 case SbxBYREF | SbxCURRENCY:
428 if( n > SbxMAXCURR )
430 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
432 else if( n < SbxMINCURR )
434 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
436 *p->pnInt64 = ImpDoubleToCurrency( n );
437 break;
438 default:
439 SbxBase::SetError( SbxERR_CONVERSION );
440 break;
444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */