Skip to Main Content
  • Questions
  • Oracle JVM Timezone different to OS Timezone

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Steve.

Asked: December 16, 2001 - 4:55 pm UTC

Last updated: September 09, 2004 - 7:31 am UTC

Version: 8.1.7

Viewed 1000+ times

You Asked

Hi Tom,

I have Oracle installed on a machine where the local
timezone is GMT+10. Here's my test script ...

create or replace and compile java source named JTime as
public class JTime
{
public static void ShowDate()
{
java.util.Date dt = new java.util.Date () ;
java.util.TimeZone tz = java.util.TimeZone.getDefault () ;
System.out.println ("dt = " + dt) ;
System.out.println ("tz = " + tz) ;
}
}
/
create or replace procedure JTime
is language java
name 'JTime.ShowDate ()' ;
/
set serveroutput on size 1000000
begin
dbms_java.set_output (1000000) ;
JTime ;
dbms_output.put_line ('Sysdate = ' || to_char (sysdate, 'YYYY-Mon-DD HH24:MI:SS')) ;
end ;
/

Here's the output from executing in SQL*Plus ...

SQL*Plus: Release 8.1.7.0.0 - Production on Tue Dec 11 14:20:45
2001

(c) Copyright 2000 Oracle Corporation. All rights reserved.


Connected to:
Oracle8i Enterprise Edition Release 8.1.7.0.0 - 64bit Production
With the Partitioning option
JServer Release 8.1.7.0.0 - 64bit Production

SQL> @tst

Java created.


Procedure created.

dt = Mon Dec 10 22:20:54 EST 2001
tz =
java.util.SimpleTimeZone[id=EST,offset=-
18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=3,startDay=1,startDayOfWeek=1,startTime=7200000,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=7200000]
Sysdate = 2001-Dec-11 14:20:55

PL/SQL procedure successfully completed.

As you can see, the Aurora JVM is running with a timezone of GMT-5. If I run pretty much the same java code using the OS JVM (v 1.3), I see a timezone id of "Australia/Victoria". I have tried changing my $TZ environment variable to "Australia/Victoria", and I get a correct value within the Oracle JVM, but it completely screws up SYSDATE (appears to show GMT).

I would dearly love an explanation, and information on how to fix it.

Thanks,

Steve

Here's the output from the properties :

SQL> -- listing properties --
java.specification.name=Java Platform API Specification
java.version=1.2.1
oracle.aurora.mts.INIT=oracle.aurora.mts.rdbms.INIT
user.timezone=EST
java.specification.version=1.2
java.vm.vendor=Oracle Corporation
java.vm.specification.version=1.0
user.home=
java.naming.factory.initial=oracle.aurora.namespace.InitialContex...
os.arch=PA_RISC
java.vendor.url=</code> http://www.oracle.com/java/ <code>
file.encoding.pkg=sun.io
user.region=US
java.home=/opt/app/oracle/product/8.1.7/javavm/
java.class.path=
line.separator=
java.io.tmpdir=/var/tmp/
jdbc.drivers=oracle.jdbc.driver.OracleDriver
os.name=HP-UX
java.vendor=Oracle Corporation
oracle.jserver.version=8.1.7
oracle.server.version=8.1.7
java.library.path=
java.vm.specification.vendor=Sun Microsystems Inc.
oracle.aurora.namespace.INIT=oracle.aurora.namespace.rdbms.INIT
oracle.aurora.rdbms.SID=DevFM
file.encoding=ISO8859_1
oracle.aurora.mts.session.INIT=oracle.aurora.mts.session.rdbms.INIT
java.specification.vendor=Sun Microsystems Inc.
oracle.aurora.vm.environment.name=rdbms
user.name=
user.language=en
java.vm.name=JServer VM
java.vm.specification.name=Java Virtual Machine Specification
java.class.version=46.0
oracle.aurora.rdbms.oracle_home=/opt/app/oracle/product/8.1.7/
sun.boot.library.path=/opt/app/oracle/product/8.1.7/lib64:
sqlj.runtime=sqlj.framework.ide.aurora.rdbms.Oracl...
java.naming.factory.url.pkgs=oracle.aurora.ejb.jndi:com.sun.jndi.u...
java.protocol.handler.pkgs=oracle.aurora.rdbms.url
os.version=B.11.00
java.vm.version=1.2.1
java.compiler=
path.separator=:
file.separator=/
user.dir=

PL/SQL procedure successfully completed.


and Tom said...

Hi Steve,

My name is Mark Piermarini and I work for Tom Kyte. He asked me to finish helping you with this problem. I see the environment variable "user.region" is set to "US" -- I will look into that more. For now, I wrote some Java to set the default timezone for JVM session. It has to be called but only once. It will either take a valid named time zone like 'Australia/Sydney' or an offset from GMT. It will also set the default based on the session time from the database. Can you load the java class and PL/SQL package and then test to see if it works for you? Bug 2124255 is closely related to this problem. Below I listed the source code and a test run.
============================================================
create or replace and compile java source named "TZ_Stuff" as
import java.sql.*;
import java.util.*;
import oracle.jdbc.driver.OracleDriver;

// Set the default JVM timezone to be either a user-defined value or a
// value that is retrieved from the database session time zone. One of
// the setDefault() methods should be called before any Java time zone
// work is done and it only needs to be executed once for a JVM. All
// methods are exposed in the PL/SQL wrapper package. list() method
// will show all valid named time zones.
//
// Bug 2124255 in the Oracle Metalink is similar problem.
//
public class TZ_Stuff {

public static void list() {
String[] ids = TimeZone.getAvailableIDs();
for (int i = 0; i < ids.length; i++) {
System.out.println(ids[i]);
}
}

// Accept a time zone in the form of "Australia/Sydney" or
// "GMT[|-]hh[[:]mm]". Using a custom time zone might have
// implications on daylight savings. This method is not exhaustive
// in its' error and input handling. There is a debug message
// displayed which can be removed.
public static void setDefault(String tz) {
String theTZ = tz;

// If the string starts with a plus or minus sign then the caller
// is using a raw offset so prefix with GMT.
if (tz.startsWith("+") || tz.startsWith("-")) {
theTZ = "GMT" + tz;
}

// Now set the default timezone
System.out.println("NEW DEFAULT TZ = " + TimeZone.getTimeZone(theTZ));
TimeZone.setDefault(TimeZone.getTimeZone(theTZ));
}

// Find the value from the database and set it to the default. Only
// execute this once so we do not bother keeping the connection or
// caching a prepared statement. Or anything for that matter.
public static void setDefault() throws Exception {
Connection c = new OracleDriver().defaultConnection();
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("select sessiontimezone from dual");
while (rs.next()) {
setDefault(rs.getString(1));
}

rs.close();
s.close();
c.close();
}
}
/
show errors

create or replace package tz_stuff as
procedure list as
language java name 'TZ_Stuff.list()';

procedure sync_1 as
language java name 'TZ_Stuff.setDefault()';

procedure sync_2(p_time_zone in varchar2) as
language java name 'TZ_Stuff.setDefault(java.lang.String)';
end;
/
show errors

exec tz_stuff.list
exec tz_stuff.sync_2('Australia/Sydney')


-- -------------------------------------------------------------
-- -- This is your code....
-- -------------------------------------------------------------
create or replace and compile java source named JTime as
public class JTime {
public static void ShowDate() {
java.util.Date dt = new java.util.Date ();
java.util.TimeZone tz = java.util.TimeZone.getDefault ();
System.out.println ("dt = " + dt);
System.out.println ("tz = " + tz);
}
}
/

create or replace procedure JTime
is language java name 'JTime.ShowDate()';
/

set serveroutput on size 1000000
exec dbms_java.set_output (1000000);
begin
JTime;
dbms_output.put_line (
'Sysdate = ' ||
to_char (sysdate, 'YYYY-Mon-DD HH24:MI:SS'));
end;
/

============================================================
============================================================

Could you run this:


create or replace and compile java source named "props" as
public class props {
public static void show_props() {
System.getProperties().list(System.out);
}
}
/
show errors
create or replace procedure java_props
as language java name 'props.show_props()';
/
show errors
set serveroutput on size 10000
exec dbms_java.set_output(10000)
exec java_props


and let us know what it says...


Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, September 08, 2004 - 7:40 pm UTC

Hi Tom,
How can we find the version of JVM oracle is using?

Thanks

More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.