| /* |
| * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.internal.platform.database.oracle; |
| |
| import java.io.StringWriter; |
| import java.sql.*; |
| import java.util.*; |
| import oracle.sql.*; |
| import org.eclipse.persistence.internal.helper.Helper; |
| |
| /** |
| * Used as a helper class for TIMESTAMP, TIMESTAMPTZ and TIMESTAMPLTZ in oracle9. |
| */ |
| public class TIMESTAMPHelper { |
| |
| /** |
| * This conversion required the use of the literal string to get the same |
| * functionality as the native SQL to_timestamp() approach. |
| */ |
| public static TIMESTAMPTZ buildTIMESTAMPTZ(Calendar cal, Connection con, boolean shouldPrintCalendar) throws SQLException { |
| //Bug5614674. It used to be a driver bug and Helper.printCalendar(cal, false) was used to make it work. It has been fixed in 11. Separate the newer version from the old ones. |
| if (shouldPrintCalendar) { |
| return new TIMESTAMPTZ(con, Helper.printCalendar(cal, false), cal); |
| } else { |
| return new TIMESTAMPTZ(con, new Timestamp(cal.getTimeInMillis()), cal); |
| } |
| } |
| |
| /** |
| * Build a calendar from TIMESTAMPTZWrapper. |
| */ |
| public static Calendar buildCalendar(TIMESTAMPTZWrapper timestampTZ) throws SQLException{ |
| Timestamp ts = timestampTZ.getTimestamp(); |
| TimeZone tz = timestampTZ.getTimeZone(); |
| |
| Calendar gCal; |
| if(timestampTZ.isTimestampInGmt()) { |
| gCal = Calendar.getInstance(tz); |
| gCal.setTime(ts); |
| } else { |
| gCal = Calendar.getInstance(); |
| gCal.setTime(ts); |
| gCal.getTimeZone().setID(tz.getID()); |
| gCal.getTimeZone().setRawOffset(tz.getRawOffset()); |
| } |
| return gCal; |
| } |
| |
| /** |
| * Build a calendar from TIMESTAMPLTZWrapper. |
| */ |
| public static Calendar buildCalendar(TIMESTAMPLTZWrapper timestampLTZ) throws SQLException{ |
| Calendar gCal; |
| if (timestampLTZ.getZoneId() != null) { |
| gCal = Calendar.getInstance(TimeZone.getTimeZone(timestampLTZ.getZoneId())); |
| } else { |
| gCal = Calendar.getInstance(); |
| } |
| |
| //This is the only way to set time in Calendar. Passing Timestamp directly to the new |
| //calendar does not work because the GMT time is wrong. |
| if(timestampLTZ.isLtzTimestampInGmt()) { |
| gCal.setTimeInMillis(timestampLTZ.getTimestamp().getTime()); |
| } else { |
| Calendar localCalendar = Helper.allocateCalendar(); |
| localCalendar.setTime(timestampLTZ.getTimestamp()); |
| gCal.set(localCalendar.get(Calendar.YEAR), localCalendar.get(Calendar.MONTH), localCalendar.get(Calendar.DATE), localCalendar.get(Calendar.HOUR_OF_DAY), localCalendar.get(Calendar.MINUTE), localCalendar.get(Calendar.SECOND)); |
| Helper.releaseCalendar(localCalendar); |
| } |
| gCal.set(Calendar.MILLISECOND, timestampLTZ.getTimestamp().getNanos() / 1000000); |
| |
| return gCal; |
| } |
| |
| /** |
| * Build a calendar string based on the calendar fields. |
| * If the daylight savings time should be printed and the zone is in daylight savings time, |
| * print the short representation of daylight savings from the calendar's timezone data. |
| */ |
| public static String printCalendar(final Calendar calendar) { |
| if (calendar == null) { |
| return "null"; |
| } |
| final StringWriter writer = new StringWriter(); |
| writer.write(Helper.printCalendar(calendar, false)); |
| writer.write(" "); |
| writer.write(calendar.getTimeZone().getID()); |
| // If we should print daylight savings and the zone is reported to be using daylight time, |
| // write the short representation of the daylight time in the writer. |
| if (shouldAppendDaylightTime(calendar)) { |
| writer.write(" "); |
| writer.write(calendar.getTimeZone().getDisplayName(true, TimeZone.SHORT)); |
| } |
| return writer.toString(); |
| } |
| |
| /** |
| * Return true if the calendar supports and is in daylight time |
| * (according to its timezone), false otherwise |
| */ |
| public static boolean shouldAppendDaylightTime(Calendar calendar) { |
| if (calendar == null) { |
| return false; |
| } |
| TimeZone zone = calendar.getTimeZone(); |
| return zone.useDaylightTime() && zone.inDaylightTime(calendar.getTime()); |
| } |
| |
| /** |
| * Extract TimeZone from TIMESTAMPTZ. |
| */ |
| public static TimeZone extractTimeZone(byte[] bytes) { |
| String regionName = null; |
| if ((bytes[11] & -128) != 0) { |
| int regionCode = (bytes[11] & 127) << 6; |
| regionCode += ((bytes[12] & 252) >> 2); |
| regionName = new String(ZONEIDMAP.getRegion(regionCode)); |
| } else { |
| int hourOffset = bytes[11] - 20; |
| int minuteOffset = bytes[12] - 60; |
| String offset = Helper.buildZeroPrefix(hourOffset, 2) + ":" + Helper.buildZeroPrefixWithoutSign(minuteOffset, 2); |
| regionName = "GMT" + offset; |
| } |
| return TimeZone.getTimeZone(regionName); |
| } |
| } |