To store your creation time in an instance field in an object, use Instant
, not String
. Strings are for presentation to users, for storage if your storage doesn’t support date-time types and for data exchange.
For example:
OffsetDateTime creationDateTime = ZonedDateTime.of(
2025, 2, 16, 23, 35, 0, 0,
ZoneId.of("Asia/Yekaterinburg"))
.toOffsetDateTime();
System.out.println(creationDateTime);
Instant creationTime = creationDateTime.toInstant();
System.out.println(creationTime);
Output:
2025-02-16T23:35+05:00 2025-02-16T18:35:00Z
The Instant
already prints in the format you asked for, only it will also print a fraction of second if a non-zero fraction exists.
If against my recommendation you insist on a string, I suggest this formatter:
private static final DateTimeFormatter formatter
= new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.appendPattern("HH:mm:ssX")
.toFormatter(Locale.ROOT);
It’s wordier than yours but has the advantage of reusing the built-in DateTimeFormatter.ISO_LOCAL_DATE
. Now convert to UTC and format:
String utcString = creationDateTime.withOffsetSameInstant(ZoneOffset.UTC)
.format(formatter);
System.out.println(utcString);
Output is the same as before:
2025-02-16T18:35:00Z
An OffsetDateTime
has an offset from UTC, hence the class name. In java.time parlance a time zone is a IANA time zone and comprises past, present and future UTC offsets used in a particular place, the zone, such as Asia/Yekaterinburg in my code example above. So UTC is not a time zone, and an OffsetDateTime
cannot have a time zone in this sense (this is what we have the ZonedDateTime
class for).
Do I need to set timezone using
withOffsetSameInstant(ZoneOffset.of("UTC"))));
or I can skip it?
First, ZoneOffset.of("UTC")
throws an exception. Instead use the built-in constant ZoneOffset.UTC
. Then the answer to your question is, it depends on the result you want, of course. Your result will typically differ depending on whether you convert it to UTC or not.