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 package org.apache.openoffice.comp.sdbc.dbtools.util; 23 24 import java.math.BigInteger; 25 import java.util.StringTokenizer; 26 27 import com.sun.star.util.Date; 28 import com.sun.star.util.DateTime; 29 import com.sun.star.util.Time; 30 31 public class DBTypeConversion { 32 private static final int MAX_DAYS = 3636532; 33 private static Date standardDate = new Date((short)1, (short)1, (short)1900); 34 private static int aDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 35 private static final double fMilliSecondsPerDay = 86400000.0; 36 safeParseDouble(String value)37 public static double safeParseDouble(String value) { 38 try { 39 return Double.parseDouble(value); 40 } catch (NumberFormatException numberFormatException) { 41 return 0.0; 42 } 43 } 44 safeParseFloat(String value)45 public static float safeParseFloat(String value) { 46 try { 47 return Float.parseFloat(value); 48 } catch (NumberFormatException numberFormatException) { 49 return 0.0f; 50 } 51 } 52 safeParseInt(String value)53 public static int safeParseInt(String value) { 54 try { 55 return Integer.parseInt(value); 56 } catch (NumberFormatException numberFormatException) { 57 return 0; 58 } 59 } 60 safeParseLong(String value)61 public static long safeParseLong(String value) { 62 try { 63 return Long.parseLong(value); 64 } catch (NumberFormatException numberFormatException) { 65 return 0; 66 } 67 } 68 unsignedLongToFloat(long value)69 public static float unsignedLongToFloat(long value) { 70 float f = value & 0x7fffFFFFffffFFFFL; 71 if (value < 0) { 72 f += 0x1p63f; 73 } 74 return f; 75 } 76 unsignedLongToDouble(long value)77 public static double unsignedLongToDouble(long value) { 78 double d = value & 0x7fffFFFFffffFFFFL; 79 if (value < 0) { 80 d += 0x1p63f; 81 } 82 return d; 83 } 84 toUnsignedInt(byte value)85 public static int toUnsignedInt(byte value) { 86 return value & 0xff; 87 } 88 toUnsignedInt(short value)89 public static int toUnsignedInt(short value) { 90 return value & 0xffff; 91 } 92 toUnsignedString(int value)93 public static String toUnsignedString(int value) { 94 return Long.toString(value & 0xffffFFFFL); 95 } 96 toUnsignedString(long value)97 public static String toUnsignedString(long value) { 98 return new BigInteger(Long.toHexString(value), 16).toString(); 99 } 100 addDays(int nDays, Date _rDate)101 public static void addDays(int nDays, Date _rDate) { 102 int nTempDays = implRelativeToAbsoluteNull( _rDate ); 103 104 nTempDays += nDays; 105 if ( nTempDays > MAX_DAYS ) 106 { 107 _rDate.Day = 31; 108 _rDate.Month = 12; 109 _rDate.Year = 9999; 110 } 111 else if ( nTempDays <= 0 ) 112 { 113 _rDate.Day = 1; 114 _rDate.Month = 1; 115 _rDate.Year = 00; 116 } 117 else 118 implBuildFromRelative( nTempDays, _rDate ); 119 } 120 subDays(int nDays, Date _rDate)121 public static void subDays(int nDays, Date _rDate) { 122 int nTempDays = implRelativeToAbsoluteNull( _rDate ); 123 124 nTempDays -= nDays; 125 if ( nTempDays > MAX_DAYS ) 126 { 127 _rDate.Day = 31; 128 _rDate.Month = 12; 129 _rDate.Year = 9999; 130 } 131 else if ( nTempDays <= 0 ) 132 { 133 _rDate.Day = 1; 134 _rDate.Month = 1; 135 _rDate.Year = 00; 136 } 137 else 138 implBuildFromRelative( nTempDays, _rDate ); 139 } 140 getMsFromTime(final Time rVal)141 public static int getMsFromTime(final Time rVal) { 142 int nHour = rVal.Hours; 143 int nMin = rVal.Minutes; 144 int nSec = rVal.Seconds; 145 int n100Sec = rVal.HundredthSeconds; 146 147 return ((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10)); 148 } 149 getStandardDate()150 public static Date getStandardDate() { 151 return standardDate; 152 } 153 implDaysInMonth(int _nMonth, int _nYear)154 private static int implDaysInMonth(int _nMonth, int _nYear) { 155 if (_nMonth != 2) 156 return aDaysInMonth[_nMonth-1]; 157 else { 158 if (implIsLeapYear(_nYear)) 159 return aDaysInMonth[_nMonth-1] + 1; 160 else 161 return aDaysInMonth[_nMonth-1]; 162 } 163 } 164 implBuildFromRelative( int nDays, Date date )165 private static void implBuildFromRelative( int nDays, Date date ) { 166 int nTempDays; 167 int i = 0; 168 boolean bCalc; 169 170 do { 171 nTempDays = nDays; 172 date.Year = (short)((nTempDays / 365) - i); 173 nTempDays -= (date.Year-1) * 365; 174 nTempDays -= ((date.Year-1) / 4) - ((date.Year-1) / 100) + ((date.Year-1) / 400); 175 bCalc = false; 176 if ( nTempDays < 1 ) 177 { 178 i++; 179 bCalc = true; 180 } 181 else 182 { 183 if ( nTempDays > 365 ) 184 { 185 if ( (nTempDays != 366) || !implIsLeapYear( date.Year ) ) 186 { 187 i--; 188 bCalc = true; 189 } 190 } 191 } 192 } 193 while ( bCalc ); 194 195 date.Month = 1; 196 while ( nTempDays > implDaysInMonth( date.Month, date.Year ) ) 197 { 198 nTempDays -= implDaysInMonth( date.Month, date.Year ); 199 date.Month++; 200 } 201 date.Day = (short)nTempDays; 202 } 203 implIsLeapYear(int _nYear)204 private static boolean implIsLeapYear(int _nYear) { 205 return ( ( ((_nYear % 4) == 0) 206 && ((_nYear % 100) != 0) 207 ) 208 ) 209 || ((_nYear % 400) == 0) 210 ; 211 } 212 213 implRelativeToAbsoluteNull(final Date _rDate)214 private static int implRelativeToAbsoluteNull(final Date _rDate) { 215 int nDays = 0; 216 217 // ripped this code from the implementation of tools::Date 218 int nNormalizedYear = _rDate.Year - 1; 219 nDays = nNormalizedYear * 365; 220 // leap years 221 nDays += (nNormalizedYear / 4) - (nNormalizedYear / 100) + (nNormalizedYear / 400); 222 223 for (int i = 1; i < _rDate.Month; ++i) 224 nDays += implDaysInMonth(i, _rDate.Year); 225 226 nDays += _rDate.Day; 227 return nDays; 228 } 229 toDays(Date rVal)230 public static int toDays(Date rVal) { 231 return toDays(rVal, getStandardDate()); 232 } 233 toDays(Date rVal, Date rNullDate)234 public static int toDays(Date rVal, Date rNullDate) { 235 return implRelativeToAbsoluteNull(rVal) - implRelativeToAbsoluteNull(rNullDate); 236 } 237 toDouble(Date rVal)238 public static double toDouble(Date rVal) { 239 return toDouble(rVal, getStandardDate()); 240 } 241 toDouble(Date rVal, Date _rNullDate)242 public static double toDouble(Date rVal, Date _rNullDate) { 243 return (double)toDays(rVal, _rNullDate); 244 } 245 toDouble(DateTime _rVal)246 public static double toDouble(DateTime _rVal) { 247 return toDouble(_rVal, getStandardDate()); 248 } 249 toDouble(DateTime _rVal, Date _rNullDate)250 public static double toDouble(DateTime _rVal, Date _rNullDate) { 251 long nTime = toDays(new Date(_rVal.Day, _rVal.Month, _rVal.Year), _rNullDate); 252 Time aTimePart = new Time(); 253 254 aTimePart.Hours = _rVal.Hours; 255 aTimePart.Minutes = _rVal.Minutes; 256 aTimePart.Seconds = _rVal.Seconds; 257 aTimePart.HundredthSeconds = _rVal.HundredthSeconds; 258 259 return ((double)nTime) + toDouble(aTimePart); 260 } 261 toDouble(Time rVal)262 public static double toDouble(Time rVal) { 263 return (double)getMsFromTime(rVal) / fMilliSecondsPerDay; 264 } 265 toDate(double dVal)266 public static Date toDate(double dVal) { 267 return toDate(dVal, getStandardDate()); 268 } 269 toDate(double dVal, Date _rNullDate)270 public static Date toDate(double dVal, Date _rNullDate) { 271 Date aRet = _rNullDate; 272 273 if (dVal >= 0) 274 addDays((int)dVal,aRet); 275 else 276 subDays((int)(-dVal),aRet); 277 // x -= (sal_uInt32)(-nDays); 278 279 return aRet; 280 } 281 toDate(String value)282 public static Date toDate(String value) { 283 String[] tokens = value.split("-"); 284 285 short nYear = 0, 286 nMonth = 0, 287 nDay = 0; 288 if (tokens.length > 0) { 289 nYear = (short)safeParseInt(tokens[0]); 290 } 291 if (tokens.length > 1) { 292 nMonth = (short)safeParseInt(tokens[1]); 293 } 294 if (tokens.length > 2) { 295 nDay = (short)safeParseInt(tokens[2]); 296 } 297 298 return new Date(nDay,nMonth,nYear); 299 } 300 toDateTime(double dVal)301 public static DateTime toDateTime(double dVal) { 302 return toDateTime(dVal, getStandardDate()); 303 } 304 toDateTime(double dVal, Date _rNullDate)305 public static DateTime toDateTime(double dVal, Date _rNullDate) { 306 Date aDate = toDate(dVal, _rNullDate); 307 Time aTime = toTime(dVal); 308 309 DateTime xRet = new DateTime(); 310 311 xRet.Day = aDate.Day; 312 xRet.Month = aDate.Month; 313 xRet.Year = aDate.Year; 314 315 xRet.HundredthSeconds = aTime.HundredthSeconds; 316 xRet.Minutes = aTime.Minutes; 317 xRet.Seconds = aTime.Seconds; 318 xRet.Hours = aTime.Hours; 319 320 321 return xRet; 322 } 323 toDateTime(String _sSQLString)324 public static DateTime toDateTime(String _sSQLString) { 325 // the date part 326 int nSeparation = _sSQLString.indexOf( ' ' ); 327 String dateString; 328 String timeString = ""; 329 if (nSeparation >= 0) { 330 dateString = _sSQLString.substring(0, nSeparation); 331 timeString = _sSQLString.substring(nSeparation + 1); 332 } else { 333 dateString = _sSQLString; 334 } 335 Date aDate = toDate(dateString); 336 Time aTime = new Time(); 337 338 if ( -1 != nSeparation ) 339 aTime = toTime( timeString ); 340 341 return new DateTime(aTime.HundredthSeconds,aTime.Seconds,aTime.Minutes,aTime.Hours,aDate.Day,aDate.Month,aDate.Year); 342 } 343 toTime(int _nVal)344 public static Time toTime(int _nVal) { 345 Time aReturn = new Time(); 346 aReturn.Hours = (short)(((int)(_nVal >= 0 ? _nVal : _nVal*-1)) / 1000000); 347 aReturn.Minutes = (short)((((int)(_nVal >= 0 ? _nVal : _nVal*-1)) / 10000) % 100); 348 aReturn.Seconds = (short)((((int)(_nVal >= 0 ? _nVal : _nVal*-1)) / 100) % 100); 349 aReturn.HundredthSeconds = (short)(((int)(_nVal >= 0 ? _nVal : _nVal*-1)) % 100); 350 return aReturn; 351 } 352 toTime(double dVal)353 public static Time toTime(double dVal) { 354 int nDays = (int)dVal; 355 int nMS = (int)((dVal - (double)nDays) * fMilliSecondsPerDay + 0.5); 356 357 short nSign; 358 if ( nMS < 0 ) 359 { 360 nMS *= -1; 361 nSign = -1; 362 } 363 else 364 nSign = 1; 365 366 Time xRet = new Time(); 367 // Zeit normalisieren 368 // we have to sal_Int32 here because otherwise we get an overflow 369 int nHundredthSeconds = nMS/10; 370 int nSeconds = nHundredthSeconds / 100; 371 int nMinutes = nSeconds / 60; 372 373 xRet.HundredthSeconds = (short)(nHundredthSeconds % 100); 374 xRet.Seconds = (short)(nSeconds % 60); 375 xRet.Hours = (short)(nMinutes / 60); 376 xRet.Minutes = (short)(nMinutes % 60); 377 378 // Zeit zusammenbauen 379 int nTime = (int)(xRet.HundredthSeconds + (xRet.Seconds*100) + (xRet.Minutes*10000) + (xRet.Hours*1000000)) * nSign; 380 381 if(nTime < 0) 382 { 383 xRet.HundredthSeconds = 99; 384 xRet.Minutes = 59; 385 xRet.Seconds = 59; 386 xRet.Hours = 23; 387 } 388 return xRet; 389 } 390 toTime(String _sSQLString)391 public static Time toTime(String _sSQLString) { 392 short nHour = 0, 393 nMinute = 0, 394 nSecond = 0, 395 nHundredthSeconds = 0; 396 StringTokenizer tokenizer = new StringTokenizer(_sSQLString, ":"); 397 if (tokenizer.hasMoreTokens()) { 398 nHour = (short)safeParseInt(tokenizer.nextToken()); 399 } 400 if (tokenizer.hasMoreTokens()) { 401 nMinute = (short)safeParseInt(tokenizer.nextToken()); 402 } 403 if (tokenizer.hasMoreTokens()) { 404 String secondAndNano = tokenizer.nextToken(); 405 int dot = secondAndNano.indexOf("."); 406 if (dot >= 0) { 407 nSecond = (short)safeParseInt(secondAndNano.substring(0, dot)); 408 String nano = secondAndNano.substring(dot + 1); 409 if (nano.length() > 2) { 410 nano = nano.substring(0, 2); 411 } 412 nano = nano + "00".substring(0, 2 - nano.length()); 413 nHundredthSeconds = (short)safeParseInt(nano); 414 } else { 415 nSecond = (short)safeParseInt(secondAndNano); 416 } 417 } 418 return new Time(nHundredthSeconds,nSecond,nMinute,nHour); 419 } 420 421 /// Return the date in the format %04d-%02d-%02d. toDateString(Date date)422 public static String toDateString(Date date) { 423 return String.format("%04d-%02d-%02d", 424 toUnsignedInt(date.Year), 425 toUnsignedInt(date.Month), 426 toUnsignedInt(date.Day)); 427 } 428 429 /// Return the time in the format %02d:%02d:%02d. toTimeString(Time time)430 public static String toTimeString(Time time) { 431 return String.format("%02d:%02d:%02d", 432 toUnsignedInt(time.Hours), 433 toUnsignedInt(time.Minutes), 434 toUnsignedInt(time.Seconds)); 435 } 436 437 /// Return the DateTime in the format %04d-%02d-%02d %02d:%02d:%02d.%d. toDateTimeString(DateTime dateTime)438 public static String toDateTimeString(DateTime dateTime) { 439 return String.format("%04d-%02d-%02d %02d:%02d:%02d.%d", 440 toUnsignedInt(dateTime.Year), 441 toUnsignedInt(dateTime.Month), 442 toUnsignedInt(dateTime.Day), 443 toUnsignedInt(dateTime.Hours), 444 toUnsignedInt(dateTime.Minutes), 445 toUnsignedInt(dateTime.Seconds), 446 toUnsignedInt(dateTime.HundredthSeconds)); 447 } 448 } 449