java HOUR и HOUR_OF_DAY оба возвращаются 12-часовой раз - PullRequest
5 голосов
/ 31 января 2011

Я использую следующий код, чтобы попытаться получить HOUR_OF_DAY (0-23) метки времени Unix, преобразованной в миллисекунды. Отметка времени «1296442971» преобразуется в вс 30 января 2011 года 22:02:51 GMT-0500 (EST).

Я запускаю следующий код, чтобы попытаться получить 24-часовую метку времени:

    //calculate the hour for this timestamp
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeZone(TimeZone.getTimeZone(tz));             
    calendar.setTimeInMillis(ts * 1000);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);  
    int twelveHour = calendar.get(Calendar.HOUR);

В этом примере оба значения «hour» и «twelveHour» имеют значение 10, тогда как «hour» должно иметь значение «22». У кого-нибудь есть идеи относительно того, что может быть не так с моим кодом?

Спасибо!

Ответы [ 4 ]

7 голосов
/ 31 января 2011

Предполагая, что ts является переменной, содержащей значение 1296442971 . Я полагаю, что вы не объявили его типа long и, следовательно, он может быть переполнен

Ниже работает после изменения ts на тип long

long l = 1296442971;
calendar.setTimeInMillis(l * 1000);
out.println(calendar.getTime());
out.println(calendar.get(Calendar.HOUR_OF_DAY));
out.println(calendar.get(Calendar.HOUR));
0 голосов
/ 17 сентября 2016

ТЛ; др

Instant.ofEpochSecond( 1_296_442_971L )
       .atZone( ZoneId.of( "America/New_York" ) )
       .getHour()

23

… для значения: 2011-01-30T23:02:51-04:00[America/New_York]

32-разрядные против 64-разрядных целых чисел

Как правильно отмечено в других ответах, вы должны использовать 64-битный long или Long для отслеживания количества миллисекунд с 1970 года в UTC. Ваш номер 1296442971 - это количество целых секунд с 1970 года в UTC. При умножении на 1000, чтобы получить миллисекунды с начала эпохи, вы переполняете ограничение 32-битного int или Integer.

java.time

Другая проблема заключается в том, что вы используете проблемные старые унаследованные классы даты и времени, которые теперь заменены java.time классами.

Instant

Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд .

Класс Instant имеет фабричный метод для импорта количества целых секунд с начала эпохи.

Instant instant = Instant.ofEpochSecond( 1_296_442_971L );

instant.toString (): 2011-01-31T03: 02: 51Z

ZonedDateTime

Чтобы увидеть часы на восточном побережье США, примените ZoneId для часового пояса, например America/New_York, чтобы получить ZonedDateTime объект.

ZoneId z = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString (): 2011-01-30T23: 02: 51-04: 00 [America / New_York]

Опрос для часового дня в 24-часовой нумерации 0-23, позвонив по номеру getHour.

int hourOfDay = zdt.getHour();

23

О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date, .Calendar и & java.text.SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time.

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений.

Большая часть функциональности java.time перенесена в Java 6 & 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP (см. Как пользоваться… ).

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и другие.

0 голосов
/ 31 января 2011

Ваша проблема почти наверняка в том, что вы используете int для удержания секунд. Введите следующую программу, которая проверяет int и long:

import java.util.Calendar;
import java.util.TimeZone;

public class scratch {
    public static void main (String args[]) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("America/New_York"));

        int intval = 1296442971;
        calendar.setTimeInMillis(intval * 1000);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);  
        int twelveHour = calendar.get(Calendar.HOUR);
        System.out.println (hour);
        System.out.println (twelveHour);

        long longval = 1296442971L;
        calendar.setTimeInMillis(longval * 1000);
        hour = calendar.get(Calendar.HOUR_OF_DAY);  
        twelveHour = calendar.get(Calendar.HOUR);
        System.out.println (hour);
        System.out.println (twelveHour);
    }
}

и вы получите:

10
10
22
10
0 голосов
/ 31 января 2011

Это печатает 22 и 10 для меня соответственно.Это выглядит правильно для Нью-Йорка (так как вы упомянули восточное время).

    long ts = 1296442971;
    Calendar calendar = Calendar.getInstance();       
    TimeZone tz = TimeZone.getTimeZone("America/New_York");
    calendar.setTimeZone(tz);
    calendar.setTimeInMillis(ts*1000);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);  
    int twelveHour = calendar.get(Calendar.HOUR);
    System.out.println("hour:"+hour);
    System.out.println("twelvehour:"+twelveHour);
...