Reputation: 41
I am trying to get the UTC milliseconds to convert a Joda DateTime
instance to a SQL Timestamp, however it is converting it to my local time instead.
This is an example:
DateTime d = DateTime.now().withZone(DateTimeZone.UTC);
Timestamp t = new Timestamp(d.getMillis());
System.out.println(t);
t.setHours(d.getHourOfDay());
System.out.println(t);
And the output:
2015-04-17 18:11:27.277
2015-04-17 22:11:27.277
Why is it converted to my local timezone? I thought the DateTime.getMillis()
method always returned the milliseconds for UTC?
Upvotes: 4
Views: 5256
Reputation: 338516
ZonedDateTime.now()
Instant
The Joda-Time library was replaced by the java.time classes built into Java 8 and later.
Instead of DateTime
class, use java.time.Instant
to represent a moment as seen in UTC (an offset of zero hours-minutes-seconds).
Instant now = Instant.now() ;
ZonedDateTime
You can adjust to see that moment through the wall-clock/calendar of a particular time zone. Use ZonedDateTime
class.
ZoneId z = ZoneId.of( "America/Edmonton" ) ; // Or ZoneId.systemDefault()
ZonedDateTime zdt = now.atZone( z ) ;
Or skip the Instant
and go directly to capturing the current moment as a ZonedDateTime
object.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
You said:
new Timestamp
Never use java.sql.Timestamp
. This class is a disaster of poor design and confusing documentation. Entirely replaced with java.time classes.
Upvotes: 1
Reputation: 32323
When you change the time, you don't change the number of milliseconds since the epoch. In other words, calling withZone
doesn't actually change the underlying long millis
.
The real problem is the Timestamp.setHours
method, which has been deprecated since Java 1.1. See the documentation:
@Deprecated
public void setHours(int hours)
Deprecated. As of JDK version 1.1, replaced by
Calendar.set(Calendar.HOUR_OF_DAY, int hours)
. Sets the hour of this Date object to the specified value. This Date object is modified so that it represents a point in time within the specified hour of the day, with the year, month, date, minute, and second the same as before, as interpreted in the local time zone.
Upvotes: 4
Reputation: 2541
try this:
DateTimeZone.setDefault(DateTimeZone.UTC);
DateTime d = DateTime.now();
Timestamp t = new Timestamp(d.getMillis());
System.out.println(t);
t.setHours(d.getHourOfDay());
System.out.println(t);
Upvotes: 1