Source Code Cross Referenced for SQLTimestamp.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » iapi » types » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.iapi.types 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.iapi.types.SQLTimestamp
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.iapi.types;
0023:
0024:        import org.apache.derby.iapi.reference.SQLState;
0025:
0026:        import org.apache.derby.iapi.services.io.ArrayInputStream;
0027:
0028:        import org.apache.derby.iapi.error.StandardException;
0029:        import org.apache.derby.iapi.db.DatabaseContext;
0030:
0031:        import org.apache.derby.iapi.types.DataValueDescriptor;
0032:        import org.apache.derby.iapi.types.TypeId;
0033:
0034:        import org.apache.derby.iapi.types.NumberDataValue;
0035:        import org.apache.derby.iapi.types.DateTimeDataValue;
0036:
0037:        import org.apache.derby.iapi.services.io.StoredFormatIds;
0038:        import org.apache.derby.iapi.services.context.ContextService;
0039:
0040:        import org.apache.derby.iapi.services.sanity.SanityManager;
0041:        import org.apache.derby.iapi.types.DataType;
0042:        import org.apache.derby.iapi.services.i18n.LocaleFinder;
0043:        import org.apache.derby.iapi.services.cache.ClassSize;
0044:        import org.apache.derby.iapi.util.StringUtil;
0045:        import org.apache.derby.iapi.util.ReuseFactory;
0046:
0047:        import org.apache.derby.iapi.types.SQLDouble;
0048:        import org.apache.derby.iapi.types.SQLTime;
0049:
0050:        import java.sql.Date;
0051:        import java.sql.Time;
0052:        import java.sql.Timestamp;
0053:        import java.sql.Types;
0054:        import java.sql.ResultSet;
0055:        import java.sql.SQLException;
0056:        import java.sql.PreparedStatement;
0057:
0058:        import java.util.Calendar;
0059:        import java.util.GregorianCalendar;
0060:
0061:        import java.io.ObjectOutput;
0062:        import java.io.ObjectInput;
0063:        import java.io.IOException;
0064:
0065:        import java.text.DateFormat;
0066:        import java.text.ParseException;
0067:
0068:        /**
0069:         * This contains an instance of a SQL Timestamp object.
0070:         * <p>
0071:         * SQLTimestamp is stored in 3 ints - an encoded date, an encoded time and
0072:         *		nanoseconds
0073:         * encodedDate = 0 indicates a null WSCTimestamp
0074:         *
0075:         * SQLTimestamp is similar to SQLTimestamp, but it does conserves space by not keeping a GregorianCalendar object
0076:         *
0077:         * PERFORMANCE OPTIMIZATION:
0078:         *	We only instantiate the value field when required due to the overhead of the
0079:         *	Date methods.
0080:         *	Thus, use isNull() instead of "value == null" and
0081:         *	getTimestamp() instead of using value directly.
0082:         */
0083:
0084:        public final class SQLTimestamp extends DataType implements 
0085:                DateTimeDataValue {
0086:
0087:            static final int MAX_FRACTION_DIGITS = 6; // Only microsecond resolution on conversion to/from strings
0088:            static final int FRACTION_TO_NANO = 1000; // 10**(9 - MAX_FRACTION_DIGITS)
0089:
0090:            static final int ONE_BILLION = 1000000000;
0091:
0092:            private int encodedDate;
0093:            private int encodedTime;
0094:            private int nanos;
0095:
0096:            // The cached value.toString()
0097:            private String valueString;
0098:
0099:            /*
0100:             ** DataValueDescriptor interface
0101:             ** (mostly implemented in DataType)
0102:             */
0103:
0104:            private static final int BASE_MEMORY_USAGE = ClassSize
0105:                    .estimateBaseFromCatalog(SQLTimestamp.class);
0106:
0107:            public int estimateMemoryUsage() {
0108:                int sz = BASE_MEMORY_USAGE
0109:                        + ClassSize.estimateMemoryUsage(valueString);
0110:                return sz;
0111:            } // end of estimateMemoryUsage
0112:
0113:            public String getString() {
0114:                if (!isNull()) {
0115:                    if (valueString == null) {
0116:                        valueString = getTimestamp((Calendar) null).toString();
0117:                        /* The java.sql.Timestamp.toString() method is supposed to return a string in
0118:                         * the JDBC escape format. However the JDK 1.3 libraries truncate leading zeros from
0119:                         * the year. This is not acceptable to DB2. So add leading zeros if necessary.
0120:                         */
0121:                        int separatorIdx = valueString.indexOf('-');
0122:                        if (separatorIdx >= 0 && separatorIdx < 4) {
0123:                            StringBuffer sb = new StringBuffer();
0124:                            for (; separatorIdx < 4; separatorIdx++)
0125:                                sb.append('0');
0126:                            sb.append(valueString);
0127:                            valueString = sb.toString();
0128:                        }
0129:                    }
0130:
0131:                    return valueString;
0132:                } else {
0133:                    if (SanityManager.DEBUG) {
0134:                        if (valueString != null) {
0135:                            SanityManager
0136:                                    .THROWASSERT("valueString expected to be null, not "
0137:                                            + valueString);
0138:                        }
0139:                    }
0140:                    return null;
0141:                }
0142:            }
0143:
0144:            /**
0145:            	getDate returns the date portion of the timestamp
0146:            	Time is set to 00:00:00.0
0147:            	Since Date is a JDBC object we use the JDBC definition
0148:            	for the time portion.  See JDBC API Tutorial, 47.3.12.
0149:
0150:            	@exception StandardException thrown on failure
0151:             */
0152:            public Date getDate(Calendar cal) throws StandardException {
0153:                if (isNull())
0154:                    return null;
0155:                return newDate(cal);
0156:            }
0157:
0158:            private Date newDate(java.util.Calendar cal)
0159:                    throws StandardException {
0160:                if (cal == null)
0161:                    cal = new GregorianCalendar();
0162:                cal.clear();
0163:                cal.set(Calendar.YEAR, SQLDate.getYear(encodedDate));
0164:                cal.set(Calendar.MONTH, SQLDate.getMonth(encodedDate) - 1);
0165:                cal.set(Calendar.DATE, SQLDate.getDay(encodedDate));
0166:                cal.set(Calendar.HOUR_OF_DAY, 0);
0167:                cal.set(Calendar.MINUTE, 0);
0168:                cal.set(Calendar.SECOND, 0);
0169:                cal.set(Calendar.MILLISECOND, 0);
0170:                return new Date(cal.getTime().getTime());
0171:            }
0172:
0173:            /**
0174:            	getTime returns the time portion of the timestamp
0175:            	Date is set to 1970-01-01
0176:            	Since Time is a JDBC object we use the JDBC definition
0177:            	for the date portion.  See JDBC API Tutorial, 47.3.12.
0178:            	@exception StandardException thrown on failure
0179:             */
0180:            public Time getTime(Calendar cal) throws StandardException {
0181:                if (isNull())
0182:                    return null;
0183:                return newTime(cal);
0184:            }
0185:
0186:            private Time newTime(java.util.Calendar cal)
0187:                    throws StandardException {
0188:                if (cal == null)
0189:                    cal = new GregorianCalendar();
0190:                cal.clear();
0191:                cal.set(Calendar.YEAR, 1970);
0192:                cal.set(Calendar.MONTH, Calendar.JANUARY);
0193:                cal.set(Calendar.DATE, 1);
0194:                cal.set(Calendar.HOUR_OF_DAY, SQLTime.getHour(encodedTime));
0195:                cal.set(Calendar.MINUTE, SQLTime.getMinute(encodedTime));
0196:                cal.set(Calendar.SECOND, SQLTime.getSecond(encodedTime));
0197:                cal.set(Calendar.MILLISECOND, (int) (nanos / 1000000));
0198:                return new Time(cal.getTime().getTime());
0199:            }
0200:
0201:            public Object getObject() {
0202:                return getTimestamp((Calendar) null);
0203:            }
0204:
0205:            /* get storage length */
0206:            public int getLength() {
0207:                return 12;
0208:            }
0209:
0210:            /* this is for DataType's error generator */
0211:            public String getTypeName() {
0212:                return "TIMESTAMP";
0213:            }
0214:
0215:            /*
0216:             * Storable interface, implies Externalizable, TypedFormat
0217:             */
0218:
0219:            /**
0220:            	Return my format identifier.
0221:
0222:            	@see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
0223:             */
0224:            public int getTypeFormatId() {
0225:                return StoredFormatIds.SQL_TIMESTAMP_ID;
0226:            }
0227:
0228:            /** 
0229:            	@exception IOException error writing data
0230:
0231:             */
0232:            public void writeExternal(ObjectOutput out) throws IOException {
0233:
0234:                if (SanityManager.DEBUG)
0235:                    SanityManager
0236:                            .ASSERT(!isNull(),
0237:                                    "writeExternal() is not supposed to be called for null values.");
0238:
0239:                /*
0240:                 ** Timestamp is written out 3 ints, encoded date, encoded time, and
0241:                 ** nanoseconds
0242:                 */
0243:                out.writeInt(encodedDate);
0244:                out.writeInt(encodedTime);
0245:                out.writeInt(nanos);
0246:            }
0247:
0248:            /**
0249:             * @see java.io.Externalizable#readExternal
0250:             *
0251:             * @exception IOException	Thrown on error reading the object
0252:             */
0253:            public void readExternal(ObjectInput in) throws IOException {
0254:                encodedDate = in.readInt();
0255:                encodedTime = in.readInt();
0256:                nanos = in.readInt();
0257:                // reset cached values
0258:                valueString = null;
0259:            }
0260:
0261:            public void readExternalFromArray(ArrayInputStream in)
0262:                    throws IOException {
0263:                encodedDate = in.readInt();
0264:                encodedTime = in.readInt();
0265:                nanos = in.readInt();
0266:                // reset cached values
0267:                valueString = null;
0268:            }
0269:
0270:            /*
0271:             * DataValueDescriptor interface
0272:             */
0273:
0274:            /** @see DataValueDescriptor#getClone */
0275:            public DataValueDescriptor getClone() {
0276:                // Call constructor with all of our info
0277:                return new SQLTimestamp(encodedDate, encodedTime, nanos);
0278:            }
0279:
0280:            /**
0281:             * @see DataValueDescriptor#getNewNull
0282:             */
0283:            public DataValueDescriptor getNewNull() {
0284:                return new SQLTimestamp();
0285:            }
0286:
0287:            /**
0288:             * @see org.apache.derby.iapi.services.io.Storable#restoreToNull
0289:             *
0290:             */
0291:            public void restoreToNull() {
0292:                // clear numeric representation
0293:                encodedDate = 0;
0294:                encodedTime = 0;
0295:                nanos = 0;
0296:
0297:                // clear cached valueString
0298:                valueString = null;
0299:            }
0300:
0301:            /*
0302:             * DataValueDescriptor interface
0303:             */
0304:
0305:            /** 
0306:             * @see DataValueDescriptor#setValueFromResultSet 
0307:             *
0308:             * @exception SQLException		Thrown on error
0309:             */
0310:            public void setValueFromResultSet(ResultSet resultSet,
0311:                    int colNumber, boolean isNullable) throws SQLException,
0312:                    StandardException {
0313:                setValue(resultSet.getTimestamp(colNumber), (Calendar) null);
0314:            }
0315:
0316:            public int compare(DataValueDescriptor other)
0317:                    throws StandardException {
0318:                /* Use compare method from dominant type, negating result
0319:                 * to reflect flipping of sides.
0320:                 */
0321:                if (typePrecedence() < other.typePrecedence()) {
0322:                    return -(other.compare(this ));
0323:                }
0324:
0325:                boolean this Null, otherNull;
0326:
0327:                this Null = this .isNull();
0328:                otherNull = other.isNull();
0329:
0330:                /*
0331:                 * thisNull otherNull	return
0332:                 *	T		T		 	0	(this == other)
0333:                 *	F		T		 	-1 	(this < other)
0334:                 *	T		F		 	1	(this > other)
0335:                 */
0336:                if (this Null || otherNull) {
0337:                    if (!this Null) // otherNull must be true
0338:                        return -1;
0339:                    if (!otherNull) // thisNull must be true
0340:                        return 1;
0341:                    return 0;
0342:                }
0343:
0344:                /*
0345:                	Neither are null compare them 
0346:                 */
0347:
0348:                int comparison;
0349:                /* get the comparison date values */
0350:                int otherEncodedDate = 0;
0351:                int otherEncodedTime = 0;
0352:                int otherNanos = 0;
0353:
0354:                /* if the argument is another SQLTimestamp, look up the value
0355:                 */
0356:                if (other instanceof  SQLTimestamp) {
0357:                    SQLTimestamp st = (SQLTimestamp) other;
0358:                    otherEncodedDate = st.encodedDate;
0359:                    otherEncodedTime = st.encodedTime;
0360:                    otherNanos = st.nanos;
0361:                } else {
0362:                    /* O.K. have to do it the hard way and calculate the numeric value
0363:                     * from the value
0364:                     */
0365:                    Calendar cal = new GregorianCalendar();
0366:                    Timestamp otherts = other.getTimestamp(cal);
0367:                    otherEncodedDate = SQLTimestamp.computeEncodedDate(otherts,
0368:                            cal);
0369:                    otherEncodedTime = SQLTimestamp.computeEncodedTime(otherts,
0370:                            cal);
0371:                    otherNanos = otherts.getNanos();
0372:                }
0373:                if (encodedDate < otherEncodedDate)
0374:                    comparison = -1;
0375:                else if (encodedDate > otherEncodedDate)
0376:                    comparison = 1;
0377:                else if (encodedTime < otherEncodedTime)
0378:                    comparison = -1;
0379:                else if (encodedTime > otherEncodedTime)
0380:                    comparison = 1;
0381:                else if (nanos < otherNanos)
0382:                    comparison = -1;
0383:                else if (nanos > otherNanos)
0384:                    comparison = 1;
0385:                else
0386:                    comparison = 0;
0387:
0388:                return comparison;
0389:            }
0390:
0391:            /**
0392:            	@exception StandardException thrown on error
0393:             */
0394:            public boolean compare(int op, DataValueDescriptor other,
0395:                    boolean orderedNulls, boolean unknownRV)
0396:                    throws StandardException {
0397:                if (!orderedNulls) // nulls are unordered
0398:                {
0399:                    if (this .isNull() || ((DataValueDescriptor) other).isNull())
0400:                        return unknownRV;
0401:                }
0402:
0403:                /* Do the comparison */
0404:                return super .compare(op, other, orderedNulls, unknownRV);
0405:            }
0406:
0407:            /*
0408:             ** Class interface
0409:             */
0410:
0411:            /*
0412:             ** Constructors
0413:             */
0414:
0415:            /** no-arg constructor required by Formattable */
0416:            public SQLTimestamp() {
0417:            }
0418:
0419:            public SQLTimestamp(Timestamp value) throws StandardException {
0420:                setValue(value, (Calendar) null);
0421:            }
0422:
0423:            SQLTimestamp(int encodedDate, int encodedTime, int nanos) {
0424:
0425:                this .encodedDate = encodedDate;
0426:                this .encodedTime = encodedTime;
0427:                this .nanos = nanos;
0428:            }
0429:
0430:            public SQLTimestamp(DataValueDescriptor date,
0431:                    DataValueDescriptor time) throws StandardException {
0432:                Calendar cal = null;
0433:                if (date == null || date.isNull() || time == null
0434:                        || time.isNull())
0435:                    return;
0436:                if (date instanceof  SQLDate) {
0437:                    SQLDate sqlDate = (SQLDate) date;
0438:                    encodedDate = sqlDate.getEncodedDate();
0439:                } else {
0440:                    cal = new GregorianCalendar();
0441:                    encodedDate = computeEncodedDate(date.getDate(cal), cal);
0442:                }
0443:                if (time instanceof  SQLTime) {
0444:                    SQLTime sqlTime = (SQLTime) time;
0445:                    encodedTime = sqlTime.getEncodedTime();
0446:                } else {
0447:                    if (cal == null)
0448:                        cal = new GregorianCalendar();
0449:                    encodedTime = computeEncodedTime(time.getTime(cal), cal);
0450:                }
0451:            }
0452:
0453:            /**
0454:             * Construct a timestamp from a string. The allowed formats are:
0455:             *<ol>
0456:             *<li>JDBC escape: yyyy-mm-dd hh:mm:ss[.fffff]
0457:             *<li>IBM: yyyy-mm-dd-hh.mm.ss[.nnnnnn]
0458:             *</ol>
0459:             * The format is specified by a parameter to the constructor. Leading zeroes may be omitted from the month, day,
0460:             * and hour part of the timestamp. The microsecond part may be omitted or truncated.
0461:             */
0462:            public SQLTimestamp(String timestampStr, boolean isJDBCEscape,
0463:                    LocaleFinder localeFinder) throws StandardException {
0464:                parseTimestamp(timestampStr, isJDBCEscape, localeFinder,
0465:                        (Calendar) null);
0466:            }
0467:
0468:            /**
0469:             * Construct a timestamp from a string. The allowed formats are:
0470:             *<ol>
0471:             *<li>JDBC escape: yyyy-mm-dd hh:mm:ss[.fffff]
0472:             *<li>IBM: yyyy-mm-dd-hh.mm.ss[.nnnnnn]
0473:             *</ol>
0474:             * The format is specified by a parameter to the constructor. Leading zeroes may be omitted from the month, day,
0475:             * and hour part of the timestamp. The microsecond part may be omitted or truncated.
0476:             */
0477:            public SQLTimestamp(String timestampStr, boolean isJDBCEscape,
0478:                    LocaleFinder localeFinder, Calendar cal)
0479:                    throws StandardException {
0480:                parseTimestamp(timestampStr, isJDBCEscape, localeFinder, cal);
0481:            }
0482:
0483:            static final char DATE_SEPARATOR = '-';
0484:            private static final char[] DATE_SEPARATORS = { DATE_SEPARATOR };
0485:            private static final char IBM_DATE_TIME_SEPARATOR = '-';
0486:            private static final char ODBC_DATE_TIME_SEPARATOR = ' ';
0487:            private static final char[] DATE_TIME_SEPARATORS = {
0488:                    IBM_DATE_TIME_SEPARATOR, ODBC_DATE_TIME_SEPARATOR };
0489:            private static final char[] DATE_TIME_SEPARATORS_OR_END = {
0490:                    IBM_DATE_TIME_SEPARATOR, ODBC_DATE_TIME_SEPARATOR, (char) 0 };
0491:            private static final char IBM_TIME_SEPARATOR = '.';
0492:            private static final char ODBC_TIME_SEPARATOR = ':';
0493:            private static final char[] TIME_SEPARATORS = { IBM_TIME_SEPARATOR,
0494:                    ODBC_TIME_SEPARATOR };
0495:            private static final char[] TIME_SEPARATORS_OR_END = {
0496:                    IBM_TIME_SEPARATOR, ODBC_TIME_SEPARATOR, (char) 0 };
0497:            private static final char[] END_OF_STRING = { (char) 0 };
0498:
0499:            private void parseTimestamp(String timestampStr,
0500:                    boolean isJDBCEscape, LocaleFinder localeFinder,
0501:                    Calendar cal) throws StandardException {
0502:                StandardException thrownSE = null;
0503:                DateTimeParser parser = new DateTimeParser(timestampStr);
0504:                try {
0505:                    int[] dateTimeNano = parseDateOrTimestamp(parser, true);
0506:                    encodedDate = dateTimeNano[0];
0507:                    encodedTime = dateTimeNano[1];
0508:                    nanos = dateTimeNano[2];
0509:                    valueString = parser.getTrimmedString();
0510:                    return;
0511:                } catch (StandardException se) {
0512:                    thrownSE = se;
0513:                }
0514:                // see if it is a localized timestamp
0515:                try {
0516:                    timestampStr = StringUtil.trimTrailing(timestampStr);
0517:                    int[] dateAndTime = parseLocalTimestamp(timestampStr,
0518:                            localeFinder, cal);
0519:                    encodedDate = dateAndTime[0];
0520:                    encodedTime = dateAndTime[1];
0521:                    valueString = timestampStr;
0522:                    return;
0523:                } catch (ParseException pe) {
0524:                } catch (StandardException se) {
0525:                }
0526:                if (thrownSE != null)
0527:                    throw thrownSE;
0528:                throw StandardException
0529:                        .newException(SQLState.LANG_DATE_SYNTAX_EXCEPTION);
0530:            } // end of parseTimestamp
0531:
0532:            /**
0533:             * Parse a localized timestamp.
0534:             *
0535:             * @param str the timestamp string, with trailing blanks removed.
0536:             * @param localeFinder
0537:             *
0538:             * @return a {encodedDate, encodedTime} array.
0539:             *
0540:             * @exception ParseException If the string is not a valid timestamp.
0541:             */
0542:            static int[] parseLocalTimestamp(String str,
0543:                    LocaleFinder localeFinder, Calendar cal)
0544:                    throws StandardException, ParseException {
0545:                DateFormat timestampFormat = null;
0546:                if (localeFinder == null)
0547:                    timestampFormat = DateFormat.getDateTimeInstance();
0548:                else if (cal == null)
0549:                    timestampFormat = localeFinder.getTimestampFormat();
0550:                else
0551:                    timestampFormat = (DateFormat) localeFinder
0552:                            .getTimestampFormat().clone();
0553:                if (cal == null)
0554:                    cal = new GregorianCalendar();
0555:                else
0556:                    timestampFormat.setCalendar(cal);
0557:                java.util.Date date = timestampFormat.parse(str);
0558:
0559:                return new int[] { computeEncodedDate(date, cal),
0560:                        computeEncodedTime(date, cal) };
0561:            } // end of parseLocalTimestamp
0562:
0563:            /**
0564:             * Parse a timestamp or a date. DB2 allows timestamps to be used as dates or times. So
0565:             * date('2004-04-15-16.15.32') is valid, as is date('2004-04-15').
0566:             *
0567:             * This method does not handle localized timestamps.
0568:             *
0569:             * @param parser a DateTimeParser initialized with a string.
0570:             * @param timeRequired If true then an error will be thrown if the time is missing. If false then the time may
0571:             *                     be omitted.
0572:             *
0573:             * @return {encodedDate, encodedTime, nanosecond} array.
0574:             *
0575:             * @exception StandardException if the syntax is incorrect for an IBM standard timestamp.
0576:             */
0577:            static int[] parseDateOrTimestamp(DateTimeParser parser,
0578:                    boolean timeRequired) throws StandardException {
0579:                int year = parser.parseInt(4, false, DATE_SEPARATORS, false);
0580:                int month = parser.parseInt(2, true, DATE_SEPARATORS, false);
0581:                int day = parser.parseInt(2, true,
0582:                        timeRequired ? DATE_TIME_SEPARATORS
0583:                                : DATE_TIME_SEPARATORS_OR_END, false);
0584:                int hour = 0;
0585:                int minute = 0;
0586:                int second = 0;
0587:                int nano = 0;
0588:                if (parser.getCurrentSeparator() != 0) {
0589:                    char timeSeparator = (parser.getCurrentSeparator() == ODBC_DATE_TIME_SEPARATOR) ? ODBC_TIME_SEPARATOR
0590:                            : IBM_TIME_SEPARATOR;
0591:                    hour = parser.parseInt(2, true, TIME_SEPARATORS, false);
0592:                    if (timeSeparator == parser.getCurrentSeparator()) {
0593:                        minute = parser.parseInt(2, false, TIME_SEPARATORS,
0594:                                false);
0595:                        if (timeSeparator == parser.getCurrentSeparator()) {
0596:                            second = parser.parseInt(2, false,
0597:                                    TIME_SEPARATORS_OR_END, false);
0598:                            if (parser.getCurrentSeparator() == '.')
0599:                                nano = parser.parseInt(MAX_FRACTION_DIGITS,
0600:                                        true, END_OF_STRING, true)
0601:                                        * FRACTION_TO_NANO;
0602:                        }
0603:                    }
0604:                }
0605:                parser.checkEnd();
0606:                return new int[] {
0607:                        SQLDate.computeEncodedDate(year, month, day),
0608:                        SQLTime.computeEncodedTime(hour, minute, second), nano };
0609:            } // end of parseDateOrTimestamp
0610:
0611:            /**
0612:             * Set the value from a correctly typed Timestamp object.
0613:             * @throws StandardException 
0614:             */
0615:            void setObject(Object theValue) throws StandardException {
0616:                setValue((Timestamp) theValue);
0617:            }
0618:
0619:            protected void setFrom(DataValueDescriptor theValue)
0620:                    throws StandardException {
0621:
0622:                if (theValue instanceof  SQLTimestamp) {
0623:                    restoreToNull();
0624:                    SQLTimestamp tvst = (SQLTimestamp) theValue;
0625:                    encodedDate = tvst.encodedDate;
0626:                    encodedTime = tvst.encodedTime;
0627:                    nanos = tvst.nanos;
0628:                } else {
0629:                    Calendar cal = new GregorianCalendar();
0630:                    setValue(theValue.getTimestamp(cal), cal);
0631:                }
0632:            }
0633:
0634:            /**
0635:            	@see DateTimeDataValue#setValue
0636:            	When converting from a date to a timestamp, time is set to 00:00:00.0
0637:
0638:             */
0639:            public void setValue(Date value, Calendar cal)
0640:                    throws StandardException {
0641:                restoreToNull();
0642:                if (value != null) {
0643:                    if (cal == null)
0644:                        cal = new GregorianCalendar();
0645:                    encodedDate = computeEncodedDate(value, cal);
0646:                }
0647:                /* encodedTime and nanos are already set to zero by restoreToNull() */
0648:            }
0649:
0650:            /**
0651:            	@see DateTimeDataValue#setValue
0652:
0653:             */
0654:            public void setValue(Time value, Calendar cal)
0655:                    throws StandardException {
0656:                restoreToNull();
0657:                if (value != null) {
0658:                    /*
0659:                     ** Create a new timestamp with today's date,
0660:                     ** and 'value' time.  
0661:                     **
0662:                     ** We create a new calendar to get today's date
0663:                     */
0664:                    Calendar today = GregorianCalendar.getInstance();
0665:                    encodedDate = SQLDate.computeEncodedDate(today);
0666:                    if (cal == null)
0667:                        cal = today;
0668:                    encodedTime = computeEncodedTime(value, cal);
0669:                }
0670:            }
0671:
0672:            /**
0673:            	@see DateTimeDataValue#setValue
0674:
0675:             */
0676:            public void setValue(Timestamp value, Calendar cal)
0677:                    throws StandardException {
0678:                restoreToNull();
0679:                setNumericTimestamp(value, cal);
0680:            }
0681:
0682:            public void setValue(String theValue) throws StandardException {
0683:                restoreToNull();
0684:
0685:                if (theValue != null) {
0686:                    DatabaseContext databaseContext = (DatabaseContext) ContextService
0687:                            .getContext(DatabaseContext.CONTEXT_ID);
0688:                    parseTimestamp(theValue, false,
0689:                            (databaseContext == null) ? null : databaseContext
0690:                                    .getDatabase(), (Calendar) null);
0691:                }
0692:                /* restoreToNull will have already set the encoded date to 0 (null value) */
0693:            }
0694:
0695:            /*
0696:             ** SQL Operators
0697:             */
0698:
0699:            /**
0700:             * @see DateTimeDataValue#getYear
0701:             * 
0702:             * @exception StandardException		Thrown on error
0703:             */
0704:            public NumberDataValue getYear(NumberDataValue result)
0705:                    throws StandardException {
0706:                if (SanityManager.DEBUG) {
0707:                    SanityManager.ASSERT(!isNull(), "getYear called on a null");
0708:                }
0709:                return SQLDate.setSource(SQLDate.getYear(encodedDate), result);
0710:            }
0711:
0712:            /**
0713:             * @see DateTimeDataValue#getMonth
0714:             * 
0715:             * @exception StandardException		Thrown on error
0716:             */
0717:            public NumberDataValue getMonth(NumberDataValue result)
0718:                    throws StandardException {
0719:                if (SanityManager.DEBUG) {
0720:                    SanityManager
0721:                            .ASSERT(!isNull(), "getMonth called on a null");
0722:                }
0723:                return SQLDate.setSource(SQLDate.getMonth(encodedDate), result);
0724:            }
0725:
0726:            /**
0727:             * @see DateTimeDataValue#getDate
0728:             * 
0729:             * @exception StandardException		Thrown on error
0730:             */
0731:            public NumberDataValue getDate(NumberDataValue result)
0732:                    throws StandardException {
0733:                if (SanityManager.DEBUG) {
0734:                    SanityManager.ASSERT(!isNull(), "getDate called on a null");
0735:                }
0736:                return SQLDate.setSource(SQLDate.getDay(encodedDate), result);
0737:            }
0738:
0739:            /**
0740:             * @see DateTimeDataValue#getHours
0741:             * 
0742:             * @exception StandardException		Thrown on error
0743:             */
0744:            public NumberDataValue getHours(NumberDataValue result)
0745:                    throws StandardException {
0746:                if (SanityManager.DEBUG) {
0747:                    SanityManager
0748:                            .ASSERT(!isNull(), "getHours called on a null");
0749:                }
0750:                return SQLDate.setSource(SQLTime.getHour(encodedTime), result);
0751:            }
0752:
0753:            /**
0754:             * @see DateTimeDataValue#getMinutes
0755:             * 
0756:             * @exception StandardException		Thrown on error
0757:             */
0758:            public NumberDataValue getMinutes(NumberDataValue result)
0759:                    throws StandardException {
0760:                if (SanityManager.DEBUG) {
0761:                    SanityManager.ASSERT(!isNull(),
0762:                            "getMinute called on a null");
0763:                }
0764:                return SQLDate
0765:                        .setSource(SQLTime.getMinute(encodedTime), result);
0766:            }
0767:
0768:            /**
0769:             * @see DateTimeDataValue#getSeconds
0770:             * 
0771:             * @exception StandardException		Thrown on error
0772:             */
0773:            public NumberDataValue getSeconds(NumberDataValue source)
0774:                    throws StandardException {
0775:                if (SanityManager.DEBUG) {
0776:                    SanityManager.ASSERT(!isNull(),
0777:                            "getSeconds called on a null");
0778:                    SanityManager
0779:                            .ASSERT(source == null
0780:                                    || source instanceof  SQLDouble,
0781:                                    "getSeconds for a timestamp was given a source other than a SQLDouble");
0782:                }
0783:                NumberDataValue result;
0784:
0785:                if (source != null)
0786:                    result = source;
0787:                else
0788:                    result = new SQLDouble();
0789:
0790:                result.setValue((double) (SQLTime.getSecond(encodedTime))
0791:                        + ((double) nanos) / 1.0e9);
0792:
0793:                return result;
0794:            }
0795:
0796:            /*
0797:             ** String display of value
0798:             */
0799:
0800:            public String toString() {
0801:                if (isNull()) {
0802:                    return "NULL";
0803:                } else {
0804:                    return getTimestamp((Calendar) null).toString();
0805:                }
0806:            }
0807:
0808:            /*
0809:             * Hash code
0810:             */
0811:            public int hashCode() {
0812:                if (isNull()) {
0813:                    return 0;
0814:                }
0815:
0816:                return encodedDate + encodedTime + nanos; //since 0 is null
0817:
0818:            }
0819:
0820:            /** @see DataValueDescriptor#typePrecedence */
0821:            public int typePrecedence() {
0822:                return TypeId.TIMESTAMP_PRECEDENCE;
0823:            }
0824:
0825:            /**
0826:             * Check if the value is null.  encodedDate value of 0 is null
0827:             *
0828:             * @return Whether or not value is logically null.
0829:             */
0830:            public final boolean isNull() {
0831:                return (encodedDate == 0);
0832:            }
0833:
0834:            /**
0835:             * Get the value field.  We instantiate the field
0836:             * on demand.
0837:             *
0838:             * @return	The value field.
0839:             */
0840:            public Timestamp getTimestamp(java.util.Calendar cal) {
0841:                if (isNull())
0842:                    return null;
0843:                return newTimestamp(cal);
0844:            }
0845:
0846:            private Timestamp newTimestamp(Calendar currentCal) {
0847:                if (currentCal == null)
0848:                    currentCal = new GregorianCalendar();
0849:                setCalendar(currentCal);
0850:                Timestamp t = new Timestamp(currentCal.getTime().getTime());
0851:                t.setNanos(nanos);
0852:                return t;
0853:            }
0854:
0855:            private void setCalendar(Calendar cal) {
0856:                cal.clear();
0857:                cal.set(Calendar.YEAR, SQLDate.getYear(encodedDate));
0858:                /* Note calendar month is zero based so we subtract 1*/
0859:                cal.set(Calendar.MONTH, (SQLDate.getMonth(encodedDate) - 1));
0860:                cal.set(Calendar.DATE, SQLDate.getDay(encodedDate));
0861:                cal.set(Calendar.HOUR_OF_DAY, SQLTime.getHour(encodedTime));
0862:                cal.set(Calendar.MINUTE, SQLTime.getMinute(encodedTime));
0863:                cal.set(Calendar.SECOND, SQLTime.getSecond(encodedTime));
0864:                cal.set(Calendar.MILLISECOND, 0);
0865:            } // end of setCalendar
0866:
0867:            /**
0868:             * Set the encoded values for the timestamp
0869:             *
0870:             */
0871:            private void setNumericTimestamp(Timestamp value, Calendar cal)
0872:                    throws StandardException {
0873:                if (SanityManager.DEBUG) {
0874:                    SanityManager.ASSERT(isNull(),
0875:                            "setNumericTimestamp called when already set");
0876:                }
0877:                if (value != null) {
0878:                    if (cal == null)
0879:                        cal = new GregorianCalendar();
0880:                    encodedDate = computeEncodedDate(value, cal);
0881:                    encodedTime = computeEncodedTime(value, cal);
0882:                    nanos = value.getNanos();
0883:                }
0884:                /* encoded date should already be 0 for null */
0885:            }
0886:
0887:            // International Support
0888:
0889:            /**
0890:             * International version of getString(). Overrides getNationalString
0891:             * in DataType for date, time, and timestamp.
0892:             *
0893:             * @exception StandardException		Thrown on error
0894:             */
0895:            protected String getNationalString(LocaleFinder localeFinder)
0896:                    throws StandardException {
0897:                if (isNull()) {
0898:                    return getString();
0899:                }
0900:
0901:                return localeFinder.getTimestampFormat().format(
0902:                        getTimestamp((Calendar) null));
0903:            }
0904:
0905:            /**
0906:            	computeEncodedDate sets the date in a Calendar object
0907:            	and then uses the SQLDate function to compute an encoded date
0908:            	The encoded date is
0909:            		year << 16 + month << 8 + date
0910:            	@param value	the value to convert
0911:            	@return 		the encodedDate
0912:
0913:             */
0914:            private static int computeEncodedDate(java.util.Date value,
0915:                    Calendar currentCal) throws StandardException {
0916:                if (value == null)
0917:                    return 0;
0918:
0919:                currentCal.setTime(value);
0920:                return SQLDate.computeEncodedDate(currentCal);
0921:            }
0922:
0923:            /**
0924:            	computeEncodedTime extracts the hour, minute and seconds from
0925:            	a java.util.Date value and encodes them as
0926:            		hour << 16 + minute << 8 + second
0927:            	using the SQLTime function for encoding the data
0928:            	@param value	the value to convert
0929:            	@return 		the encodedTime
0930:
0931:             */
0932:            private static int computeEncodedTime(java.util.Date value,
0933:                    Calendar currentCal) throws StandardException {
0934:                currentCal.setTime(value);
0935:                return SQLTime.computeEncodedTime(currentCal);
0936:            }
0937:
0938:            public void setInto(PreparedStatement ps, int position)
0939:                    throws SQLException, StandardException {
0940:
0941:                ps.setTimestamp(position, getTimestamp((Calendar) null));
0942:            }
0943:
0944:            /**
0945:             * Compute the SQL timestamp function.
0946:             *
0947:             * @exception StandardException
0948:             */
0949:            public static DateTimeDataValue computeTimestampFunction(
0950:                    DataValueDescriptor operand, DataValueFactory dvf)
0951:                    throws StandardException {
0952:                try {
0953:                    if (operand.isNull())
0954:                        return new SQLTimestamp();
0955:                    if (operand instanceof  SQLTimestamp)
0956:                        return (SQLTimestamp) operand.getClone();
0957:
0958:                    String str = operand.getString();
0959:                    if (str.length() == 14) {
0960:                        int year = parseDateTimeInteger(str, 0, 4);
0961:                        int month = parseDateTimeInteger(str, 4, 2);
0962:                        int day = parseDateTimeInteger(str, 6, 2);
0963:                        int hour = parseDateTimeInteger(str, 8, 2);
0964:                        int minute = parseDateTimeInteger(str, 10, 2);
0965:                        int second = parseDateTimeInteger(str, 12, 2);
0966:                        return new SQLTimestamp(SQLDate.computeEncodedDate(
0967:                                year, month, day), SQLTime.computeEncodedTime(
0968:                                hour, minute, second), 0);
0969:                    }
0970:                    // else use the standard cast
0971:                    return dvf.getTimestampValue(str, false);
0972:                } catch (StandardException se) {
0973:                    if (SQLState.LANG_DATE_SYNTAX_EXCEPTION.startsWith(se
0974:                            .getSQLState()))
0975:                        throw StandardException.newException(
0976:                                SQLState.LANG_INVALID_FUNCTION_ARGUMENT,
0977:                                operand.getString(), "timestamp");
0978:                    throw se;
0979:                }
0980:            } // end of computeTimestampFunction
0981:
0982:            static int parseDateTimeInteger(String str, int start, int ndigits)
0983:                    throws StandardException {
0984:                int end = start + ndigits;
0985:                int retVal = 0;
0986:                for (int i = start; i < end; i++) {
0987:                    char c = str.charAt(i);
0988:                    if (!Character.isDigit(c))
0989:                        throw StandardException
0990:                                .newException(SQLState.LANG_DATE_SYNTAX_EXCEPTION);
0991:                    retVal = 10 * retVal + Character.digit(c, 10);
0992:                }
0993:                return retVal;
0994:            } // end of parseDateTimeInteger
0995:
0996:            /**
0997:             * Add a number of intervals to a datetime value. Implements the JDBC escape TIMESTAMPADD function.
0998:             *
0999:             * @param intervalType One of FRAC_SECOND_INTERVAL, SECOND_INTERVAL, MINUTE_INTERVAL, HOUR_INTERVAL,
1000:             *                     DAY_INTERVAL, WEEK_INTERVAL, MONTH_INTERVAL, QUARTER_INTERVAL, or YEAR_INTERVAL
1001:             * @param count The number of intervals to add
1002:             * @param currentDate Used to convert time to timestamp
1003:             * @param resultHolder If non-null a DateTimeDataValue that can be used to hold the result. If null then
1004:             *                     generate a new holder
1005:             *
1006:             * @return startTime + intervalCount intervals, as a timestamp
1007:             *
1008:             * @exception StandardException
1009:             */
1010:            public DateTimeDataValue timestampAdd(int intervalType,
1011:                    NumberDataValue count, java.sql.Date currentDate,
1012:                    DateTimeDataValue resultHolder) throws StandardException {
1013:                if (resultHolder == null)
1014:                    resultHolder = new SQLTimestamp();
1015:                SQLTimestamp tsResult = (SQLTimestamp) resultHolder;
1016:                if (isNull() || count.isNull()) {
1017:                    tsResult.restoreToNull();
1018:                    return resultHolder;
1019:                }
1020:                tsResult.setFrom(this );
1021:                int intervalCount = count.getInt();
1022:
1023:                switch (intervalType) {
1024:                case FRAC_SECOND_INTERVAL:
1025:                    // The interval is nanoseconds. Do the computation in long to avoid overflow.
1026:                    long nanos = this .nanos + intervalCount;
1027:                    if (nanos >= 0 && nanos < ONE_BILLION)
1028:                        tsResult.nanos = (int) nanos;
1029:                    else {
1030:                        int secondsInc = (int) (nanos / ONE_BILLION);
1031:                        if (nanos >= 0)
1032:                            tsResult.nanos = (int) (nanos % ONE_BILLION);
1033:                        else {
1034:                            secondsInc--;
1035:                            nanos -= secondsInc * (long) ONE_BILLION; // 0 <= nanos < ONE_BILLION
1036:                            tsResult.nanos = (int) nanos;
1037:                        }
1038:                        addInternal(Calendar.SECOND, secondsInc, tsResult);
1039:                    }
1040:                    break;
1041:
1042:                case SECOND_INTERVAL:
1043:                    addInternal(Calendar.SECOND, intervalCount, tsResult);
1044:                    break;
1045:
1046:                case MINUTE_INTERVAL:
1047:                    addInternal(Calendar.MINUTE, intervalCount, tsResult);
1048:                    break;
1049:
1050:                case HOUR_INTERVAL:
1051:                    addInternal(Calendar.HOUR, intervalCount, tsResult);
1052:                    break;
1053:
1054:                case DAY_INTERVAL:
1055:                    addInternal(Calendar.DATE, intervalCount, tsResult);
1056:                    break;
1057:
1058:                case WEEK_INTERVAL:
1059:                    addInternal(Calendar.DATE, intervalCount * 7, tsResult);
1060:                    break;
1061:
1062:                case MONTH_INTERVAL:
1063:                    addInternal(Calendar.MONTH, intervalCount, tsResult);
1064:                    break;
1065:
1066:                case QUARTER_INTERVAL:
1067:                    addInternal(Calendar.MONTH, intervalCount * 3, tsResult);
1068:                    break;
1069:
1070:                case YEAR_INTERVAL:
1071:                    addInternal(Calendar.YEAR, intervalCount, tsResult);
1072:                    break;
1073:
1074:                default:
1075:                    throw StandardException.newException(
1076:                            SQLState.LANG_INVALID_FUNCTION_ARGUMENT,
1077:                            ReuseFactory.getInteger(intervalType),
1078:                            "TIMESTAMPADD");
1079:                }
1080:                return tsResult;
1081:            } // end of timestampAdd
1082:
1083:            private void addInternal(int calIntervalType, int count,
1084:                    SQLTimestamp tsResult) throws StandardException {
1085:                Calendar cal = new GregorianCalendar();
1086:                setCalendar(cal);
1087:                try {
1088:                    cal.add(calIntervalType, count);
1089:                    tsResult.encodedTime = SQLTime.computeEncodedTime(cal);
1090:                    tsResult.encodedDate = SQLDate.computeEncodedDate(cal);
1091:                } catch (StandardException se) {
1092:                    String state = se.getSQLState();
1093:                    if (state != null
1094:                            && state.length() > 0
1095:                            && SQLState.LANG_DATE_RANGE_EXCEPTION
1096:                                    .startsWith(state)) {
1097:                        throw StandardException.newException(
1098:                                SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1099:                                "TIMESTAMP");
1100:                    }
1101:                    throw se;
1102:                }
1103:            } // end of addInternal
1104:
1105:            /**
1106:             * Finds the difference between two datetime values as a number of intervals. Implements the JDBC
1107:             * TIMESTAMPDIFF escape function.
1108:             *
1109:             * @param intervalType One of FRAC_SECOND_INTERVAL, SECOND_INTERVAL, MINUTE_INTERVAL, HOUR_INTERVAL,
1110:             *                     DAY_INTERVAL, WEEK_INTERVAL, MONTH_INTERVAL, QUARTER_INTERVAL, or YEAR_INTERVAL
1111:             * @param time1
1112:             * @param currentDate Used to convert time to timestamp
1113:             * @param resultHolder If non-null a NumberDataValue that can be used to hold the result. If null then
1114:             *                     generate a new holder
1115:             *
1116:             * @return the number of intervals by which this datetime is greater than time1
1117:             *
1118:             * @exception StandardException
1119:             */
1120:            public NumberDataValue timestampDiff(int intervalType,
1121:                    DateTimeDataValue time1, java.sql.Date currentDate,
1122:                    NumberDataValue resultHolder) throws StandardException {
1123:                if (resultHolder == null)
1124:                    resultHolder = new SQLInteger();
1125:
1126:                if (isNull() || time1.isNull()) {
1127:                    resultHolder.setToNull();
1128:                    return resultHolder;
1129:                }
1130:
1131:                SQLTimestamp ts1 = promote(time1, currentDate);
1132:
1133:                /* Years, months, and quarters are difficult because their lengths are not constant.
1134:                 * The other intervals are relatively easy (because we ignore leap seconds).
1135:                 */
1136:                Calendar cal = new GregorianCalendar();
1137:                setCalendar(cal);
1138:                long this InSeconds = cal.getTime().getTime() / 1000;
1139:                ts1.setCalendar(cal);
1140:                long ts1InSeconds = cal.getTime().getTime() / 1000;
1141:                long secondsDiff = this InSeconds - ts1InSeconds;
1142:                int nanosDiff = nanos - ts1.nanos;
1143:                // Normalize secondsDiff and nanosDiff so that they are both <= 0 or both >= 0.
1144:                if (nanosDiff < 0 && secondsDiff > 0) {
1145:                    secondsDiff--;
1146:                    nanosDiff += ONE_BILLION;
1147:                } else if (nanosDiff > 0 && secondsDiff < 0) {
1148:                    secondsDiff++;
1149:                    nanosDiff -= ONE_BILLION;
1150:                }
1151:                long ldiff = 0;
1152:
1153:                switch (intervalType) {
1154:                case FRAC_SECOND_INTERVAL:
1155:                    if (secondsDiff > Integer.MAX_VALUE / ONE_BILLION
1156:                            || secondsDiff < Integer.MIN_VALUE / ONE_BILLION)
1157:                        throw StandardException.newException(
1158:                                SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1159:                                "INTEGER");
1160:                    ldiff = secondsDiff * ONE_BILLION + nanosDiff;
1161:                    break;
1162:
1163:                case SECOND_INTERVAL:
1164:                    ldiff = secondsDiff;
1165:                    break;
1166:
1167:                case MINUTE_INTERVAL:
1168:                    ldiff = secondsDiff / 60;
1169:                    break;
1170:
1171:                case HOUR_INTERVAL:
1172:                    ldiff = secondsDiff / (60 * 60);
1173:                    break;
1174:
1175:                case DAY_INTERVAL:
1176:                    ldiff = secondsDiff / (24 * 60 * 60);
1177:                    break;
1178:
1179:                case WEEK_INTERVAL:
1180:                    ldiff = secondsDiff / (7 * 24 * 60 * 60);
1181:                    break;
1182:
1183:                case QUARTER_INTERVAL:
1184:                case MONTH_INTERVAL:
1185:                    // Make a conservative guess and increment until we overshoot.
1186:                    if (Math.abs(secondsDiff) > 366 * 24 * 60 * 60) // Certainly more than a year
1187:                        ldiff = 12 * (secondsDiff / (366 * 24 * 60 * 60));
1188:                    else
1189:                        ldiff = secondsDiff / (31 * 24 * 60 * 60);
1190:                    if (secondsDiff >= 0) {
1191:                        if (ldiff >= Integer.MAX_VALUE)
1192:                            throw StandardException.newException(
1193:                                    SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1194:                                    "INTEGER");
1195:                        // cal holds the time for time1
1196:                        cal.add(Calendar.MONTH, (int) (ldiff + 1));
1197:                        for (;;) {
1198:                            if (cal.getTime().getTime() / 1000 > this InSeconds)
1199:                                break;
1200:                            cal.add(Calendar.MONTH, 1);
1201:                            ldiff++;
1202:                        }
1203:                    } else {
1204:                        if (ldiff <= Integer.MIN_VALUE)
1205:                            throw StandardException.newException(
1206:                                    SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1207:                                    "INTEGER");
1208:                        // cal holds the time for time1
1209:                        cal.add(Calendar.MONTH, (int) (ldiff - 1));
1210:                        for (;;) {
1211:                            if (cal.getTime().getTime() / 1000 < this InSeconds)
1212:                                break;
1213:                            cal.add(Calendar.MONTH, -1);
1214:                            ldiff--;
1215:                        }
1216:                    }
1217:                    if (intervalType == QUARTER_INTERVAL)
1218:                        ldiff = ldiff / 3;
1219:                    break;
1220:
1221:                case YEAR_INTERVAL:
1222:                    // Make a conservative guess and increment until we overshoot.
1223:                    ldiff = secondsDiff / (366 * 24 * 60 * 60);
1224:                    if (secondsDiff >= 0) {
1225:                        if (ldiff >= Integer.MAX_VALUE)
1226:                            throw StandardException.newException(
1227:                                    SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1228:                                    "INTEGER");
1229:                        // cal holds the time for time1
1230:                        cal.add(Calendar.YEAR, (int) (ldiff + 1));
1231:                        for (;;) {
1232:                            if (cal.getTime().getTime() / 1000 > this InSeconds)
1233:                                break;
1234:                            cal.add(Calendar.YEAR, 1);
1235:                            ldiff++;
1236:                        }
1237:                    } else {
1238:                        if (ldiff <= Integer.MIN_VALUE)
1239:                            throw StandardException.newException(
1240:                                    SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1241:                                    "INTEGER");
1242:                        // cal holds the time for time1
1243:                        cal.add(Calendar.YEAR, (int) (ldiff - 1));
1244:                        for (;;) {
1245:                            if (cal.getTime().getTime() / 1000 < this InSeconds)
1246:                                break;
1247:                            cal.add(Calendar.YEAR, -1);
1248:                            ldiff--;
1249:                        }
1250:                    }
1251:                    break;
1252:
1253:                default:
1254:                    throw StandardException.newException(
1255:                            SQLState.LANG_INVALID_FUNCTION_ARGUMENT,
1256:                            ReuseFactory.getInteger(intervalType),
1257:                            "TIMESTAMPDIFF");
1258:                }
1259:                if (ldiff > Integer.MAX_VALUE || ldiff < Integer.MIN_VALUE)
1260:                    throw StandardException
1261:                            .newException(
1262:                                    SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
1263:                                    "INTEGER");
1264:                resultHolder.setValue((int) ldiff);
1265:                return resultHolder;
1266:            } // end of timestampDiff
1267:
1268:            /**
1269:             * Promotes a DateTimeDataValue to a timestamp.
1270:             *
1271:             *
1272:             * @return the corresponding timestamp, using the current date if datetime is a time,
1273:             *         or time 00:00:00 if datetime is a date.
1274:             *
1275:             * @exception StandardException
1276:             */
1277:            static SQLTimestamp promote(DateTimeDataValue dateTime,
1278:                    java.sql.Date currentDate) throws StandardException {
1279:                if (dateTime instanceof  SQLTimestamp)
1280:                    return (SQLTimestamp) dateTime;
1281:                else if (dateTime instanceof  SQLTime)
1282:                    return new SQLTimestamp(SQLDate.computeEncodedDate(
1283:                            currentDate, (Calendar) null), ((SQLTime) dateTime)
1284:                            .getEncodedTime(), 0 /* nanoseconds */);
1285:                else if (dateTime instanceof  SQLDate)
1286:                    return new SQLTimestamp(((SQLDate) dateTime)
1287:                            .getEncodedDate(), 0, 0);
1288:                else
1289:                    return new SQLTimestamp(dateTime
1290:                            .getTimestamp(new GregorianCalendar()));
1291:            } // end of promote
1292:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.