-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Jerry,

On 1/9/20 1:15 PM, Christopher Schultz wrote:
> You should write yourself some small tests in Java to try
> everything [you've] read here. Just grab a date value from the
> database and inspect the object you get back. Mess with the time
> zones of various components, see what changes, and how to need to
> handle the those situations so the user always sees what they
> expect to see.

I wrote some code for this. I'm attaching it below.

What you'll find is that, no matter what:

1. NOW() always returns a timestamp which is in the client's session
time zone (not the JVM's time zone)
2. Timestamp values are not re-zoned at any stage
3. The zone offset of the java.util.Date object returned by
ResultSet.getDate|Timestamp always matches the JVM's time zone

#3 is where the confusion is coming from, I think.

If you SELECT a date that should be in America/Chicago and your JVM TZ
is America/Chicago, then all is well. But if you change the client
session's time zone and SELECT a date that you expect to be in the new
time zone, then it depends whether this was SELECT NOW() or SELECT
field FROM table. The former will be totally wrong (wait, NOW()
returns *tomorrow*?). The latter will give you whatever date was
stored (without re-zoning it) and your java.util.Date object will have
the America/Chicago zone offset.

Hope that helps,
- -chris

==== CUT ====
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class JDBCDateTest {
    private static SimpleDateFormat df = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");

    /**
     * Sorry for the bad CLI argument interface; this is an example
     * and not really worth fleshing this all out. Unfortunately,
     * it means havig to put your password on the command-line :(
     */
    public static void main(String[] args)
        throws Exception
    {
        String url = "jdbc:mysql://localhost/test";
        String driver = "com.mysql.jdbc.Driver";
        String username = System.getProperty("user.name");
        String password = null;

        Connection conn = null;
        Statement s = null;
        ResultSet rs = null;

        int argindex = 0;

        while(argindex < args.length) {
            String arg = args[argindex++];

            if("--url".equals(arg) || "-U".equals(arg))
                url = args[argindex++];
            else if("--driver".equals(arg) || "-D".equals(arg))
                driver = args[argindex++];
            else if("--username".equals(arg) || "-u".equals(arg))
                username = args[argindex++];
            else if("--password".equals(arg) || "-p".equals(arg))
                password= args[argindex++];
            else {
                System.err.println("Unknown argument: " + arg);
                System.exit(1);
            }
        }
        try {
            // Register JDBC driver
            Class.forName(driver);

            conn = DriverManager.getConnection(url, username, password);

            // First, dump some time zone information
            TimeZone tz = TimeZone.getDefault();
            System.out.println("JVM default time zone: " + tz.getID());

            s = conn.createStatement();
            rs = s.executeQuery("SELECT @@global.time_zone AS
server_zone, @@session.time_zone AS session_zone");

            if(!rs.next())
                throw new IllegalStateException("Could not fetch
server time zones");

            System.out.println("Server time zone:  " +
rs.getString("server_zone"));
            System.out.println("Session time zone: " +
rs.getString("server_zone"));

            rs.close(); rs = null;

            System.out.println("=====  SELECT NOW() with default time
zone ====");
            rs = s.executeQuery("SELECT NOW() AS now");

            if(!rs.next())
                throw new IllegalStateException("SELECT NOW returned
no rows");

            dump(rs.getDate("now"));
            dump(rs.getTimestamp("now"));
            rs.close(); rs = null;

            System.out.println("=====  SELECT NOW() with +10:00 time
zone ====");

            s.executeUpdate("SET time_zone = '+10:00'");
            rs = s.executeQuery("SELECT NOW() AS now");

            if(!rs.next())
                throw new IllegalStateException("SELECT returned no
rows");

            dump(rs.getDate("now"));
            dump(rs.getTimestamp("now"));

            rs.close(); rs = null;

            System.out.println("=====  SELECT explicit date with
+10:00 time zone ====");

            rs = s.executeQuery("SELECT TIMESTAMP('2020-01-09
14:14:00') AS date");

            if(!rs.next())
                throw new IllegalStateException("SELECT returned no
rows");

            dump(rs.getDate("date"));
            dump(rs.getTimestamp("date"));

            rs.close(); rs = null;

            System.out.println("=====  SELECT explicit date with
SYSTEM time zone ====");

            s.executeUpdate("SET time_zone = 'SYSTEM'");
            rs = s.executeQuery("SELECT TIMESTAMP('2020-01-09
14:14:00') AS date");

            if(!rs.next())
                throw new IllegalStateException("SELECT returned no
rows");

            dump(rs.getDate("date"));
            dump(rs.getTimestamp("date"));

            rs.close(); rs = null;

            s.close(); s = null;
        } finally {
            if(null != rs) try { rs.close(); } catch (SQLException sqle)
 {
                System.err.println("Cannot close JDBC ResultSet");
                sqle.printStackTrace();
            }
            if(null != s) try { s.close(); } catch (SQLException sqle) {
                System.err.println("Cannot close JDBC Statement");
                sqle.printStackTrace();
            }
            if(null != conn) try { conn.close(); } catch (SQLException
sqle) {
                System.err.println("Cannot close JDBC Connection");
                sqle.printStackTrace();
            }
        }
    }

    @SuppressWarnings("deprecation")
    private static void dump(Date date)
    {
        System.out.println(date.getClass().getName());
        System.out.print("  toString()=");
        System.out.println(date.toString());
        System.out.print("           t=");
        System.out.println(date.getTime());
        System.out.print("        year=");
        System.out.println(date.getYear() + 1900);
        System.out.print("       month=");
        System.out.println(date.getMonth() + 1);
        System.out.print("         day=");
        System.out.println(date.getDay());
        // java.sql.Date.getHours, etc. throw IllegalArgumentException
if called
        if(!(date instanceof java.sql.Date)) {
            System.out.print("        hour=");
            System.out.println(date.getHours());
            System.out.print("      minute=");
            System.out.println(date.getMinutes());
            System.out.print("      second=");
            System.out.println(date.getSeconds());
        }
        System.out.print("      offset=");
        System.out.println(date.getTimezoneOffset());
        System.out.print("          df=");
        System.out.println(df.format(date));
    }
}
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl4XfngACgkQHPApP6U8
pFiTvw//eNPIiNKUsDjaQhMc+1VRbXFUCMjrvkq8QpqssLXBuvTTx0iSMKSsZTbq
+FzBiG7u8jT7i3M66hLyqSUkgExsVDGaZv0sYs4wJlWso6Fc+5CMpFOf5ZZKYOSK
iDRRbLUaOMaocW9ldKK6CkSHSvPMDIOgOA+EAU9QKTKqgvosVZ+3qUl5qmeUJIQn
okM8L6QxmrCp90vXfm8yy3j2C2Hi7v15ayeVcETQ5CTPNK358in97y/9L9Np2xS4
bNkI+5u6uhfPpz8EtLpd5vdfzj7+U1YrncpqB2BZtDYYfnQdmC5x0GQEuX7GgBZ/
25lw4VkU4WQ/KuAdOUZaIh6QyAp7Nc6fLXZFxDJhS9XNN8lOKYSO8dvEfNSGLKpG
BFZ+eymhLsFN7QhJDxgzefnkFYLC8y57AdXYosByg4lVsrpTFt4M1aJ08niTQciu
eV2Di86U9SZsoJua0qkj4VJnC+jtBRzm/2gfw5fAfMf19gbaURKZieaF/jsZx+td
R7ticX1bl/tzVkp/7WJvlVe0sclAmV08fdXEh+H5E5N44urBgPf+N3ZknIx4QuAN
7oHUu8vW258ENWcWCjHKJ5a+qajnRukJthn8RElU5djLku2NuWwU803iHPwt6A4e
QPXNan43Nx8D+tEQa54B6txdie6jk/6k53XdHhjEq+JiiNP1bM8=
=p39n
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to