Yes, your approach seems fine and correct.
For your implementation: if you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.
If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).
The code below works for both. The only difference is the package names (in Java 8 is java.time
and in ThreeTen Backport is org.threeten.bp
), but the classes and methods names are the same.
To get the UTC time, you can use the Instant
class. It's the best choice because it's always in UTC, and can be easily converted to and from another timezones:
// get current UTC time - Instant is always in UTC
Instant instant = Instant.now();
// you can use the string representation
System.out.println(instant.toString());// 2017-06-06T11:57:21.665Z
// or the timestamp (epoch millis - milliseconds from 1970-01-01T00:00:00Z)
System.out.println(instant.toEpochMilli());// 1496750241665
// convert to another timezone (always use valid IDs)
ZonedDateTime z = instant.atZone(ZoneId.of("America/Sao_Paulo"));
System.out.println(z);// 2017-06-06T08:57:21.665-03:00[America/Sao_Paulo]
// in another timezone
z = instant.atZone(ZoneId.of("Europe/Berlin"));
System.out.println(z);// 2017-06-06T13:57:21.665+02:00[Europe/Berlin]
// convert back to UTC Instant
System.out.println(z.toInstant()); // 2017-06-06T11:57:21.665Z
The API uses IANA timezones names (always in the format Continent/City
, like America/Sao_Paulo
or Europe/Berlin
). Avoid using the 3-letter abbreviations (like CST
or PST
) because they are ambiguous and not standard. You can use ZoneId.getAvailableZoneIds()
to get a full list of all timezones names.
You can also use ZoneId.systemDefault()
to get the system's default timezone. In this case, if the code runs on a server, it'll use the server's machine timezone. And if it runs in a device, it'll use whatever is configured in the device.