Unfortunately, the accepted answer is misguiding. As a matter of fact,
2012-06-01T00:00:00.000+02:00 = 2012-05-31T22:00:00Z
The Z
on the right-hand side is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC
timezone (which has the timezone offset of +00:00
hours).
Writing 2012-06-01T00:00:00.000+02:00
as 2012-06-01
, although a matter of just a function call, is dangerous for any business logic that depends on the timezone because it may have a different date in a timezone with a different offset value e.g. as shown above. 2012-06-01
is just a LocalDate
which should be used to track events like birth date, wedding date etc.
java.time
The legacy date-time API (java.util
date-time types and their formatting type, SimpleDateFormat
etc.) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time
, the modern date-time API*.
Also, quoted below is a notice at the Home Page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time
, the modern API:
How to parse the given date-time string:
The given date-time string has a timezone offset and therefore it should be parsed to OffsetDateTime
. Since the modern date-time API is based on ISO 8601 and does not require using a DateTimeFormatter
object explicitly as long as the date-time string conforms to the ISO 8601 standards.
OffsetDateTime odt = OffsetDateTime.parse("2012-06-01T00:00:00.000+02:00"); // 2012-06-01T00:00+02:00
How to get the date-time out of it in UTC:
There are multiple ways. The simplest way is to convert it into an Instant
which represents an instantaneous point on the timeline which is in UTC.
Instant instant = odt.toInstant(); // 2012-05-31T22:00:00Z
Alternatively,
OffsetDateTime odtUtc = odt.withOffsetSameInstant(ZoneOffset.UTC); // 2012-05-31T22:00Z
How to get java.util.Date
out of it:
If at all, you need an instance of java.util.Date
from the instance of OffsetDateTime
, you can use Date#from(Instant instant)
.
Date date = Date.from(instant); // Thu May 31 23:00:00 BST 2012 <--In my timezone
Note that a java.util.Date
object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT
(or UTC). When you print an object of java.util.Date
, its toString
method returns the date-time in the JVM's timezone, calculated from this milliseconds value. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFormat
and obtain the formatted string from it e.g.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println(sdf.format(date)); // 2012-05-31T22:00:00.000Z
How to get the date part out of it:
As I have already explained, it is dangerous for any business logic that depends on the timezone. However, it's just a matter of a simple function call.
LocalDate localDate = odt.toLocalDate(); // 2012-06-01
Learn more about java.time
, the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.