Экземпляр календаря не работает

Попытка напечатать время в разных часовых поясах, используя 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()));
Другие вопросы по тегам