Thread

  1. [Keystone Slip # 15] JDBC getTimestamp() aborts with some Locales

    webmaster@postgresql.org — 1999-07-26T16:41:21Z

    ---------------------------------------------------------------------------
    Slip number -----: 15
    Problem ---------: JDBC getTimestamp() aborts with some Locales
    Opened by -------: rcoelho@px.com.br on 07/25/99 10:02
    Assigned To -----: scrappy
    ---------------------------------------------------------------------------
    Summary:
    --------- Plataform Description
    RedHat Linux 5.2 Intel
    Postgresql 6.5
    Blackdown Java 1.1.7
    -------------- Simple description
    If your locale is not supported by Java standard, SimpleDateFormat(in getTimestamp function)can't parse timezone ID. This problem has solution but the exception error messages is really strange.
    ------------------- To reproduce the problem
    # first set RHLinux Timezone to EST with /usr/sbin/timeconfig. I'm using Brazil/East
    
    export LANG=pt_BR       # Portuguese (Brazil)
    psql mydb
    mydb> create table timetest(anyfield timestamp);
    mydb> insert into timetest values (now());
    mydb> q
    java example.psql jdbc:postgresql.....       # from pgsql/src/interfaces/jdbc
    
    # The program will abort with error in MessageFormat. See in explanation.
    --------------- Partial Solution
    SimpleDateFormat support PGSql syntax for string timestamp's timezone (GMT offset, in my case -03).
    I just cut the offset conversion to timezone ID in src/interfaces/jdbc/postgresql/jdbc1/ResultSet.java.
    It works fine (with Daylight saving too).
    
        434   public Timestamp getTimestamp(int columnIndex) throws SQLException
        435   {
        436     String s = getString(columnIndex);
        437     SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz");
        438 
        439     if (s != null)
        440       {
        441 //CUT  int TZ = new Float(s.substring(19)).intValue();
        442 //CUT  TZ = TZ * 60 * 60 * 1000;
        443 //CUT  TimeZone zone = TimeZone.getDefault();
        444 //CUT  zone.setRawOffset(TZ);
        445 //CUT  String nm = zone.getID();
        446 //CUT  s = s.substring(0,19) + nm;
        447     try {
        448       java.util.Date d = df.parse(s);
        449       return new Timestamp(d.getTime());
        450     } catch (ParseException e) {
        451       throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErrorOffset()),s);
        452     }
        453       }
        454     return null;                // SQL NULL
        455   }
        456 
    --------------------- Explanation of the real problem
    First problem: SimpleDateFormat was not parsing EST timezone ID if locale(pt_BR) is present.
    I thought timezone's ID (EST, PST, etc.) was universal, not depending on locales.
    
    Looking for Blackdown's classes source code (java/text/SimpleDateFormat.java,
    java/util/TimeZone.java and java/util/Locale.java), I found that SimpleDateFormat works with
    GMT+HH:MM, Locale timezone ID and RFC822 (just offset) and all locale's timezone was in
    java/text/resources/DateFormatzoneData_*.java. So if the locale is not in resources (pt_BR, for example),it recognizes just GMT ID. Is it a Blackdown java classes bug ?
    
    Second problem: But why programa aborts ? It has a message for this.
    The abortion reason is:
    
    java.lang.IllegalArgumentException: Argument # > Arg length
    java.lang.IllegalArgumentException: Argument # > Arg length
            at java.text.MessageFormat.format(MessageFormat.java)
            at java.text.MessageFormat.format(MessageFormat.java)
            at java.text.MessageFormat.format(MessageFormat.java)
            at postgresql.util.PSQLException.translate(PSQLException.java:83)
            at postgresql.util.PSQLException.<init>(PSQLException.java:57)
            at postgresql.jdbc1.ResultSet.getTimestamp(ResultSet.java:451)
            at postgresql.jdbc1.ResultSet.getObject(ResultSet.java:733)
            at example.psql.displayResult(psql.java:122)
            at example.psql.processLine(psql.java:88)
            at example.psql.<init>(psql.java:58)
            at example.psql.main(psql.java:204)
    
    So, I put something like "System.out.println("message="+message+" NArgs="+args.length)" in
    tranlate function of src/interfaces/jdbc/postgresql/util/PSQLException.java.
    
    For my surprise, the result was: message=Bad Timestamp Format at {1} in {2} NArgs=2
    
    The message just requires two args. FOR THIS, I HAVE NO SOLUTION.
    
    Best Regards,
    
    Ricardo Coelho.
    ---------------------------------------------------------------------------
    
    
              Full information on this slip is available at:
    http://www.postgresql.org/bugs/visitor.php3?sid=15&v_func=zoom
    
    ---------------------------------------------------------------------------
    This message was generated automatically by Keystone at http://www.postgresql.org