One is your local time and one is UTC. This depends more on the way it is printed than on the actual (internal) value.
To have both shown equal, you can
- Set your local time zone to UTC by passing
-Duser.timezone=UTC
to your VM.
Format the Instant
to your local time zone:
DateTimeFormatter formatter =
DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault());
System.out.println(formatter.format(Instant.now()));
Convert the Timestamp
to an Instant
:
new Timestamp(System.currentTimeMillis()).toInstant();
Full code:
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault());
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
Instant instant = Instant.now();
System.out.println("Timestamp: " + timestamp);
System.out.println("Instant: " + instant);
System.out.println("Instant to local: " + formatter.format(instant));
System.out.println("Timestamp to UTC: " + timestamp.toInstant());
}
Will print out (in my local time zone):
Timestamp: 2017-06-10 21:17:13.935
Instant: 2017-06-10T19:17:13.935Z
Instant to local: 2017-06-10T21:17:13.935
Timestamp to UTC: 2017-06-10T19:17:13.935Z
So there is "some global setting", although it might not do what you want. An Instant
will always be printed in UTC by default.
If you want to work with local dates only and you are not restricted to Instant
, there are two* more options:
Convert the Instant
to ZonedDateTime
:
ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
Or skip the Instant
altogether in favor of ZonedDateTime.now()
*Depending on your needs you can exchange ZonedDateTime
with OffsetDateTime
or LocalDateTime
.
Edit: The magical way.
public static void main(String[] args) throws Exception {
Field field = DateTimeFormatter.class.getField("ISO_INSTANT");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault()));
System.out.println(new Timestamp(System.currentTimeMillis()));
System.out.println(Instant.now());
}
Use reflection to change DateTimeFormatter.ISO_INSTANT
to a formatter that uses your local time. Might not work with a SecurityManager
and might have one or another unwanted side effect. See e.g. Change private static final field using Java reflection for details.