Question

I am using the following code to try to get the HOUR_OF_DAY (0-23) of a unix timestamp, converted to milliseconds. The timestamp '1296442971' converts to Sun Jan 30 2011 22:02:51 GMT-0500 (EST).

I'm running the following code to try to get the 24-hr timestamp:

    //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);

In this example, both 'hour' and 'twelveHour' have the value 10, when 'hour' should have the value '22'. Does anyone have any ideas as to what could be wrong with my code?

Thanks!

Was it helpful?

Solution

Assuming ts is the variable containing the value 1296442971. I believe you have not declared it to be of type long and hence it might be overflowing

Below works after changing ts to long type

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));

OTHER TIPS

This prints 22 and 10 for me respectively. That looks correct for NY (since you mentioned eastern time).

    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);

Your problem is almost certainly that you're using an int to hold the seconds. Type in the following program which checks int and 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);
    }
}

and you get:

10
10
22
10

tl;dr

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

23

…for value: 2011-01-30T23:02:51-04:00[America/New_York]

32-bit vs 64-bit integers

As the other answers correctly noted, you must use a 64-bit long or Long to track the number of milliseconds since 1970 in UTC. Your number 1296442971 is the number of whole seconds since 1970 in UTC. When multiplied by 1,000 to get milliseconds-since-epoch, you overflow the limit of a 32-bit int or Integer.

java.time

Another problem is that you are using troublesome old legacy date-time classes, now supplanted by the java.time classes.

Instant

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.

The Instant class has a factory method for importing a number of whole seconds since epoch.

Instant instant = Instant.ofEpochSecond( 1_296_442_971L );

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

ZonedDateTime

To see the wall-clock time of the east coast US, apply a ZoneId for a time zone such as America/New_York to get a ZonedDateTime object.

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

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

Interrogate for the hour-of-day in 24-hour numbering of 0-23 by calling getHour.

int hourOfDay = zdt.getHour();

23

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top