bump product version to 4.1.6.2
[LibreOffice.git] / basic / source / sbx / sbxdate.cxx
blob6db87a7e1961254f1933db961f5be7de603fd26c
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 <i18nlangtag/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 = new SvNumberFormatter( comphelper::getProcessComponentContext(), eLangType );
103 sal_uInt32 nIndex;
104 sal_Int32 nCheckPos = 0;
105 short nType = 127;
107 // Default templates of the formatter have only two-digit
108 // date. Therefore register an own format.
110 // HACK, because the number formatter in PutandConvertEntry replace the wildcard
111 // for month, day, year not according to the configuration.
112 // Problem: Print Year(Date) under Engl. OS
113 // quod vide basic/source/runtime/runtime.cxx
115 SvtSysLocale aSysLocale;
116 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
117 OUString aDateStr;
118 switch( eDate )
120 default:
121 case MDY: aDateStr = "MM/DD/YYYY"; break;
122 case DMY: aDateStr = "DD/MM/YYYY"; break;
123 case YMD: aDateStr = "YYYY/MM/DD"; break;
126 OUString aStr( aDateStr );
127 aStr += " HH:MM:SS";
129 pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
130 nIndex, LANGUAGE_ENGLISH_US, eLangType );
131 sal_Bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes );
132 if ( bSuccess )
134 short nType_ = pFormatter->GetType( nIndex );
135 if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
136 NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
138 bSuccess = sal_False;
142 if ( !bSuccess )
144 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
147 delete pFormatter;
149 break;
150 case SbxOBJECT:
151 pVal = PTR_CAST(SbxValue,p->pObj);
152 if( pVal )
154 nRes = pVal->GetDate();
156 else
158 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
160 break;
161 case SbxBYREF | SbxCHAR:
162 nRes = *p->pChar;
163 break;
164 case SbxBYREF | SbxBYTE:
165 nRes = *p->pByte;
166 break;
167 case SbxBYREF | SbxINTEGER:
168 case SbxBYREF | SbxBOOL:
169 nRes = *p->pInteger;
170 break;
171 case SbxBYREF | SbxLONG:
172 nRes = *p->pLong;
173 break;
174 case SbxBYREF | SbxULONG:
175 nRes = *p->pULong;
176 break;
177 case SbxBYREF | SbxERROR:
178 case SbxBYREF | SbxUSHORT:
179 nRes = *p->pUShort;
180 break;
181 case SbxBYREF | SbxSINGLE:
182 nRes = *p->pSingle;
183 break;
184 case SbxBYREF | SbxDATE:
185 case SbxBYREF | SbxDOUBLE:
186 nRes = *p->pDouble;
187 break;
188 case SbxBYREF | SbxCURRENCY:
189 nRes = ImpCurrencyToDouble( *p->pnInt64 );
190 break;
191 case SbxBYREF | SbxSALINT64:
192 nRes = static_cast< double >(*p->pnInt64);
193 break;
194 case SbxBYREF | SbxSALUINT64:
195 nRes = ImpSalUInt64ToDouble( *p->puInt64 );
196 break;
197 default:
198 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
199 break;
201 return nRes;
204 void ImpPutDate( SbxValues* p, double n )
206 SbxValues aTmp;
207 SbxDecimal* pDec;
208 SbxValue* pVal;
210 start:
211 switch( +p->eType )
213 case SbxDATE:
214 case SbxDOUBLE:
215 p->nDouble = n;
216 break;
217 // from here will be tested
218 case SbxCHAR:
219 aTmp.pChar = &p->nChar;
220 goto direct;
221 case SbxBYTE:
222 aTmp.pByte = &p->nByte;
223 goto direct;
224 case SbxINTEGER:
225 case SbxBOOL:
226 aTmp.pInteger = &p->nInteger;
227 goto direct;
228 case SbxLONG:
229 aTmp.pLong = &p->nLong;
230 goto direct;
231 case SbxULONG:
232 aTmp.pULong = &p->nULong;
233 goto direct;
234 case SbxERROR:
235 case SbxUSHORT:
236 aTmp.pUShort = &p->nUShort;
237 goto direct;
238 case SbxSINGLE:
239 aTmp.pSingle = &p->nSingle;
240 goto direct;
241 case SbxCURRENCY:
242 case SbxSALINT64:
243 aTmp.pnInt64 = &p->nInt64;
244 goto direct;
245 case SbxSALUINT64:
246 aTmp.puInt64 = &p->uInt64;
247 goto direct;
248 case SbxDECIMAL:
249 case SbxBYREF | SbxDECIMAL:
250 pDec = ImpCreateDecimal( p );
251 if( !pDec->setDouble( n ) )
253 SbxBase::SetError( SbxERR_OVERFLOW );
255 break;
256 direct:
257 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
258 p = &aTmp; goto start;
260 case SbxBYREF | SbxSTRING:
261 case SbxSTRING:
262 case SbxLPSTR:
264 if( !p->pOUString )
266 p->pOUString = new OUString;
268 Color* pColor;
270 LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
271 SvNumberFormatter* pFormatter = new SvNumberFormatter( comphelper::getProcessComponentContext(), eLangType );
273 sal_uInt32 nIndex;
274 sal_Int32 nCheckPos = 0;
275 short nType;
277 SvtSysLocale aSysLocale;
278 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
279 OUString aStr;
280 // if the whole-number part is 0, we want no year!
281 if( n <= -1.0 || n >= 1.0 )
283 // Time only if != 00:00:00
284 if( floor( n ) == n )
286 switch( eDate )
288 case MDY: aStr = "MM.TT.JJJJ"; break;
289 case DMY: aStr = "TT.MM.JJJJ"; break;
290 case YMD: aStr = "JJJJ.MM.TT"; break;
291 default: aStr = "MM.TT.JJJJ";
294 else
296 switch( eDate )
298 case MDY: aStr = "MM.TT.JJJJ HH:MM:SS"; break;
299 case DMY: aStr = "TT.MM.JJJJ HH:MM:SS"; break;
300 case YMD: aStr = "JJJJ.MM.TT HH:MM:SS"; break;
301 default: aStr = "MM.TT.JJJJ HH:MM:SS";
305 else
307 aStr = "HH:MM:SS";
309 pFormatter->PutandConvertEntry( aStr,
310 nCheckPos,
311 nType,
312 nIndex,
313 LANGUAGE_GERMAN,
314 eLangType );
315 OUString aTmpString;
316 pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor );
317 *p->pOUString = aTmpString;
318 delete pFormatter;
319 break;
321 case SbxOBJECT:
322 pVal = PTR_CAST(SbxValue,p->pObj);
323 if( pVal )
325 pVal->PutDate( n );
327 else
329 SbxBase::SetError( SbxERR_NO_OBJECT );
331 break;
332 case SbxBYREF | SbxCHAR:
333 if( n > SbxMAXCHAR )
335 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
337 else if( n < SbxMINCHAR )
339 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
341 *p->pChar = (sal_Unicode) n;
342 break;
343 case SbxBYREF | SbxBYTE:
344 if( n > SbxMAXBYTE )
346 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
348 else if( n < 0 )
350 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
352 *p->pByte = (sal_uInt8) n;
353 break;
354 case SbxBYREF | SbxINTEGER:
355 case SbxBYREF | SbxBOOL:
356 if( n > SbxMAXINT )
358 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
360 else if( n < SbxMININT )
362 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
364 *p->pInteger = (sal_Int16) n;
365 break;
366 case SbxBYREF | SbxERROR:
367 case SbxBYREF | SbxUSHORT:
368 if( n > SbxMAXUINT )
370 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
372 else if( n < 0 )
374 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
376 *p->pUShort = (sal_uInt16) n;
377 break;
378 case SbxBYREF | SbxLONG:
379 if( n > SbxMAXLNG )
381 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
383 else if( n < SbxMINLNG )
385 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
387 *p->pLong = (sal_Int32) n;
388 break;
389 case SbxBYREF | SbxULONG:
390 if( n > SbxMAXULNG )
392 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
394 else if( n < 0 )
396 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
398 *p->pULong = (sal_uInt32) n;
399 break;
400 case SbxBYREF | SbxSINGLE:
401 if( n > SbxMAXSNG )
403 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
405 else if( n < SbxMINSNG )
407 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
409 *p->pSingle = (float) n;
410 break;
411 case SbxBYREF | SbxSALINT64:
412 *p->pnInt64 = ImpDoubleToSalInt64( n );
413 break;
414 case SbxBYREF | SbxSALUINT64:
415 *p->puInt64 = ImpDoubleToSalUInt64( n );
416 break;
417 case SbxBYREF | SbxDATE:
418 case SbxBYREF | SbxDOUBLE:
419 *p->pDouble = (double) n;
420 break;
421 case SbxBYREF | SbxCURRENCY:
422 if( n > SbxMAXCURR )
424 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
426 else if( n < SbxMINCURR )
428 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
430 *p->pnInt64 = ImpDoubleToCurrency( n );
431 break;
432 default:
433 SbxBase::SetError( SbxERR_CONVERSION );
434 break;
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */