Michael Lam
asked on
Java How to convert UTC milliseconds into UTC Date
I have an int 1446159600 which is UTC/GMT date Thu, 29 Oct 2015 23:00:00 GMT. I tried to do conversion to the actual UTC date, but couldn't get it to work with Calendar, SimpleDateFormat, and Timezone classes. Can someone help me?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
yes
Date is a fairly simple wrapper on a millisecond value. It does not embody the concept of a timezone. That is layered on by what is interpreting the millisecond value into human readable form, typically a DateFormat, though Date.toString() uses a different method. Both are still dependent on something other than Date providing the TimeZone which will usually be the default JVM TimeZone unless provided.
So this:
Sat Jan 17 11:42:39 CST 1970
The output is exactly the same if I do the much simpler
January 17, 1970 5:42:39 PM GMT
This kind of confusion is the reason the JodaTime API was adopted as a JSR in Java8.
Regards,
Jim
So this:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(1446159600)
Date date = calendar .getTime();
doesn't give you a Date object representing GMT time. It's still just a wrapper on a millisecond value. If you doSystem.out.println(date.toString());
what is printed will be in the JVM default TimeZone. For me, that's CST so I get:Sat Jan 17 11:42:39 CST 1970
The output is exactly the same if I do the much simpler
Date date = new Date(1446159600);
What you want to do is set the TimeZone on the DateFormat to get the desired interpretation:DateFormat gmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
gmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(gmt.format(date));
Using this the output isJanuary 17, 1970 5:42:39 PM GMT
This kind of confusion is the reason the JodaTime API was adopted as a JSR in Java8.
Regards,
Jim
Problem is the author has posted in the question :
Expected result is Thu, 29 Oct 2015 23:00:00.
I have an int 1446159600 which is UTC/GMT date Thu, 29 Oct 2015 23:00:00 GMT
Expected result is Thu, 29 Oct 2015 23:00:00.
Per the javadoc for Date:
Date(long date)
Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
So epoch is GMT to begin with and milliseconds is a delta from that. The question then becomes one of interpretation into a TimeZone after the milliseconds have been added to the epoch.
The int value provided in the question appears to actually be the number of seconds, not milliseconds, from the epoch. Given that change, this code will produce the intended result:
Date(long date)
Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
So epoch is GMT to begin with and milliseconds is a delta from that. The question then becomes one of interpretation into a TimeZone after the milliseconds have been added to the epoch.
The int value provided in the question appears to actually be the number of seconds, not milliseconds, from the epoch. Given that change, this code will produce the intended result:
Date date = new Date(1446159600L * 1000L);
DateFormat gmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
gmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(gmt.format(date));
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Jim Cakalic: I want the output to be a Date and not string
To reiterate, the Date object simply represents the number of milliseconds that have elapsed since midnight 1/1/1970 GMT. If you want the value you have as a Date object then multiply it by 1000 (because your value is in seconds) and use the result as the argument to the Date constructor:
Date date = new Date(1446159600L * 1000L);
Date date = new Date(1446159600L * 1000L);
ASKER