java HOUR and HOUR_OF_DAY both returning 12-hr time
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 followin开发者_开发知识库g 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!
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));
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.
精彩评论