Как изменить 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);
Это решение нормально?
Ответы
Ответ 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);
}