Экземпляр календаря не работает
Попытка напечатать время в разных часовых поясах, используя GregorianCalendar
используя код ниже, но не работает. Есть идеи почему?
GregorianCalendar.getInstance(TimeZone.getTimeZone("PST")).getTime()
, Он печатает время в соответствии с моим часовым поясом, а не в PST.
3 ответа
По замыслу java.util.Date будет инициализироваться миллисекундами UTC с начала эпохи и, следовательно, не принимать во внимание часовые пояса. Следующий код будет генерировать:
Calendar pstCalendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("PST"));
Calendar defCalendar = GregorianCalendar.getInstance(TimeZone.getDefault());
// Same values here :
System.out.println(pstCalendar.getTime());
System.out.println(defCalendar.getTime());
// Different values here :
System.out.println(pstCalendar.get(Calendar.HOUR_OF_DAY));
System.out.println(defCalendar.get(Calendar.HOUR_OF_DAY));
Решение состоит в том, чтобы не использовать метод getTime напрямую, а учитывать Calendar.ZONE_OFFSET и использовать diff перед преобразованием в объект даты:
Date d = new Date();
// Default time :
System.out.println(d);
d.setTime(d.getTime() + pstCalendar.get(Calendar.ZONE_OFFSET));
// Time after applying offset
System.out.println(d);
Избегайте juCalendar
Классы java.util.Date и.Calendar общеизвестно хлопотны и устарели. Избежать их. Вместо этого используйте Joda-Time или пакет java.time в Java 8 (вдохновленный Joda-Time).
В отличие от juDate, объект даты-времени в этих двух других библиотеках знает свой назначенный часовой пояс.
Joda времени
Некоторые примеры кода в Joda-Time 2.5. Работа с часовыми поясами становится элементарной при использовании Joda-Time.
DateTime dateTimeDefaultZone = DateTime.now(); // The JVM’s current default time zone assigned. I recommend always specifying a zone instead of implicitly relying on default.
DateTime dateTimeLosAngeles = dateTimeDefaultZone.withZone( DateTimeZone.forID( "America/Los_Angeles" ) );
DateTime dateatimeUtc = dateTimeDefaultZone.withZone( DateTimeZone.UTC );
DateTime dateTimeKolkata = dateTimeDefaultZone.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
Названия часовых поясов
Используйте правильные имена часовых поясов. Избегайте этих 3 или 4 буквенных кодов, поскольку они не являются ни стандартизированными, ни уникальными, и они еще больше запутывают проблему перехода на летнее время.
Calendar # getTime () - Возвращает объект Date, представляющий значение времени этого Календаря (смещение в миллисекундах от Epoch. Чтобы быть точным, значение в java.util.Date - это количество миллисекунд с начала эпохи Unix, которое произошло в полночь 1 января 1970, UTC. И java.util.Date не имеет определенного часового пояса.
с другой стороны, вы можете достичь того, что вы пытаетесь сделать таким же образом,
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println(sdf.format(new Date()));