I have a timestamp 2018-01-01 18:20:23.11 which is in UTC. I need to print this in a different format but retain the UTC timezone. However if I use SimpleDateFormat ("dd MMM YYYY yyyy kk:mm z"), it takes my current timezone and gives me 01 Jan 2018 18:20 EST. I want this to print 01 Jan 2018 18:20 UTC. Doing a Timezone.getTimeZone("UTC") converts this time to UTC (does a +4 to hours)which is not the desired result.
-
2Please update your question to show what you have already tried in a [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve). For further information, please see [how to ask good questions](http://stackoverflow.com/help/how-to-ask), and take the [tour of the site](http://stackoverflow.com/tour) :) – giorgiga Feb 13 '18 at 22:07
-
See related Question, [*Changing time zone with Calendar object from EEST to HST changes the time-of-day unexpectedly*](https://stackoverflow.com/q/51257965/642706) – Basil Bourque Jul 11 '18 at 03:07
1 Answers
DateTimeFormatter originalFormatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SS");
DateTimeFormatter newFormatter
= DateTimeFormatter.ofPattern("dd MMM uuuu HH:mm z", Locale.ENGLISH);
String originalTimestamp = "2018-01-01 18:20:23.11";
String differentFormat = LocalDateTime.parse(originalTimestamp, originalFormatter)
.atZone(ZoneId.of("Etc/UTC"))
.format(newFormatter);
System.out.println(differentFormat);
This prints
01 Jan 2018 18:20 UTC
ZoneId.of("Etc/UTC")
or ZoneOffset.UTC
?
A possibly nerdy edit: I had first written .atZone(ZoneOffset.UTC)
in the conversion. I usually use ZoneOffset.UTC
to denote UTC and consider this the nice and idiomatic way of specifying it. However in the case of your code, this resulted in the zone being given as Z
in the output where you had asked for UTC
. Using ZoneId.of("Etc/UTC")
instead gives you what you want. I can find no other way of making sure that the zone is formatted as UTC
(save hardcoding UTC
in the format pattern string, but that would be an ugly hack).
BTW ZoneId.of("Etc/UTC").normalized()
returns ZoneOffset.UTC
(at least on my Java 10, but I expect it to be the case always).
SimpleDateFormat vs. java.time
SimpleDateFormat
is not only long outdated, it is also notoriously troublesome. I recommend you avoid it. It is correct, as you have observed, that it uses your JVM’s default time zone. There is a way to persuade it to do differently, but I would not bother.
java.time
is the modern Java date and time API. It came out in 2014 as a replacement for the old and poorly designed date and time classes. IMHO it is so much nicer to work with.
Link: Oracle tutorial: Date Time explaining how to use java.time

- 81,772
- 15
- 137
- 161
-
-
Interesting that `ZoneOffset.UTC` and `ZoneId.of("Etc/UTC")` show different behavior. Thanks. I suggest adding that as a note of interest in your Answer. – Basil Bourque Jul 11 '18 at 03:09
-
wow, that was awesome, great java to change a time zone we need that much code, isn't it a shame? – Aadam Jan 27 '22 at 15:01