Это java.язык SQL.Временная метка часовой пояс конкретный?


Я должен хранить UTC dateTime в БД.
Я преобразовал даты приведены в конкретный часовой пояс по Гринвичу. для этого я следовал приведенному ниже коду.
Мой входной dateTime "20121225 10: 00: 00 Z "часовой пояс" Азия / Калькутта"
Мой сервер / БД (oracle) работает в том же часовом поясе(IST) "Азия/Калькутта"

получить объект даты в этом конкретном часовом поясе

        String date = "20121225 10:00:00 Z";
        String timeZoneId = "Asia/Calcutta";
        TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);

        DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss z");
                    //This date object is given time and given timezone
        java.util.Date parsedDate = dateFormatLocal.parse(date + " "  
                         + timeZone.getDisplayName(false, TimeZone.SHORT));

        if (timeZone.inDaylightTime(parsedDate)) {
            // We need to re-parse because we don't know if the date
            // is DST until it is parsed...
            parsedDate = dateFormatLocal.parse(date + " "
                    + timeZone.getDisplayName(true, TimeZone.SHORT));
        }

       //assigning to the java.sql.TimeStamp instace variable
        obj.setTsSchedStartTime(new java.sql.Timestamp(parsedDate.getTime()));

хранить в DB

        if (tsSchedStartTime != null) {
            stmt.setTimestamp(11, tsSchedStartTime);
        } else {
            stmt.setNull(11, java.sql.Types.DATE);
        }

выход

БД (Oracle), имеет также сохраняется один и тот же dateTime: "20121225 10:00:00 не в UTC.

Я подтвердил из приведенного ниже sql.

     select to_char(sched_start_time, 'yyyy/mm/dd hh24:mi:ss') from myTable

мой сервер БД также работает в том же часовом поясе "Азия / Калькутта"

это дает мне ниже появления

  1. Date.getTime() не в UTC
  2. или отметка времени имеет влияние часового пояса при хранении в БД Что я делаю не так здесь?

еще один вопрос:

будет timeStamp.toString() печать в местном часовом поясе, как java.util.date делает? Не мирового?

4 64

4 ответа:

хотя это явно не указано для setTimestamp(int parameterIndex, Timestamp x) водители должны следовать правилам, установленным setTimestamp(int parameterIndex, Timestamp x, Calendar cal) документация:

устанавливает заданный параметр в заданное java.sql.Timestamp значение, используя данный

Я думаю, что правильный ответ должен быть Java.язык SQL.Метка времени не является конкретным часовым поясом. Метка времени является составной частью java.утиль.Дата и отдельное значение наносекунды. В этом классе нет информации о часовом поясе. Таким образом, как и дата, этот класс просто содержит количество миллисекунд с 1 января 1970 года, 00:00:00 GMT + nanos.

В PreparedStatement.setTimestamp(int parameterIndex, Timestamp x, Calendar cal) Календарь используется драйвером для изменения часового пояса по умолчанию. Но Метка времени все еще держит миллисекунды в GMT.

API неясно, как именно драйвер JDBC должен использовать календарь. Провайдеры, похоже, не стесняются интерпретировать его, например, в прошлый раз, когда я работал с календарем MySQL 5.5, драйвер просто игнорировал календарь в обоих PreparedStatement.setTimestamp и ResultSet.getTimestamp.

Это зависит от вашего водителя. Вам нужно указать параметр в вашей программе Java, чтобы сообщить ему часовой пояс, который вы хотите использовать.

java -Duser.timezone="America/New_York" GetCurrentDateTimeZone

далее этого:

to_char(new_time(sched_start_time, 'CURRENT_TIMEZONE', 'NEW_TIMEZONE'), 'MM/DD/YY HH:MI AM')

также может иметь значение при правильной обработке преобразования. Взято из здесь

для Mysql у нас есть ограничение. В драйвер Mysql doc мы :

ниже приведены некоторые известные проблемы и ограничения для MySQL Connector / J: когда Connector / J извлекает метки времени для дневного света экономия времени (DST) переключение дня с помощью метода getTimeStamp() на результирующий набор, некоторые из возвращенных значений могут быть неправильными. Ошибки могут при подключении следует избегать использования следующих параметров подключения к база данных:

useTimezone=true
useLegacyDatetimeCode=false
serverTimezone=UTC

Итак, когда мы не используем эти параметры и мы называем setTimestamp or getTimestamp с календарем или без календаря, у нас есть метка времени в часовом поясе jvm.

пример :

часовой пояс jvm-GMT+2. В базе данных у нас есть временная метка:1461100256 = 19/04/16 21:10:56,000000000 GMT

Properties props = new Properties();
props.setProperty("user", "root");
props.setProperty("password", "");
props.setProperty("useTimezone", "true");
props.setProperty("useLegacyDatetimeCode", "false");
props.setProperty("serverTimezone", "UTC");
Connection con = DriverManager.getConnection(conString, props);
......
Calendar nowGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Calendar nowGMTPlus4 = Calendar.getInstance(TimeZone.getTimeZone("GMT+4"));
......
rs.getTimestamp("timestampColumn");//Oracle driver convert date to jvm timezone and Mysql convert date to GMT (specified in the parameter)
rs.getTimestamp("timestampColumn", nowGMT);//convert date to GMT 
rs.getTimestamp("timestampColumn", nowGMTPlus4);//convert date to GMT+4 timezone

первый метод возвращает : 1461100256000 = 19/04/2016 - 21:10:56 GMT

В второй метод возвращает : 1461100256000 = 19/04/2016 - 21:10:56 GMT

третий метод возвращает : 1461085856000 = 19/04/2016 - 17:10:56 GMT

вместо Oracle, когда мы используем те же вызовы, у нас есть :

первый метод возвращает : 1461093056000 = 19/04/2016 - 19:10:56 GMT

второй метод возвращает : 1461100256000 = 19/04/2016 - 21:10:56 GMT

В третий метод возвращает : 1461085856000 = 19/04/2016 - 17:10:56 GMT

Примечание : Нет необходимости указывать параметры для Oracle.