Подтвердить что ты не робот

Как изменить TIMEZONE для java.util.Calendar/Date

Я хотел бы изменить значение TIMEZONE в экземпляре Java Calendar во время выполнения. Я попробовал ниже. Но в обоих случаях вывод одинаковый:

    Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    System.out.println(cSchedStartCal.getTime().getTime());
    cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
    System.out.println(cSchedStartCal.getTime().getTime());

ВЫВОД:
1353402486773
1353402486773

Я тоже пробовал это, но результат все тот же:

    Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    System.out.println(cSchedStartCal.getTime());

    Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
    cSchedStartCal1.setTime(cSchedStartCal.getTime());
    System.out.println(cSchedStartCal.getTime());

В API я вижу комментарий ниже, но я не могу понять его много:

     * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
     * Is cal set to 1 o'clock EST or 1 o'clock PST?  Answer: PST.  More
     * generally, a call to setTimeZone() affects calls to set() BEFORE AND
     * AFTER it up to the next call to complete().

Не могли бы вы помочь мне?

Одно возможное решение:

    Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    long gmtTime = cSchedStartCal.getTime().getTime();

    long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone("Asia/Calcutta").getRawOffset();
    Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
    cSchedStartCal1.setTimeInMillis(timezoneAlteredTime);

Это решение нормально?

4b9b3361

Ответ 1

В Java Даты отображаются внутри UTC в миллисекундах с эпохи (так что часовые пояса не учитываются, поэтому вы получаете те же результаты, что и getTime() дает вам указанные миллисекунды).
В вашем решении:

Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
long gmtTime = cSchedStartCal.getTime().getTime();

long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone("Asia/Calcutta").getRawOffset();
Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
cSchedStartCal1.setTimeInMillis(timezoneAlteredTime);

вы просто добавляете смещение от GMT к указанному часовому поясу ( "Азия/Калькутта" в вашем примере) в миллисекундах, так что это должно работать нормально.

Другим возможным решением могло бы стать использование статических полей класса Calendar:

//instantiates a calendar using the current time in the specified timezone
Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
//change the timezone
cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
//get the current hour of the day in the new timezone
cSchedStartCal.get(Calendar.HOUR_OF_DAY);

Для более подробного объяснения обратитесь к fooobar.com/questions/164758/....

Ответ 2

  • Класс Date/Timestamp представляет собой конкретный момент времени с точностью до миллисекунды с 1 января 1970 года, 00:00:00 по Гринвичу. Таким образом, разница во времени (от эпохи к текущему времени) будет одинаковой на всех компьютерах по всему миру, независимо от Timezone.

  • Date/Timestamp не знает о данном времени, на котором находится часовой пояс.

  • Если нам нужно время, основанное на часовом поясе, мы должны перейти в классы Calendar или SimpleDateFormat в java.

  • Если вы попытаетесь напечатать объект Date/Timestamp с помощью toString(), он преобразует и печатает время с часовым поясом по умолчанию вашего компьютера.

  • Таким образом, мы можем сказать, что (Date/Timestamp).getTime() объект всегда будет иметь UTC (время в миллисекундах)

  • В заключение Date.getTime() будет указывать время UTC, но toString() находится в специфическом часовом поясе, а не в UTC.

Теперь, как я могу создать/изменить время в указанном часовом поясе?

Приведенный ниже код дает вам дату (время в миллисекундах) с указанными часовыми поясами. Единственная проблема здесь заключается в том, что вы должны указывать дату в строчном формате.

   DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
   dateFormatLocal.setTimeZone(timeZone);
   java.util.Date parsedDate = dateFormatLocal.parse(date);

Используйте dateFormat.format для ввода даты ввода (всегда UTC), часового пояса и даты возврата в виде строки.

Как сохранить время UTC/GMT в БД:

Если вы напечатаете объект parsedDate, время будет в часовом поясе по умолчанию. Но вы можете сохранить время UTC в БД, как показано ниже.

        Calendar calGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        Timestamp tsSchedStartTime = new Timestamp (parsedDate.getTime());
        if (tsSchedStartTime != null) {
            stmt.setTimestamp(11, tsSchedStartTime, calGMT );
        } else {
            stmt.setNull(11, java.sql.Types.DATE);
        }