summaryrefslogtreecommitdiff
path: root/connectivity/source/commontools/dbconversion.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/commontools/dbconversion.cxx')
-rw-r--r--connectivity/source/commontools/dbconversion.cxx490
1 files changed, 490 insertions, 0 deletions
diff --git a/connectivity/source/commontools/dbconversion.cxx b/connectivity/source/commontools/dbconversion.cxx
new file mode 100644
index 000000000000..6149b4748c30
--- /dev/null
+++ b/connectivity/source/commontools/dbconversion.cxx
@@ -0,0 +1,490 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_connectivity.hxx"
+#include <connectivity/dbconversion.hxx>
+#include <connectivity/dbcharset.hxx>
+#include <osl/diagnose.h>
+#ifndef _INC_STDIO
+#include <stdio.h>
+#endif
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#define MAX_DAYS 3636532
+
+//.........................................................................
+namespace dbtools
+{
+//.........................................................................
+
+
+ using namespace ::comphelper;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+
+
+ //------------------------------------------------------------------------------
+ ::com::sun::star::util::Date DBTypeConversion::getStandardDate()
+ {
+ static ::com::sun::star::util::Date STANDARD_DB_DATE(1,1,1900);
+ return STANDARD_DB_DATE;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString DBTypeConversion::toDateString(const Date& rDate)
+ {
+ sal_Char s[11];
+ snprintf(s,
+ sizeof(s),
+ "%04d-%02d-%02d",
+ (int)rDate.Year,
+ (int)rDate.Month,
+ (int)rDate.Day);
+ s[10] = 0;
+ return ::rtl::OUString::createFromAscii(s);
+ }
+ //------------------------------------------------------------------
+ ::rtl::OUString DBTypeConversion::toTimeString(const Time& rTime)
+ {
+ sal_Char s[9];
+ snprintf(s,
+ sizeof(s),
+ "%02d:%02d:%02d",
+ (int)rTime.Hours,
+ (int)rTime.Minutes,
+ (int)rTime.Seconds);
+ s[8] = 0;
+ return ::rtl::OUString::createFromAscii(s);
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString DBTypeConversion::toDateTimeString(const DateTime& _rDateTime)
+ {
+ Date aDate(_rDateTime.Day,_rDateTime.Month,_rDateTime.Year);
+ ::rtl::OUStringBuffer aTemp(toDateString(aDate));
+ aTemp.appendAscii(" ");
+ Time aTime(0,_rDateTime.Seconds,_rDateTime.Minutes,_rDateTime.Hours);
+ aTemp.append( toTimeString(aTime) );
+ aTemp.appendAscii(".");
+ aTemp.append( static_cast<sal_Int32>(_rDateTime.HundredthSeconds));
+ return aTemp.makeStringAndClear();
+ }
+ //------------------------------------------------------------------------------
+ Date DBTypeConversion::toDate(sal_Int32 _nVal)
+ {
+ Date aReturn;
+ aReturn.Day = (sal_uInt16)(_nVal % 100);
+ aReturn.Month = (sal_uInt16)((_nVal / 100) % 100);
+ aReturn.Year = (sal_uInt16)(_nVal / 10000);
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------------
+ Time DBTypeConversion::toTime(sal_Int32 _nVal)
+ {
+ Time aReturn;
+ aReturn.Hours = (sal_uInt16)(((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) / 1000000);
+ aReturn.Minutes = (sal_uInt16)((((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) / 10000) % 100);
+ aReturn.Seconds = (sal_uInt16)((((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) / 100) % 100);
+ aReturn.HundredthSeconds = (sal_uInt16)(((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) % 100);
+ return aReturn;
+ }
+
+ const double fMilliSecondsPerDay = 86400000.0;
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::toINT32(const Date& rVal)
+ {
+ return ((sal_Int32)(rVal.Day%100)) +
+ (((sal_Int32)(rVal.Month%100))*100) +
+ (((sal_Int32) rVal.Year%10000)*10000);
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::toINT32(const Time& rVal)
+ {
+ // Zeit normalisieren
+ sal_Int32 nSeconds = rVal.Seconds + rVal.HundredthSeconds / 100;
+ sal_Int32 nHundredthSeconds = rVal.HundredthSeconds % 100;
+ sal_Int32 nMinutes = rVal.Minutes + nSeconds / 60;
+ nSeconds = nSeconds % 60;
+ sal_Int32 nHours = rVal.Hours + nMinutes / 60;
+ nMinutes = nMinutes % 60;
+
+ // Zeit zusammenbauen
+ return (sal_Int32)(nHundredthSeconds + (nSeconds*100) + (nMinutes*10000) + (nHours*1000000));
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Int64 DBTypeConversion::toINT64(const DateTime& rVal)
+ {
+ // Zeit normalisieren
+ sal_Int32 nSeconds = rVal.Seconds + rVal.HundredthSeconds / 100;
+ sal_Int32 nHundredthSeconds = rVal.HundredthSeconds % 100;
+ sal_Int32 nMinutes = rVal.Minutes + nSeconds / 60;
+ nSeconds = nSeconds % 60;
+ sal_Int32 nHours = rVal.Hours + nMinutes / 60;
+ nMinutes = nMinutes % 60;
+
+ // Zeit zusammenbauen
+ sal_Int32 nTime = (sal_Int32)(nHundredthSeconds + (nSeconds*100) + (nMinutes*10000) + (nHours*1000000));
+ sal_Int32 nDate = ((sal_Int32)(rVal.Day%100)) + (((sal_Int32)(rVal.Month%100))*100) + (((sal_Int32) rVal.Year%10000)*10000);
+ sal_Int64 nRet;
+
+ nRet = (sal_Int64) nTime;
+ nRet <<= 32;
+ nRet += nDate;
+
+ return nRet;
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::getMsFromTime(const Time& rVal)
+ {
+ sal_Int32 nHour = rVal.Hours;
+ sal_Int32 nMin = rVal.Minutes;
+ sal_Int32 nSec = rVal.Seconds;
+ sal_Int32 n100Sec = rVal.HundredthSeconds;
+
+ return ((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10));
+ }
+
+ //------------------------------------------------------------------------------
+ static sal_Int32 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31 };
+
+ //------------------------------------------------------------------------------
+ static sal_Bool implIsLeapYear(sal_Int32 _nYear)
+ {
+ return ( ( ((_nYear % 4) == 0)
+ && ((_nYear % 100) != 0)
+ )
+ )
+ || ((_nYear % 400) == 0)
+ ;
+ }
+
+ //------------------------------------------------------------------------------
+ static sal_Int32 implDaysInMonth(sal_Int32 _nMonth, sal_Int32 _nYear)
+ {
+ OSL_ENSURE(_nMonth > 0 && _nMonth < 13,"Month as invalid value!");
+ if (_nMonth != 2)
+ return aDaysInMonth[_nMonth-1];
+ else
+ {
+ if (implIsLeapYear(_nYear))
+ return aDaysInMonth[_nMonth-1] + 1;
+ else
+ return aDaysInMonth[_nMonth-1];
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ static sal_Int32 implRelativeToAbsoluteNull(const Date& _rDate)
+ {
+ sal_Int32 nDays = 0;
+
+ // ripped this code from the implementation of tools::Date
+ sal_Int32 nNormalizedYear = _rDate.Year - 1;
+ nDays = nNormalizedYear * 365;
+ // leap years
+ nDays += (nNormalizedYear / 4) - (nNormalizedYear / 100) + (nNormalizedYear / 400);
+
+ for (sal_Int32 i = 1; i < _rDate.Month; ++i)
+ nDays += implDaysInMonth(i, _rDate.Year);
+
+ nDays += _rDate.Day;
+ return nDays;
+ }
+ //------------------------------------------------------------------------------
+ static void implBuildFromRelative( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear)
+ {
+ sal_Int32 nTempDays;
+ sal_Int32 i = 0;
+ sal_Bool bCalc;
+
+ do
+ {
+ nTempDays = nDays;
+ rYear = (sal_uInt16)((nTempDays / 365) - i);
+ nTempDays -= (rYear-1) * 365;
+ nTempDays -= ((rYear-1) / 4) - ((rYear-1) / 100) + ((rYear-1) / 400);
+ bCalc = sal_False;
+ if ( nTempDays < 1 )
+ {
+ i++;
+ bCalc = sal_True;
+ }
+ else
+ {
+ if ( nTempDays > 365 )
+ {
+ if ( (nTempDays != 366) || !implIsLeapYear( rYear ) )
+ {
+ i--;
+ bCalc = sal_True;
+ }
+ }
+ }
+ }
+ while ( bCalc );
+
+ rMonth = 1;
+ while ( nTempDays > implDaysInMonth( rMonth, rYear ) )
+ {
+ nTempDays -= implDaysInMonth( rMonth, rYear );
+ rMonth++;
+ }
+ rDay = (sal_uInt16)nTempDays;
+ }
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::toDays(const Date& _rVal, const Date& _rNullDate)
+ {
+ return implRelativeToAbsoluteNull(_rVal) - implRelativeToAbsoluteNull(_rNullDate);
+ }
+
+ //------------------------------------------------------------------------------
+ double DBTypeConversion::toDouble(const Date& rVal, const Date& _rNullDate)
+ {
+ return (double)toDays(rVal, _rNullDate);
+ }
+
+ //------------------------------------------------------------------------------
+ double DBTypeConversion::toDouble(const Time& rVal)
+ {
+ return (double)getMsFromTime(rVal) / fMilliSecondsPerDay;
+ }
+
+ //------------------------------------------------------------------------------
+ double DBTypeConversion::toDouble(const DateTime& _rVal, const Date& _rNullDate)
+ {
+ sal_Int64 nTime = toDays(Date(_rVal.Day, _rVal.Month, _rVal.Year), _rNullDate);
+ Time aTimePart;
+
+ aTimePart.Hours = _rVal.Hours;
+ aTimePart.Minutes = _rVal.Minutes;
+ aTimePart.Seconds = _rVal.Seconds;
+ aTimePart.HundredthSeconds = _rVal.HundredthSeconds;
+
+ return ((double)nTime) + toDouble(aTimePart);
+ }
+ // -------------------------------------------------------------------------
+ static void addDays(sal_Int32 nDays, Date& _rDate)
+ {
+ sal_Int32 nTempDays = implRelativeToAbsoluteNull( _rDate );
+
+ nTempDays += nDays;
+ if ( nTempDays > MAX_DAYS )
+ {
+ _rDate.Day = 31;
+ _rDate.Month = 12;
+ _rDate.Year = 9999;
+ }
+ else if ( nTempDays <= 0 )
+ {
+ _rDate.Day = 1;
+ _rDate.Month = 1;
+ _rDate.Year = 00;
+ }
+ else
+ implBuildFromRelative( nTempDays, _rDate.Day, _rDate.Month, _rDate.Year );
+ }
+ // -----------------------------------------------------------------------
+ static void subDays( sal_Int32 nDays, Date& _rDate )
+ {
+ sal_Int32 nTempDays = implRelativeToAbsoluteNull( _rDate );
+
+ nTempDays -= nDays;
+ if ( nTempDays > MAX_DAYS )
+ {
+ _rDate.Day = 31;
+ _rDate.Month = 12;
+ _rDate.Year = 9999;
+ }
+ else if ( nTempDays <= 0 )
+ {
+ _rDate.Day = 1;
+ _rDate.Month = 1;
+ _rDate.Year = 00;
+ }
+ else
+ implBuildFromRelative( nTempDays, _rDate.Day, _rDate.Month, _rDate.Year );
+ }
+ // -------------------------------------------------------------------------
+ Date DBTypeConversion::toDate(double dVal, const Date& _rNullDate)
+ {
+ Date aRet = _rNullDate;
+
+ if (dVal >= 0)
+ addDays((sal_Int32)dVal,aRet);
+ else
+ subDays((sal_uInt32)(-dVal),aRet);
+ // x -= (sal_uInt32)(-nDays);
+
+ return aRet;
+ }
+ // -------------------------------------------------------------------------
+ Time DBTypeConversion::toTime(double dVal)
+ {
+ sal_Int32 nDays = (sal_Int32)dVal;
+ sal_Int32 nMS = sal_Int32((dVal - (double)nDays) * fMilliSecondsPerDay + 0.5);
+
+ sal_Int16 nSign;
+ if ( nMS < 0 )
+ {
+ nMS *= -1;
+ nSign = -1;
+ }
+ else
+ nSign = 1;
+
+ Time xRet;
+ // Zeit normalisieren
+ // we have to sal_Int32 here because otherwise we get an overflow
+ sal_Int32 nHundredthSeconds = nMS/10;
+ sal_Int32 nSeconds = nHundredthSeconds / 100;
+ sal_Int32 nMinutes = nSeconds / 60;
+
+ xRet.HundredthSeconds = (sal_uInt16)(nHundredthSeconds % 100);
+ xRet.Seconds = (sal_uInt16)(nSeconds % 60);
+ xRet.Hours = (sal_uInt16)(nMinutes / 60);
+ xRet.Minutes = (sal_uInt16)(nMinutes % 60);
+
+ // Zeit zusammenbauen
+ sal_Int32 nTime = (sal_Int32)(xRet.HundredthSeconds + (xRet.Seconds*100) + (xRet.Minutes*10000) + (xRet.Hours*1000000)) * nSign;
+
+ if(nTime < 0)
+ {
+ xRet.HundredthSeconds = 99;
+ xRet.Minutes = 59;
+ xRet.Seconds = 59;
+ xRet.Hours = 23;
+ }
+ return xRet;
+ }
+ //------------------------------------------------------------------------------
+ DateTime DBTypeConversion::toDateTime(double dVal, const Date& _rNullDate)
+ {
+ Date aDate = toDate(dVal, _rNullDate);
+ Time aTime = toTime(dVal);
+
+ DateTime xRet;
+
+ xRet.Day = aDate.Day;
+ xRet.Month = aDate.Month;
+ xRet.Year = aDate.Year;
+
+ xRet.HundredthSeconds = aTime.HundredthSeconds;
+ xRet.Minutes = aTime.Minutes;
+ xRet.Seconds = aTime.Seconds;
+ xRet.Hours = aTime.Hours;
+
+
+ return xRet;
+ }
+ //------------------------------------------------------------------------------
+ Date DBTypeConversion::toDate(const ::rtl::OUString& _sSQLString)
+ {
+ // get the token out of a string
+ static sal_Unicode sDateSep = '-';
+
+ sal_Int32 nIndex = 0;
+ sal_uInt16 nYear = 0,
+ nMonth = 0,
+ nDay = 0;
+ nYear = (sal_uInt16)_sSQLString.getToken(0,sDateSep,nIndex).toInt32();
+ if(nIndex != -1)
+ {
+ nMonth = (sal_uInt16)_sSQLString.getToken(0,sDateSep,nIndex).toInt32();
+ if(nIndex != -1)
+ nDay = (sal_uInt16)_sSQLString.getToken(0,sDateSep,nIndex).toInt32();
+ }
+
+ return Date(nDay,nMonth,nYear);
+ }
+
+ //-----------------------------------------------------------------------------
+ DateTime DBTypeConversion::toDateTime(const ::rtl::OUString& _sSQLString)
+ {
+ //@see http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Timestamp.html#valueOf(java.lang.String)
+ //@see http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Date.html#valueOf(java.lang.String)
+ //@see http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Time.html#valueOf(java.lang.String)
+
+ // the date part
+ Date aDate = toDate(_sSQLString);
+ Time aTime;
+ sal_Int32 nSeparation = _sSQLString.indexOf( ' ' );
+ if ( -1 != nSeparation )
+ aTime = toTime( _sSQLString.copy( nSeparation ) );
+
+ return DateTime(aTime.HundredthSeconds,aTime.Seconds,aTime.Minutes,aTime.Hours,aDate.Day,aDate.Month,aDate.Year);
+ }
+
+ //-----------------------------------------------------------------------------
+ Time DBTypeConversion::toTime(const ::rtl::OUString& _sSQLString)
+ {
+ static sal_Unicode sTimeSep = ':';
+
+ sal_Int32 nIndex = 0;
+ sal_uInt16 nHour = 0,
+ nMinute = 0,
+ nSecond = 0,
+ nHundredthSeconds = 0;
+ nHour = (sal_uInt16)_sSQLString.getToken(0,sTimeSep,nIndex).toInt32();
+ if(nIndex != -1)
+ {
+ nMinute = (sal_uInt16)_sSQLString.getToken(0,sTimeSep,nIndex).toInt32();
+ if(nIndex != -1)
+ {
+ nSecond = (sal_uInt16)_sSQLString.getToken(0,sTimeSep,nIndex).toInt32();
+ nIndex = 0;
+ ::rtl::OUString sNano(_sSQLString.getToken(1,'.',nIndex));
+ if ( sNano.getLength() )
+ {
+ // our time struct only supports hundredth seconds
+ sNano = sNano.copy(0,::std::min<sal_Int32>(sNano.getLength(),2));
+ const static ::rtl::OUString s_Zeros(RTL_CONSTASCII_USTRINGPARAM("00"));
+ sNano += s_Zeros.copy(0,s_Zeros.getLength() - sNano.getLength());
+ nHundredthSeconds = static_cast<sal_uInt16>(sNano.toInt32());
+ }
+ }
+ }
+ return Time(nHundredthSeconds,nSecond,nMinute,nHour);
+ }
+
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
+